Imported Upstream version 1.7.4 upstream/1.7.4
authorDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 18 Jan 2022 02:15:05 +0000 (11:15 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 18 Jan 2022 02:15:05 +0000 (11:15 +0900)
253 files changed:
Makefile.in
NEWS
aclocal.m4
ar-lib
compile
config.h.in
configure
configure.ac
depcomp
install-sh
ltmain.sh
m4/ac_python_devel.m4 [deleted file]
m4/ax_python_devel.m4 [new file with mode: 0644]
m4/libtool.m4
missing
src/Makefile.in
src/bin/Makefile.in
src/bin/fstcompile-main.cc
src/bin/fstdraw-main.cc
src/bin/fstencode-main.cc
src/bin/fstencode.cc
src/bin/fstinfo-main.cc
src/bin/fstinfo.cc
src/bin/fstprint-main.cc
src/bin/fstrelabel-main.cc
src/bin/fstreplace-main.cc
src/bin/fsttopsort-main.cc
src/bin/fstunion-main.cc
src/extensions/Makefile.in
src/extensions/compact/Makefile.am
src/extensions/compact/Makefile.in
src/extensions/compress/Makefile.am
src/extensions/compress/Makefile.in
src/extensions/compress/compressscript.cc
src/extensions/compress/fstcompress.cc
src/extensions/const/Makefile.am
src/extensions/const/Makefile.in
src/extensions/far/Makefile.in
src/extensions/far/far-class.cc
src/extensions/far/farcompilestrings-main.cc
src/extensions/far/farcompilestrings.cc
src/extensions/far/farcreate-main.cc
src/extensions/far/farcreate.cc
src/extensions/far/farequal.cc
src/extensions/far/farextract-main.cc
src/extensions/far/farextract.cc
src/extensions/far/farinfo-main.cc
src/extensions/far/farinfo.cc
src/extensions/far/farisomorphic.cc
src/extensions/far/farprintstrings-main.cc
src/extensions/far/farprintstrings.cc
src/extensions/far/farscript.cc
src/extensions/far/script-impl.cc
src/extensions/far/stlist.cc
src/extensions/far/strings.cc
src/extensions/far/sttable.cc
src/extensions/linear/Makefile.am
src/extensions/linear/Makefile.in
src/extensions/linear/fstlinear-main.cc
src/extensions/linear/fstloglinearapply-main.cc
src/extensions/linear/linearscript.cc
src/extensions/lookahead/Makefile.am
src/extensions/lookahead/Makefile.in
src/extensions/mpdt/Makefile.in
src/extensions/mpdt/mpdtcompose-main.cc
src/extensions/mpdt/mpdtexpand-main.cc
src/extensions/mpdt/mpdtinfo-main.cc
src/extensions/mpdt/mpdtreverse-main.cc
src/extensions/mpdt/mpdtscript.cc
src/extensions/ngram/Makefile.am
src/extensions/ngram/Makefile.in
src/extensions/ngram/bitmap-index.cc
src/extensions/pdt/Makefile.in
src/extensions/pdt/pdtcompose-main.cc
src/extensions/pdt/pdtexpand-main.cc
src/extensions/pdt/pdtinfo-main.cc
src/extensions/pdt/pdtreplace-main.cc
src/extensions/pdt/pdtreverse-main.cc
src/extensions/pdt/pdtscript.cc
src/extensions/pdt/pdtshortestpath-main.cc
src/extensions/python/Makefile.am
src/extensions/python/Makefile.in
src/extensions/python/fst.pxd
src/extensions/python/memory.pxd [deleted file]
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/extensions/special/phi-fst.cc
src/extensions/special/rho-fst.cc
src/extensions/special/sigma-fst.cc
src/include/Makefile.am
src/include/Makefile.in
src/include/fst/arc-map.h
src/include/fst/cache.h
src/include/fst/closure.h
src/include/fst/compact-fst.h
src/include/fst/compat.h
src/include/fst/complement.h
src/include/fst/compose.h
src/include/fst/concat.h
src/include/fst/const-fst.h
src/include/fst/determinize.h
src/include/fst/edit-fst.h
src/include/fst/encode.h
src/include/fst/equal.h
src/include/fst/expanded-fst.h
src/include/fst/extensions/compress/compress.h
src/include/fst/extensions/compress/compressscript.h
src/include/fst/extensions/compress/gzfile.h
src/include/fst/extensions/far/compile-strings.h
src/include/fst/extensions/far/create.h
src/include/fst/extensions/far/equal.h
src/include/fst/extensions/far/extract.h
src/include/fst/extensions/far/far-class.h
src/include/fst/extensions/far/far.h
src/include/fst/extensions/far/farscript.h
src/include/fst/extensions/far/info.h
src/include/fst/extensions/far/isomorphic.h
src/include/fst/extensions/far/print-strings.h
src/include/fst/extensions/far/script-impl.h
src/include/fst/extensions/far/stlist.h
src/include/fst/extensions/far/sttable.h
src/include/fst/extensions/linear/linear-fst-data-builder.h
src/include/fst/extensions/linear/linear-fst-data.h
src/include/fst/extensions/linear/linear-fst.h
src/include/fst/extensions/linear/linearscript.h
src/include/fst/extensions/linear/loglinear-apply.h
src/include/fst/extensions/mpdt/expand.h
src/include/fst/extensions/mpdt/mpdtscript.h
src/include/fst/extensions/mpdt/read_write_utils.h
src/include/fst/extensions/ngram/bitmap-index.h
src/include/fst/extensions/ngram/ngram-fst.h
src/include/fst/extensions/pdt/expand.h
src/include/fst/extensions/pdt/pdt.h
src/include/fst/extensions/pdt/pdtscript.h
src/include/fst/extensions/pdt/replace.h
src/include/fst/extensions/pdt/shortest-path.h
src/include/fst/extensions/special/phi-fst.h
src/include/fst/extensions/special/rho-fst.h
src/include/fst/extensions/special/sigma-fst.h
src/include/fst/factor-weight.h
src/include/fst/fst-decl.h
src/include/fst/fst.h
src/include/fst/interval-set.h
src/include/fst/label-reachable.h
src/include/fst/lookahead-filter.h
src/include/fst/lookahead-matcher.h
src/include/fst/matcher-fst.h
src/include/fst/matcher.h
src/include/fst/mutable-fst.h
src/include/fst/push.h
src/include/fst/queue.h
src/include/fst/randgen.h
src/include/fst/replace.h
src/include/fst/script/arciterator-class.h
src/include/fst/script/concat.h
src/include/fst/script/decode.h
src/include/fst/script/draw-impl.h
src/include/fst/script/draw.h
src/include/fst/script/encode.h
src/include/fst/script/encodemapper-class.h
src/include/fst/script/fst-class.h
src/include/fst/script/fstscript.h
src/include/fst/script/getters.h
src/include/fst/script/info-impl.h
src/include/fst/script/info.h
src/include/fst/script/print-impl.h
src/include/fst/script/print.h
src/include/fst/script/push.h
src/include/fst/script/register.h [deleted file]
src/include/fst/script/relabel.h
src/include/fst/script/replace.h
src/include/fst/script/script-impl.h
src/include/fst/script/text-io.h
src/include/fst/script/union.h
src/include/fst/script/weight-class.h
src/include/fst/set-weight.h
src/include/fst/shortest-path.h
src/include/fst/state-map.h
src/include/fst/state-table.h
src/include/fst/string-weight.h
src/include/fst/string.h
src/include/fst/symbol-table-ops.h
src/include/fst/symbol-table.h
src/include/fst/test/algo_test.h
src/include/fst/test/compactors.h [new file with mode: 0644]
src/include/fst/test/fst_test.h
src/include/fst/test/rand-fst.h
src/include/fst/test/weight-tester.h
src/include/fst/union.h
src/include/fst/util.h
src/include/fst/vector-fst.h
src/lib/Makefile.am
src/lib/Makefile.in
src/lib/compat.cc
src/lib/encode.cc [new file with mode: 0644]
src/lib/symbol-table-ops.cc
src/lib/symbol-table.cc
src/lib/util.cc
src/script/Makefile.in
src/script/arciterator-class.cc
src/script/arcsort.cc
src/script/closure.cc
src/script/compile.cc
src/script/compose.cc
src/script/concat.cc
src/script/connect.cc
src/script/convert.cc
src/script/decode.cc
src/script/determinize.cc
src/script/difference.cc
src/script/disambiguate.cc
src/script/draw.cc
src/script/encode.cc
src/script/encodemapper-class.cc
src/script/epsnormalize.cc
src/script/equal.cc
src/script/equivalent.cc
src/script/fst-class.cc
src/script/getters.cc
src/script/info-impl.cc
src/script/info.cc
src/script/intersect.cc
src/script/invert.cc
src/script/isomorphic.cc
src/script/map.cc
src/script/minimize.cc
src/script/print.cc
src/script/project.cc
src/script/prune.cc
src/script/push.cc
src/script/randequivalent.cc
src/script/randgen.cc
src/script/relabel.cc
src/script/replace.cc
src/script/reverse.cc
src/script/reweight.cc
src/script/rmepsilon.cc
src/script/shortest-distance.cc
src/script/shortest-path.cc
src/script/stateiterator-class.cc
src/script/synchronize.cc
src/script/text-io.cc
src/script/topsort.cc
src/script/union.cc
src/script/verify.cc
src/script/weight-class.cc
src/test/Makefile.in
src/test/algo_test.cc
src/test/fst_test.cc
test-driver

index abe6d49..57b33de 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -89,7 +89,7 @@ build_triplet = @build@
 host_triplet = @host@
 subdir = .
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_python_devel.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
        $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
@@ -137,7 +137,7 @@ am__recursive_targets = \
   $(RECURSIVE_CLEAN_TARGETS) \
   $(am__extra_recursive_targets)
 AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
-       cscope distdir dist dist-all distcheck
+       cscope distdir distdir-am dist dist-all distcheck
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
        $(LISP)config.h.in
 # Read a list of newline-separated strings from the standard input,
@@ -273,7 +273,7 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
@@ -371,8 +371,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
            echo ' $(SHELL) ./config.status'; \
            $(SHELL) ./config.status;; \
          *) \
-           echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
-           cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \
        esac;
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@@ -522,7 +522,10 @@ distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
        -rm -f cscope.out cscope.in.out cscope.po.out cscope.files
 
-distdir: $(DISTFILES)
+distdir: $(BUILT_SOURCES)
+       $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
        $(am__remove_distdir)
        test -d "$(distdir)" || mkdir "$(distdir)"
        @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
diff --git a/NEWS b/NEWS
index 462c01c..b2bca5a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,11 @@
 OpenFst: Release 1.7
-   * Overloads Arc templatse with default weight argument (1.7.3)
+   * Removes harmful constexpr specifications in FAR (1.7.4)
+   * Improved script API support for EncodeMapper (1.7.4)
+   * New header format for the EncodeMapper (1.7.4)
+   * Imrproved C++17 compatibility shims (1.7.4)
+   * Rewrite of the compactor interface (1.7.4)
+   * Overloads Arc constructors with default weight argument (1.7.3)
+   * Fixes RmEpsilon and Union property checking bugs (1.7.3)
    * Makes Isomorphic more robust to nondeterminism (1.7.3)
    * Adds default weight argument to SetFinal (1.7.3)
    * Cleans up low-level logging (1.7.3)
index 7e761fb..ad18caf 100644 (file)
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.15.1 -*- Autoconf -*-
+# generated automatically by aclocal 1.16.1 -*- Autoconf -*-
 
-# Copyright (C) 1996-2017 Free Software Foundation, Inc.
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
 
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -20,7 +20,7 @@ You have another version of autoconf.  It may work, but is not guaranteed to.
 If you have problems, you may need to regenerate the build system entirely.
 To do so, use the procedure documented by the package, typically 'autoreconf'.])])
 
-# Copyright (C) 2002-2017 Free Software Foundation, Inc.
+# Copyright (C) 2002-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -32,10 +32,10 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.])
 # generated from the m4 files accompanying Automake X.Y.
 # (This private macro should not be called outside this file.)
 AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.15'
+[am__api_version='1.16'
 dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
 dnl require some minimum version.  Point them to the right macro.
-m4_if([$1], [1.15.1], [],
+m4_if([$1], [1.16.1], [],
       [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
 ])
 
@@ -51,12 +51,12 @@ m4_define([_AM_AUTOCONF_VERSION], [])
 # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
 # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.15.1])dnl
+[AM_AUTOMAKE_VERSION([1.16.1])dnl
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 
-# Copyright (C) 2011-2017 Free Software Foundation, Inc.
+# Copyright (C) 2011-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -118,7 +118,7 @@ AC_SUBST([AR])dnl
 
 # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
-# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -170,7 +170,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd`
 
 # AM_CONDITIONAL                                            -*- Autoconf -*-
 
-# Copyright (C) 1997-2017 Free Software Foundation, Inc.
+# Copyright (C) 1997-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -201,7 +201,7 @@ AC_CONFIG_COMMANDS_PRE(
 Usually this means the macro was only invoked conditionally.]])
 fi])])
 
-# Copyright (C) 1999-2017 Free Software Foundation, Inc.
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -392,13 +392,12 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
 
 # Generate code to set up dependency tracking.              -*- Autoconf -*-
 
-# Copyright (C) 1999-2017 Free Software Foundation, Inc.
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-
 # _AM_OUTPUT_DEPENDENCY_COMMANDS
 # ------------------------------
 AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
@@ -406,49 +405,41 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
   # Older Autoconf quotes --file arguments for eval, but not when files
   # are listed without --file.  Let's play safe and only enable the eval
   # if we detect the quoting.
-  case $CONFIG_FILES in
-  *\'*) eval set x "$CONFIG_FILES" ;;
-  *)   set x $CONFIG_FILES ;;
-  esac
+  # TODO: see whether this extra hack can be removed once we start
+  # requiring Autoconf 2.70 or later.
+  AS_CASE([$CONFIG_FILES],
+          [*\'*], [eval set x "$CONFIG_FILES"],
+          [*], [set x $CONFIG_FILES])
   shift
-  for mf
+  # Used to flag and report bootstrapping failures.
+  am_rc=0
+  for am_mf
   do
     # Strip MF so we end up with the name of the file.
-    mf=`echo "$mf" | sed -e 's/:.*$//'`
-    # Check whether this is an Automake generated Makefile or not.
-    # We used to match only the files named 'Makefile.in', but
-    # some people rename them; so instead we look at the file content.
-    # Grep'ing the first line is not enough: some people post-process
-    # each Makefile.in and add a new line on top of each file to say so.
-    # Grep'ing the whole file is not good either: AIX grep has a line
+    am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile which includes
+    # dependency-tracking related rules and includes.
+    # Grep'ing the whole file directly is not great: AIX grep has a line
     # limit of 2048, but all sed's we know have understand at least 4000.
-    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
-      dirpart=`AS_DIRNAME("$mf")`
-    else
-      continue
-    fi
-    # Extract the definition of DEPDIR, am__include, and am__quote
-    # from the Makefile without running 'make'.
-    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
-    test -z "$DEPDIR" && continue
-    am__include=`sed -n 's/^am__include = //p' < "$mf"`
-    test -z "$am__include" && continue
-    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
-    # Find all dependency output files, they are included files with
-    # $(DEPDIR) in their names.  We invoke sed twice because it is the
-    # simplest approach to changing $(DEPDIR) to its actual value in the
-    # expansion.
-    for file in `sed -n "
-      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
-        sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
-      # Make sure the directory exists.
-      test -f "$dirpart/$file" && continue
-      fdir=`AS_DIRNAME(["$file"])`
-      AS_MKDIR_P([$dirpart/$fdir])
-      # echo "creating $dirpart/$file"
-      echo '# dummy' > "$dirpart/$file"
-    done
+    sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \
+      || continue
+    am_dirpart=`AS_DIRNAME(["$am_mf"])`
+    am_filepart=`AS_BASENAME(["$am_mf"])`
+    AM_RUN_LOG([cd "$am_dirpart" \
+      && sed -e '/# am--include-marker/d' "$am_filepart" \
+        | $MAKE -f - am--depfiles]) || am_rc=$?
   done
+  if test $am_rc -ne 0; then
+    AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments
+    for automatic dependency tracking.  Try re-running configure with the
+    '--disable-dependency-tracking' option to at least be able to build
+    the package (albeit without support for automatic dependency tracking).])
+  fi
+  AS_UNSET([am_dirpart])
+  AS_UNSET([am_filepart])
+  AS_UNSET([am_mf])
+  AS_UNSET([am_rc])
+  rm -f conftest-deps.mk
 }
 ])# _AM_OUTPUT_DEPENDENCY_COMMANDS
 
@@ -457,18 +448,17 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
 # -----------------------------
 # This macro should only be invoked once -- use via AC_REQUIRE.
 #
-# This code is only required when automatic dependency tracking
-# is enabled.  FIXME.  This creates each '.P' file that we will
-# need in order to bootstrap the dependency handling code.
+# This code is only required when automatic dependency tracking is enabled.
+# This creates each '.Po' and '.Plo' makefile fragment that we'll need in
+# order to bootstrap the dependency handling code.
 AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
 [AC_CONFIG_COMMANDS([depfiles],
      [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
-     [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
-])
+     [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])])
 
 # Do all the work for Automake.                             -*- Autoconf -*-
 
-# Copyright (C) 1996-2017 Free Software Foundation, Inc.
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -555,8 +545,8 @@ AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
 AC_REQUIRE([AC_PROG_MKDIR_P])dnl
 # For better backward compatibility.  To be removed once Automake 1.9.x
 # dies out for good.  For more background, see:
-# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
-# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
 AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
 # We need awk for the "check" target (and possibly the TAP driver).  The
 # system "awk" is bad on some platforms.
@@ -623,7 +613,7 @@ END
 Aborting the configuration process, to ensure you take notice of the issue.
 
 You can download and install GNU coreutils to get an 'rm' implementation
-that behaves properly: <http://www.gnu.org/software/coreutils/>.
+that behaves properly: <https://www.gnu.org/software/coreutils/>.
 
 If you want to complete the configuration process using your problematic
 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
@@ -665,7 +655,7 @@ for _am_header in $config_headers :; do
 done
 echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
 
-# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -686,7 +676,7 @@ if test x"${install_sh+set}" != xset; then
 fi
 AC_SUBST([install_sh])])
 
-# Copyright (C) 2003-2017 Free Software Foundation, Inc.
+# Copyright (C) 2003-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -707,7 +697,7 @@ AC_SUBST([am__leading_dot])])
 
 # Check to see how 'make' treats includes.                 -*- Autoconf -*-
 
-# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -715,49 +705,42 @@ AC_SUBST([am__leading_dot])])
 
 # AM_MAKE_INCLUDE()
 # -----------------
-# Check to see how make treats includes.
+# Check whether make has an 'include' directive that can support all
+# the idioms we need for our automatic dependency tracking code.
 AC_DEFUN([AM_MAKE_INCLUDE],
-[am_make=${MAKE-make}
-cat > confinc << 'END'
+[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive])
+cat > confinc.mk << 'END'
 am__doit:
-       @echo this is the am__doit target
+       @echo this is the am__doit target >confinc.out
 .PHONY: am__doit
 END
-# If we don't find an include directive, just comment out the code.
-AC_MSG_CHECKING([for style of include used by $am_make])
 am__include="#"
 am__quote=
-_am_result=none
-# First try GNU make style include.
-echo "include confinc" > confmf
-# Ignore all kinds of additional output from 'make'.
-case `$am_make -s -f confmf 2> /dev/null` in #(
-*the\ am__doit\ target*)
-  am__include=include
-  am__quote=
-  _am_result=GNU
-  ;;
-esac
-# Now try BSD make style include.
-if test "$am__include" = "#"; then
-   echo '.include "confinc"' > confmf
-   case `$am_make -s -f confmf 2> /dev/null` in #(
-   *the\ am__doit\ target*)
-     am__include=.include
-     am__quote="\""
-     _am_result=BSD
-     ;;
-   esac
-fi
-AC_SUBST([am__include])
-AC_SUBST([am__quote])
-AC_MSG_RESULT([$_am_result])
-rm -f confinc confmf
-])
+# BSD make does it like this.
+echo '.include "confinc.mk" # ignored' > confmf.BSD
+# Other make implementations (GNU, Solaris 10, AIX) do it like this.
+echo 'include confinc.mk # ignored' > confmf.GNU
+_am_result=no
+for s in GNU BSD; do
+  AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out])
+  AS_CASE([$?:`cat confinc.out 2>/dev/null`],
+      ['0:this is the am__doit target'],
+      [AS_CASE([$s],
+          [BSD], [am__include='.include' am__quote='"'],
+          [am__include='include' am__quote=''])])
+  if test "$am__include" != "#"; then
+    _am_result="yes ($s style)"
+    break
+  fi
+done
+rm -f confinc.* confmf.*
+AC_MSG_RESULT([${_am_result}])
+AC_SUBST([am__include])])
+AC_SUBST([am__quote])])
 
 # Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
 
-# Copyright (C) 1997-2017 Free Software Foundation, Inc.
+# Copyright (C) 1997-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -796,7 +779,7 @@ fi
 
 # Helper functions for option handling.                     -*- Autoconf -*-
 
-# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -825,7 +808,7 @@ AC_DEFUN([_AM_SET_OPTIONS],
 AC_DEFUN([_AM_IF_OPTION],
 [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
 
-# Copyright (C) 1999-2017 Free Software Foundation, Inc.
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -872,7 +855,7 @@ AC_LANG_POP([C])])
 # For backward compatibility.
 AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
 
-# Copyright (C) 1999-2017 Free Software Foundation, Inc.
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -905,10 +888,12 @@ AC_DEFUN([AM_PATH_PYTHON],
  [
   dnl Find a Python interpreter.  Python versions prior to 2.0 are not
   dnl supported. (2.0 was released on October 16, 2000).
-  dnl FIXME: Remove the need to hard-code Python versions here.
   m4_define_default([_AM_PYTHON_INTERPRETER_LIST],
-[python python2 python3 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 python3.2 python3.1 python3.0 python2.7 dnl
- python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0])
+[python python2 python3 dnl
+ python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 dnl
+ python3.2 python3.1 python3.0 dnl
+ python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 dnl
+ python2.0])
 
   AC_ARG_VAR([PYTHON], [the Python interpreter])
 
@@ -1108,7 +1093,7 @@ for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]]
 sys.exit(sys.hexversion < minverhex)"
   AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])])
 
-# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1127,7 +1112,7 @@ AC_DEFUN([AM_RUN_LOG],
 
 # Check to make sure that the build environment is sane.    -*- Autoconf -*-
 
-# Copyright (C) 1996-2017 Free Software Foundation, Inc.
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1208,7 +1193,7 @@ AC_CONFIG_COMMANDS_PRE(
 rm -f conftest.file
 ])
 
-# Copyright (C) 2009-2017 Free Software Foundation, Inc.
+# Copyright (C) 2009-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1268,7 +1253,7 @@ AC_SUBST([AM_BACKSLASH])dnl
 _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
 ])
 
-# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1296,7 +1281,7 @@ fi
 INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
-# Copyright (C) 2006-2017 Free Software Foundation, Inc.
+# Copyright (C) 2006-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1315,7 +1300,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
 
 # Check how to create a tarball.                            -*- Autoconf -*-
 
-# Copyright (C) 2004-2017 Free Software Foundation, Inc.
+# Copyright (C) 2004-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1446,7 +1431,7 @@ AC_SUBST([am__tar])
 AC_SUBST([am__untar])
 ]) # _AM_PROG_TAR
 
-m4_include([m4/ac_python_devel.m4])
+m4_include([m4/ax_python_devel.m4])
 m4_include([m4/libtool.m4])
 m4_include([m4/ltoptions.m4])
 m4_include([m4/ltsugar.m4])
diff --git a/ar-lib b/ar-lib
index 05094d3..0baa4f6 100755 (executable)
--- a/ar-lib
+++ b/ar-lib
@@ -4,7 +4,7 @@
 me=ar-lib
 scriptversion=2012-03-01.08; # UTC
 
-# Copyright (C) 2010-2017 Free Software Foundation, Inc.
+# Copyright (C) 2010-2018 Free Software Foundation, Inc.
 # Written by Peter Rosin <peda@lysator.liu.se>.
 #
 # This program is free software; you can redistribute it and/or modify
@@ -18,7 +18,7 @@ scriptversion=2012-03-01.08; # UTC
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
diff --git a/compile b/compile
index a85b723..99e5052 100755 (executable)
--- a/compile
+++ b/compile
@@ -1,9 +1,9 @@
 #! /bin/sh
 # Wrapper for compilers which do not understand '-c -o'.
 
-scriptversion=2012-10-14.11; # UTC
+scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
 # Written by Tom Tromey <tromey@cygnus.com>.
 #
 # This program is free software; you can redistribute it and/or modify
@@ -17,7 +17,7 @@ scriptversion=2012-10-14.11; # UTC
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -255,7 +255,8 @@ EOF
     echo "compile $scriptversion"
     exit $?
     ;;
-  cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+  cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \
+  icl | *[/\\]icl | icl.exe | *[/\\]icl.exe )
     func_cl_wrapper "$@"      # Doesn't return...
     ;;
 esac
@@ -339,9 +340,9 @@ exit $ret
 # Local Variables:
 # mode: shell-script
 # sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-time-zone: "UTC0"
 # time-stamp-end: "; # UTC"
 # End:
index 8de1159..82ee330 100644 (file)
@@ -9,6 +9,9 @@
 /* Define to 1 if you have the <memory.h> header file. */
 #undef HAVE_MEMORY_H
 
+/* If available, contains the Python version number currently in use. */
+#undef HAVE_PYTHON
+
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
index 6364c9f..8695775 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for OpenFst 1.7.3.
+# Generated by GNU Autoconf 2.69 for OpenFst 1.7.4.
 #
 # Report bugs to <help@www.openfst.org>.
 #
@@ -590,8 +590,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='OpenFst'
 PACKAGE_TARNAME='openfst'
-PACKAGE_VERSION='1.7.3'
-PACKAGE_STRING='OpenFst 1.7.3'
+PACKAGE_VERSION='1.7.4'
+PACKAGE_STRING='OpenFst 1.7.4'
 PACKAGE_BUGREPORT='help@www.openfst.org'
 PACKAGE_URL=''
 
@@ -649,7 +649,7 @@ HAVE_SPECIAL_TRUE
 PYTHON_EXTRA_LDFLAGS
 PYTHON_EXTRA_LIBS
 PYTHON_SITE_PKG
-PYTHON_LDFLAGS
+PYTHON_LIBS
 PYTHON_CPPFLAGS
 pkgpyexecdir
 pyexecdir
@@ -723,7 +723,6 @@ am__nodep
 AMDEPBACKSLASH
 AMDEP_FALSE
 AMDEP_TRUE
-am__quote
 am__include
 DEPDIR
 OBJEXT
@@ -800,7 +799,8 @@ PACKAGE_VERSION
 PACKAGE_TARNAME
 PACKAGE_NAME
 PATH_SEPARATOR
-SHELL'
+SHELL
+am__quote'
 ac_subst_files=''
 ac_user_opts='
 enable_option_checking
@@ -1395,7 +1395,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures OpenFst 1.7.3 to adapt to many kinds of systems.
+\`configure' configures OpenFst 1.7.4 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1466,7 +1466,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of OpenFst 1.7.3:";;
+     short | recursive ) echo "Configuration of OpenFst 1.7.4:";;
    esac
   cat <<\_ACEOF
 
@@ -1598,7 +1598,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-OpenFst configure 1.7.3
+OpenFst configure 1.7.4
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2039,7 +2039,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by OpenFst $as_me 1.7.3, which was
+It was created by OpenFst $as_me 1.7.4, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2387,7 +2387,7 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
-am__api_version='1.15'
+am__api_version='1.16'
 
 ac_aux_dir=
 for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
@@ -2902,7 +2902,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='openfst'
- VERSION='1.7.3'
+ VERSION='1.7.4'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -2932,8 +2932,8 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
 
 # For better backward compatibility.  To be removed once Automake 1.9.x
 # dies out for good.  For more background, see:
-# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
-# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
 mkdir_p='$(MKDIR_P)'
 
 # We need awk for the "check" target (and possibly the TAP driver).  The
@@ -2984,7 +2984,7 @@ END
 Aborting the configuration process, to ensure you take notice of the issue.
 
 You can download and install GNU coreutils to get an 'rm' implementation
-that behaves properly: <http://www.gnu.org/software/coreutils/>.
+that behaves properly: <https://www.gnu.org/software/coreutils/>.
 
 If you want to complete the configuration process using your problematic
 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
@@ -2999,45 +2999,45 @@ DEPDIR="${am__leading_dot}deps"
 
 ac_config_commands="$ac_config_commands depfiles"
 
-
-am_make=${MAKE-make}
-cat > confinc << 'END'
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5
+$as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; }
+cat > confinc.mk << 'END'
 am__doit:
-       @echo this is the am__doit target
+       @echo this is the am__doit target >confinc.out
 .PHONY: am__doit
 END
-# If we don't find an include directive, just comment out the code.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
-$as_echo_n "checking for style of include used by $am_make... " >&6; }
 am__include="#"
 am__quote=
-_am_result=none
-# First try GNU make style include.
-echo "include confinc" > confmf
-# Ignore all kinds of additional output from 'make'.
-case `$am_make -s -f confmf 2> /dev/null` in #(
-*the\ am__doit\ target*)
-  am__include=include
-  am__quote=
-  _am_result=GNU
-  ;;
-esac
-# Now try BSD make style include.
-if test "$am__include" = "#"; then
-   echo '.include "confinc"' > confmf
-   case `$am_make -s -f confmf 2> /dev/null` in #(
-   *the\ am__doit\ target*)
-     am__include=.include
-     am__quote="\""
-     _am_result=BSD
+# BSD make does it like this.
+echo '.include "confinc.mk" # ignored' > confmf.BSD
+# Other make implementations (GNU, Solaris 10, AIX) do it like this.
+echo 'include confinc.mk # ignored' > confmf.GNU
+_am_result=no
+for s in GNU BSD; do
+  { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5
+   (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); }
+  case $?:`cat confinc.out 2>/dev/null` in #(
+  '0:this is the am__doit target') :
+    case $s in #(
+  BSD) :
+    am__include='.include' am__quote='"' ;; #(
+  *) :
+    am__include='include' am__quote='' ;;
+esac ;; #(
+  *) :
      ;;
-   esac
-fi
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
-$as_echo "$_am_result" >&6; }
-rm -f confinc confmf
+esac
+  if test "$am__include" != "#"; then
+    _am_result="yes ($s style)"
+    break
+  fi
+done
+rm -f confinc.* confmf.*
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5
+$as_echo "${_am_result}" >&6; }
 
 # Check whether --enable-dependency-tracking was given.
 if test "${enable_dependency_tracking+set}" = set; then :
@@ -4207,12 +4207,6 @@ unknown)
 esac
 
 
-# OpenFst does not throw exceptions, so we do not generate exception handling
-# code. However, users are free to re-enable exception handling.
-# OpenFst assumes char is unsigned; -fsigned-char is likely unsafe.
-CPPFLAGS="$CPPFLAGS -fno-exceptions -funsigned-char"
-CXXFLAGS="$CXXFLAGS -std=c++11"
-
 ac_ext=cpp
 ac_cpp='$CXXCPP $CPPFLAGS'
 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -4598,6 +4592,10 @@ else
 fi
 
 
+# This library does not throw exceptions, so we do not generate exception
+# handling code. However, users are free to re-enable exception handling.
+CXX="$CXX -std=c++11 -fno-exceptions"
+
 # Check whether --enable-static was given.
 if test "${enable_static+set}" = set; then :
   enableval=$enable_static; p=${PACKAGE-default}
@@ -6801,11 +6799,8 @@ _LT_EOF
   test $ac_status = 0; }; then
     # Now try to grab the symbols.
     nlist=conftest.nm
-    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
-  (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && test -s "$nlist"; then
+    $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&5
+    if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&5 && test -s "$nlist"; then
       # Try sorting and uniquifying the output.
       if sort "$nlist" | uniq > "$nlist"T; then
        mv -f "$nlist"T "$nlist"
@@ -13077,7 +13072,7 @@ with_gnu_ld=$lt_cv_prog_gnu_ld
       # Commands to make compiler produce verbose output that lists
       # what "hidden" libraries, object files and flags are used when
       # linking a shared library.
-      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
 
     else
       GXX=no
@@ -13569,7 +13564,7 @@ fi
             # explicitly linking system object files so we need to strip them
             # from the output so that they don't get included in the library
             # dependencies.
-            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
             ;;
           *)
             if test yes = "$GXX"; then
@@ -13634,7 +13629,7 @@ fi
            # explicitly linking system object files so we need to strip them
            # from the output so that they don't get included in the library
            # dependencies.
-           output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+           output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
            ;;
           *)
            if test yes = "$GXX"; then
@@ -13973,7 +13968,7 @@ fi
              # Commands to make compiler produce verbose output that lists
              # what "hidden" libraries, object files and flags are used when
              # linking a shared library.
-             output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+             output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
 
            else
              # FIXME: insert proper C++ library support
@@ -14057,7 +14052,7 @@ fi
                # Commands to make compiler produce verbose output that lists
                # what "hidden" libraries, object files and flags are used when
                # linking a shared library.
-               output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+               output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
              else
                # g++ 2.7 appears to require '-G' NOT '-shared' on this
                # platform.
@@ -14068,7 +14063,7 @@ fi
                # Commands to make compiler produce verbose output that lists
                # what "hidden" libraries, object files and flags are used when
                # linking a shared library.
-               output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+               output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
              fi
 
              hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir'
@@ -16228,7 +16223,7 @@ if ${am_cv_pathless_PYTHON+:} false; then :
   $as_echo_n "(cached) " >&6
 else
 
-       for am_cv_pathless_PYTHON in python python2 python3 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 python3.2 python3.1 python3.0 python2.7  python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 none; do
+       for am_cv_pathless_PYTHON in python python2 python3  python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3  python3.2 python3.1 python3.0  python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1  python2.0 none; do
          test "$am_cv_pathless_PYTHON" = none && break
          prog="import sys
 # split strings by '.' and convert to numeric.  Append some zeros
@@ -16504,9 +16499,9 @@ fi
        #
        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a version of Python >= '2.1.0'" >&5
 $as_echo_n "checking for a version of Python >= '2.1.0'... " >&6; }
-       ac_supports_python_ver=`$PYTHON -c "import sys, string; \
-               ver = string.split(sys.version)[0]; \
-               print ver >= '2.1.0'"`
+       ac_supports_python_ver=`$PYTHON -c "import sys; \
+               ver = sys.version.split ()[0]; \
+               print (ver >= '2.1.0')"`
        if test "$ac_supports_python_ver" != "True"; then
                if test -z "$PYTHON_NOVERSIONCHECK"; then
                        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
@@ -16517,7 +16512,7 @@ as_fn_error $? "
 This version of the AC_PYTHON_DEVEL macro
 doesn't work properly with versions of Python before
 2.1.0. You may need to re-run configure, setting the
-variables PYTHON_CPPFLAGS, PYTHON_LDFLAGS, PYTHON_SITE_PKG,
+variables PYTHON_CPPFLAGS, PYTHON_LIBS, PYTHON_SITE_PKG,
 PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand.
 Moreover, to disable this check, set PYTHON_NOVERSIONCHECK
 to something else than an empty string.
@@ -16538,11 +16533,11 @@ $as_echo "yes" >&6; }
        if test -n ">= '2.7'"; then
                { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a version of Python >= '2.7'" >&5
 $as_echo_n "checking for a version of Python >= '2.7'... " >&6; }
-               ac_supports_python_ver=`$PYTHON -c "import sys, string; \
-                       ver = string.split(sys.version)[0]; \
-                       print ver >= '2.7'"`
+               ac_supports_python_ver=`$PYTHON -c "import sys; \
+                       ver = sys.version.split ()[0]; \
+                       print (ver >= '2.7')"`
                if test "$ac_supports_python_ver" = "True"; then
-                  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+                  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
                else
                        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
@@ -16562,7 +16557,7 @@ variable to configure. See \`\`configure --help'' for reference.
        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the distutils Python package" >&5
 $as_echo_n "checking for the distutils Python package... " >&6; }
        ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`
-       if test -z "$ac_distutils_result"; then
+       if test $? -eq 0; then
                { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
        else
@@ -16581,9 +16576,15 @@ $ac_distutils_result" "$LINENO" 5
 $as_echo_n "checking for Python include path... " >&6; }
        if test -z "$PYTHON_CPPFLAGS"; then
                python_path=`$PYTHON -c "import distutils.sysconfig; \
-                       print distutils.sysconfig.get_python_inc();"`
+                       print (distutils.sysconfig.get_python_inc ());"`
+               plat_python_path=`$PYTHON -c "import distutils.sysconfig; \
+                       print (distutils.sysconfig.get_python_inc (plat_specific=1));"`
                if test -n "${python_path}"; then
-                       python_path="-I$python_path"
+                       if test "${plat_python_path}" != "${python_path}"; then
+                               python_path="-I$python_path -I$plat_python_path"
+                       else
+                               python_path="-I$python_path"
+                       fi
                fi
                PYTHON_CPPFLAGS=$python_path
        fi
@@ -16596,28 +16597,83 @@ $as_echo "$PYTHON_CPPFLAGS" >&6; }
        #
        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python library path" >&5
 $as_echo_n "checking for Python library path... " >&6; }
-       if test -z "$PYTHON_LDFLAGS"; then
+       if test -z "$PYTHON_LIBS"; then
                # (makes two attempts to ensure we've got a version number
                # from the interpreter)
-               py_version=`$PYTHON -c "from distutils.sysconfig import *; \
-                       from string import join; \
-                       print join(get_config_vars('VERSION'))"`
-               if test "$py_version" == "None"; then
+               ac_python_version=`cat<<EOD | $PYTHON -
+
+# join all versioning strings, on some systems
+# major/minor numbers could be in different list elements
+from distutils.sysconfig import *
+e = get_config_var('VERSION')
+if e is not None:
+       print(e)
+EOD`
+
+               if test -z "$ac_python_version"; then
                        if test -n "$PYTHON_VERSION"; then
-                               py_version=$PYTHON_VERSION
+                               ac_python_version=$PYTHON_VERSION
                        else
-                               py_version=`$PYTHON -c "import sys; \
-                                       print sys.version[:3]"`
+                               ac_python_version=`$PYTHON -c "import sys; \
+                                       print (sys.version[:3])"`
                        fi
                fi
 
-               PYTHON_LDFLAGS=`$PYTHON -c "from distutils.sysconfig import *; \
-                       from string import join; \
-                       print '-L' + get_python_lib(0,1), \
-                       '-lpython';"`$py_version
+               # Make the versioning information available to the compiler
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_PYTHON "$ac_python_version"
+_ACEOF
+
+
+               # First, the library directory:
+               ac_python_libdir=`cat<<EOD | $PYTHON -
+
+# There should be only one
+import distutils.sysconfig
+e = distutils.sysconfig.get_config_var('LIBDIR')
+if e is not None:
+       print (e)
+EOD`
+
+               # Now, for the library:
+               ac_python_library=`cat<<EOD | $PYTHON -
+
+import distutils.sysconfig
+c = distutils.sysconfig.get_config_vars()
+if 'LDVERSION' in c:
+       print ('python'+c['LDVERSION'])
+else:
+       print ('python'+c['VERSION'])
+EOD`
+
+               # This small piece shamelessly adapted from PostgreSQL python macro;
+               # credits goes to momjian, I think. I'd like to put the right name
+               # in the credits, if someone can point me in the right direction... ?
+               #
+               if test -n "$ac_python_libdir" -a -n "$ac_python_library"
+               then
+                       # use the official shared library
+                       ac_python_library=`echo "$ac_python_library" | sed "s/^lib//"`
+                       PYTHON_LIBS="-L$ac_python_libdir -l$ac_python_library"
+               else
+                       # old way: use libpython from python_configdir
+                       ac_python_libdir=`$PYTHON -c \
+                         "from distutils.sysconfig import get_python_lib as f; \
+                         import os; \
+                         print (os.path.join(f(plat_specific=1, standard_lib=1), 'config'));"`
+                       PYTHON_LIBS="-L$ac_python_libdir -lpython$ac_python_version"
+               fi
+
+               if test -z "PYTHON_LIBS"; then
+                       as_fn_error $? "
+  Cannot determine location of your Python DSO. Please check it was installed with
+  dynamic libraries enabled, or try setting PYTHON_LIBS by hand.
+                       " "$LINENO" 5
+               fi
        fi
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON_LDFLAGS" >&5
-$as_echo "$PYTHON_LDFLAGS" >&6; }
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON_LIBS" >&5
+$as_echo "$PYTHON_LIBS" >&6; }
 
 
        #
@@ -16627,7 +16683,7 @@ $as_echo "$PYTHON_LDFLAGS" >&6; }
 $as_echo_n "checking for Python site-packages path... " >&6; }
        if test -z "$PYTHON_SITE_PKG"; then
                PYTHON_SITE_PKG=`$PYTHON -c "import distutils.sysconfig; \
-                       print distutils.sysconfig.get_python_lib(0,0);"`
+                       print (distutils.sysconfig.get_python_lib(0,0));"`
        fi
        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON_SITE_PKG" >&5
 $as_echo "$PYTHON_SITE_PKG" >&6; }
@@ -16641,7 +16697,7 @@ $as_echo_n "checking python extra libraries... " >&6; }
        if test -z "$PYTHON_EXTRA_LIBS"; then
           PYTHON_EXTRA_LIBS=`$PYTHON -c "import distutils.sysconfig; \
                 conf = distutils.sysconfig.get_config_var; \
-                print conf('LOCALMODLIBS'), conf('LIBS')"`
+                print (conf('LIBS') + ' ' + conf('SYSLIBS'))"`
        fi
        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON_EXTRA_LIBS" >&5
 $as_echo "$PYTHON_EXTRA_LIBS" >&6; }
@@ -16655,7 +16711,7 @@ $as_echo_n "checking python extra linking flags... " >&6; }
        if test -z "$PYTHON_EXTRA_LDFLAGS"; then
                PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "import distutils.sysconfig; \
                        conf = distutils.sysconfig.get_config_var; \
-                       print conf('LINKFORSHARED')"`
+                       print (conf('LINKFORSHARED'))"`
        fi
        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON_EXTRA_LDFLAGS" >&5
 $as_echo "$PYTHON_EXTRA_LDFLAGS" >&6; }
@@ -16666,29 +16722,31 @@ $as_echo "$PYTHON_EXTRA_LDFLAGS" >&6; }
        #
        { $as_echo "$as_me:${as_lineno-$LINENO}: checking consistency of all components of python development environment" >&5
 $as_echo_n "checking consistency of all components of python development environment... " >&6; }
+       # save current global flags
+       ac_save_LIBS="$LIBS"
+       ac_save_LDFLAGS="$LDFLAGS"
+       ac_save_CPPFLAGS="$CPPFLAGS"
+       LIBS="$ac_save_LIBS $PYTHON_LIBS $PYTHON_EXTRA_LIBS $PYTHON_EXTRA_LIBS"
+       LDFLAGS="$ac_save_LDFLAGS $PYTHON_EXTRA_LDFLAGS"
+       CPPFLAGS="$ac_save_CPPFLAGS $PYTHON_CPPFLAGS"
        ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
-       # save current global flags
-       LIBS="$ac_save_LIBS $PYTHON_LDFLAGS"
-       CPPFLAGS="$ac_save_CPPFLAGS $PYTHON_CPPFLAGS"
        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
                #include <Python.h>
-
 int
 main ()
 {
-
-               Py_Initialize();
-
+Py_Initialize();
   ;
   return 0;
 }
+
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
   pythonexists=yes
@@ -16697,33 +16755,37 @@ else
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
+       ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+       # turn back to default flags
+       CPPFLAGS="$ac_save_CPPFLAGS"
+       LIBS="$ac_save_LIBS"
+       LDFLAGS="$ac_save_LDFLAGS"
 
        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pythonexists" >&5
 $as_echo "$pythonexists" >&6; }
 
-        if test ! "$pythonexists" = "yes"; then
-          as_fn_error $? "
+        if test ! "x$pythonexists" = "xyes"; then
+          { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "
   Could not link test program to Python. Maybe the main Python library has been
   installed in some non-standard library path. If so, pass it to configure,
-  via the LDFLAGS environment variable.
-  Example: ./configure LDFLAGS=\"-L/usr/non-standard-path/python/lib\"
+  via the LIBS environment variable.
+  Example: ./configure LIBS=\"-L/usr/non-standard-path/python/lib\"
   ============================================================================
    ERROR!
    You probably have to install the development version of the Python package
    for your distribution.  The exact name of this package varies among them.
   ============================================================================
-          " "$LINENO" 5
+
+See \`config.log' for more details" "$LINENO" 5; }
          PYTHON_VERSION=""
        fi
-       ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-       # turn back to default flags
-       CPPFLAGS="$ac_save_CPPFLAGS"
-       LIBS="$ac_save_LIBS"
 
        #
        # all done!
@@ -17489,7 +17551,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by OpenFst $as_me 1.7.3, which was
+This file was extended by OpenFst $as_me 1.7.4, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -17555,7 +17617,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-OpenFst config.status 1.7.3
+OpenFst config.status 1.7.4
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -17674,7 +17736,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 #
 # INIT-COMMANDS
 #
-AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"
 
 
 # The HP-UX ksh and POSIX shell print the target directory to stdout
@@ -18687,29 +18749,35 @@ $as_echo "$as_me: executing $ac_file commands" >&6;}
   # Older Autoconf quotes --file arguments for eval, but not when files
   # are listed without --file.  Let's play safe and only enable the eval
   # if we detect the quoting.
-  case $CONFIG_FILES in
-  *\'*) eval set x "$CONFIG_FILES" ;;
-  *)   set x $CONFIG_FILES ;;
-  esac
+  # TODO: see whether this extra hack can be removed once we start
+  # requiring Autoconf 2.70 or later.
+  case $CONFIG_FILES in #(
+  *\'*) :
+    eval set x "$CONFIG_FILES" ;; #(
+  *) :
+    set x $CONFIG_FILES ;; #(
+  *) :
+     ;;
+esac
   shift
-  for mf
+  # Used to flag and report bootstrapping failures.
+  am_rc=0
+  for am_mf
   do
     # Strip MF so we end up with the name of the file.
-    mf=`echo "$mf" | sed -e 's/:.*$//'`
-    # Check whether this is an Automake generated Makefile or not.
-    # We used to match only the files named 'Makefile.in', but
-    # some people rename them; so instead we look at the file content.
-    # Grep'ing the first line is not enough: some people post-process
-    # each Makefile.in and add a new line on top of each file to say so.
-    # Grep'ing the whole file is not good either: AIX grep has a line
+    am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile which includes
+    # dependency-tracking related rules and includes.
+    # Grep'ing the whole file directly is not great: AIX grep has a line
     # limit of 2048, but all sed's we know have understand at least 4000.
-    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
-      dirpart=`$as_dirname -- "$mf" ||
-$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-        X"$mf" : 'X\(//\)[^/]' \| \
-        X"$mf" : 'X\(//\)$' \| \
-        X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$mf" |
+    sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \
+      || continue
+    am_dirpart=`$as_dirname -- "$am_mf" ||
+$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$am_mf" : 'X\(//\)[^/]' \| \
+        X"$am_mf" : 'X\(//\)$' \| \
+        X"$am_mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$am_mf" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
            s//\1/
            q
@@ -18727,53 +18795,48 @@ $as_echo X"$mf" |
            q
          }
          s/.*/./; q'`
-    else
-      continue
-    fi
-    # Extract the definition of DEPDIR, am__include, and am__quote
-    # from the Makefile without running 'make'.
-    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
-    test -z "$DEPDIR" && continue
-    am__include=`sed -n 's/^am__include = //p' < "$mf"`
-    test -z "$am__include" && continue
-    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
-    # Find all dependency output files, they are included files with
-    # $(DEPDIR) in their names.  We invoke sed twice because it is the
-    # simplest approach to changing $(DEPDIR) to its actual value in the
-    # expansion.
-    for file in `sed -n "
-      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
-        sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
-      # Make sure the directory exists.
-      test -f "$dirpart/$file" && continue
-      fdir=`$as_dirname -- "$file" ||
-$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-        X"$file" : 'X\(//\)[^/]' \| \
-        X"$file" : 'X\(//\)$' \| \
-        X"$file" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$file" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
-           s//\1/
-           q
-         }
-         /^X\(\/\/\)[^/].*/{
+    am_filepart=`$as_basename -- "$am_mf" ||
+$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$am_mf" : 'X\(//\)$' \| \
+        X"$am_mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$am_mf" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
            s//\1/
            q
          }
-         /^X\(\/\/\)$/{
+         /^X\/\(\/\/\)$/{
            s//\1/
            q
          }
-         /^X\(\/\).*/{
+         /^X\/\(\/\).*/{
            s//\1/
            q
          }
          s/.*/./; q'`
-      as_dir=$dirpart/$fdir; as_fn_mkdir_p
-      # echo "creating $dirpart/$file"
-      echo '# dummy' > "$dirpart/$file"
-    done
+    { echo "$as_me:$LINENO: cd "$am_dirpart" \
+      && sed -e '/# am--include-marker/d' "$am_filepart" \
+        | $MAKE -f - am--depfiles" >&5
+   (cd "$am_dirpart" \
+      && sed -e '/# am--include-marker/d' "$am_filepart" \
+        | $MAKE -f - am--depfiles) >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } || am_rc=$?
   done
+  if test $am_rc -ne 0; then
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "Something went wrong bootstrapping makefile fragments
+    for automatic dependency tracking.  Try re-running configure with the
+    '--disable-dependency-tracking' option to at least be able to build
+    the package (albeit without support for automatic dependency tracking).
+See \`config.log' for more details" "$LINENO" 5; }
+  fi
+  { am_dirpart=; unset am_dirpart;}
+  { am_filepart=; unset am_filepart;}
+  { am_mf=; unset am_mf;}
+  { am_rc=; unset am_rc;}
+  rm -f conftest-deps.mk
 }
  ;;
     "libtool":C)
index 6ff5685..5ad140a 100644 (file)
@@ -1,14 +1,12 @@
-AC_INIT([OpenFst], [1.7.3], [help@www.openfst.org])
+AC_INIT([OpenFst], [1.7.4], [help@www.openfst.org])
 AM_INIT_AUTOMAKE([foreign nostdinc -Wall -Werror subdir-objects])
 AM_PROG_AR
 
-# OpenFst does not throw exceptions, so we do not generate exception handling
-# code. However, users are free to re-enable exception handling.
-# OpenFst assumes char is unsigned; -fsigned-char is likely unsafe.
-CPPFLAGS="$CPPFLAGS -fno-exceptions -funsigned-char"
-CXXFLAGS="$CXXFLAGS -std=c++11"
-
 AC_PROG_CXX
+# This library does not throw exceptions, so we do not generate exception
+# handling code. However, users are free to re-enable exception handling.
+CXX="$CXX -std=c++11 -fno-exceptions"
+
 AC_DISABLE_STATIC
 AC_PROG_LIBTOOL
 
diff --git a/depcomp b/depcomp
index b39f98f..65cbf70 100755 (executable)
--- a/depcomp
+++ b/depcomp
@@ -1,9 +1,9 @@
 #! /bin/sh
 # depcomp - compile a program generating dependencies as side-effects
 
-scriptversion=2016-01-11.22; # UTC
+scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1999-2017 Free Software Foundation, Inc.
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@ scriptversion=2016-01-11.22; # UTC
 # GNU General Public License for more details.
 
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -783,7 +783,7 @@ exit 0
 # Local Variables:
 # mode: shell-script
 # sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
 # time-stamp-time-zone: "UTC0"
index 59990a1..8175c64 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 # install - install a program, script, or datafile
 
-scriptversion=2014-09-12.12; # UTC
+scriptversion=2018-03-11.20; # UTC
 
 # This originates from X11R5 (mit/util/scripts/install.sh), which was
 # later released in X11R6 (xc/config/util/install.sh) with the
@@ -271,15 +271,18 @@ do
     fi
     dst=$dst_arg
 
-    # If destination is a directory, append the input filename; won't work
-    # if double slashes aren't ignored.
+    # If destination is a directory, append the input filename.
     if test -d "$dst"; then
       if test "$is_target_a_directory" = never; then
         echo "$0: $dst_arg: Is a directory" >&2
         exit 1
       fi
       dstdir=$dst
-      dst=$dstdir/`basename "$src"`
+      dstbase=`basename "$src"`
+      case $dst in
+       */) dst=$dst$dstbase;;
+       *)  dst=$dst/$dstbase;;
+      esac
       dstdir_status=0
     else
       dstdir=`dirname "$dst"`
@@ -288,6 +291,11 @@ do
     fi
   fi
 
+  case $dstdir in
+    */) dstdirslash=$dstdir;;
+    *)  dstdirslash=$dstdir/;;
+  esac
+
   obsolete_mkdir_used=false
 
   if test $dstdir_status != 0; then
@@ -324,14 +332,16 @@ do
             # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
             ;;
           *)
-            # $RANDOM is not portable (e.g. dash);  use it when possible to
-            # lower collision chance
+            # Note that $RANDOM variable is not portable (e.g. dash);  Use it
+            # here however when possible just to lower collision chance.
             tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+
             trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
 
-            # As "mkdir -p" follows symlinks and we work in /tmp possibly;  so
-            # create the $tmpdir first (and fail if unsuccessful) to make sure
-            # that nobody tries to guess the $tmpdir name.
+            # Because "mkdir -p" follows existing symlinks and we likely work
+            # directly in world-writeable /tmp, make sure that the '$tmpdir'
+            # directory is successfully created first before we actually test
+            # 'mkdir -p' feature.
             if (umask $mkdir_umask &&
                 $mkdirprog $mkdir_mode "$tmpdir" &&
                 exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
@@ -434,8 +444,8 @@ do
   else
 
     # Make a couple of temp file names in the proper directory.
-    dsttmp=$dstdir/_inst.$$_
-    rmtmp=$dstdir/_rm.$$_
+    dsttmp=${dstdirslash}_inst.$$_
+    rmtmp=${dstdirslash}_rm.$$_
 
     # Trap to clean up those temp files at exit.
     trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
@@ -500,9 +510,9 @@ do
 done
 
 # Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-time-zone: "UTC0"
 # time-stamp-end: "; # UTC"
 # End:
index e4eda6d..c12c197 100644 (file)
--- a/ltmain.sh
+++ b/ltmain.sh
@@ -31,7 +31,7 @@
 
 PROGRAM=libtool
 PACKAGE=libtool
-VERSION="2.4.6 Debian-2.4.6-2.1"
+VERSION="2.4.6 Debian-2.4.6-9"
 package_revision=2.4.6
 
 
@@ -64,7 +64,7 @@ package_revision=2.4.6
 # libraries, which are installed to $pkgauxdir.
 
 # Set a version string for this script.
-scriptversion=2015-10-12.13; # UTC
+scriptversion=2015-01-20.17; # UTC
 
 # General shell script boiler plate, and helper functions.
 # Written by Gary V. Vaughan, 2004
@@ -580,16 +580,16 @@ if test yes = "$_G_HAVE_PLUSEQ_OP"; then
   {
     $debug_cmd
 
-    func_quote_arg pretty "$2"
-    eval "$1+=\\ \$func_quote_arg_result"
+    func_quote_for_eval "$2"
+    eval "$1+=\\ \$func_quote_for_eval_result"
   }'
 else
   func_append_quoted ()
   {
     $debug_cmd
 
-    func_quote_arg pretty "$2"
-    eval "$1=\$$1\\ \$func_quote_arg_result"
+    func_quote_for_eval "$2"
+    eval "$1=\$$1\\ \$func_quote_for_eval_result"
   }
 fi
 
@@ -1091,181 +1091,85 @@ func_relative_path ()
 }
 
 
-# func_quote_portable EVAL ARG
-# ----------------------------
-# Internal function to portably implement func_quote_arg.  Note that we still
-# keep attention to performance here so we as much as possible try to avoid
-# calling sed binary (so far O(N) complexity as long as func_append is O(1)).
-func_quote_portable ()
+# func_quote_for_eval ARG...
+# --------------------------
+# Aesthetically quote ARGs to be evaled later.
+# This function returns two values:
+#   i) func_quote_for_eval_result
+#      double-quoted, suitable for a subsequent eval
+#  ii) func_quote_for_eval_unquoted_result
+#      has all characters that are still active within double
+#      quotes backslashified.
+func_quote_for_eval ()
 {
     $debug_cmd
 
-    func_quote_portable_result=$2
-
-    # one-time-loop (easy break)
-    while true
-    do
-      if $1; then
-        func_quote_portable_result=`$ECHO "$2" | $SED \
-          -e "$sed_double_quote_subst" -e "$sed_double_backslash"`
-        break
-      fi
-
-      # Quote for eval.
-      case $func_quote_portable_result in
+    func_quote_for_eval_unquoted_result=
+    func_quote_for_eval_result=
+    while test 0 -lt $#; do
+      case $1 in
         *[\\\`\"\$]*)
-          case $func_quote_portable_result in
-            *[\[\*\?]*)
-              func_quote_portable_result=`$ECHO "$func_quote_portable_result" | $SED "$sed_quote_subst"`
-              break
-              ;;
-          esac
+         _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;;
+        *)
+          _G_unquoted_arg=$1 ;;
+      esac
+      if test -n "$func_quote_for_eval_unquoted_result"; then
+       func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg"
+      else
+        func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg"
+      fi
 
-          func_quote_portable_old_IFS=$IFS
-          for _G_char in '\' '`' '"' '$'
-          do
-            # STATE($1) PREV($2) SEPARATOR($3)
-            set start "" ""
-            func_quote_portable_result=dummy"$_G_char$func_quote_portable_result$_G_char"dummy
-            IFS=$_G_char
-            for _G_part in $func_quote_portable_result
-            do
-              case $1 in
-              quote)
-                func_append func_quote_portable_result "$3$2"
-                set quote "$_G_part" "\\$_G_char"
-                ;;
-              start)
-                set first "" ""
-                func_quote_portable_result=
-                ;;
-              first)
-                set quote "$_G_part" ""
-                ;;
-              esac
-            done
-          done
-          IFS=$func_quote_portable_old_IFS
+      case $_G_unquoted_arg in
+        # Double-quote args containing shell metacharacters to delay
+        # word splitting, command substitution and variable expansion
+        # for a subsequent eval.
+        # Many Bourne shells cannot handle close brackets correctly
+        # in scan sets, so we specify it separately.
+        *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \  ]*|*]*|"")
+          _G_quoted_arg=\"$_G_unquoted_arg\"
           ;;
-        *) ;;
+        *)
+          _G_quoted_arg=$_G_unquoted_arg
+         ;;
       esac
-      break
-    done
 
-    func_quote_portable_unquoted_result=$func_quote_portable_result
-    case $func_quote_portable_result in
-      # double-quote args containing shell metacharacters to delay
-      # word splitting, command substitution and variable expansion
-      # for a subsequent eval.
-      # many bourne shells cannot handle close brackets correctly
-      # in scan sets, so we specify it separately.
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
-        func_quote_portable_result=\"$func_quote_portable_result\"
-        ;;
-    esac
+      if test -n "$func_quote_for_eval_result"; then
+       func_append func_quote_for_eval_result " $_G_quoted_arg"
+      else
+        func_append func_quote_for_eval_result "$_G_quoted_arg"
+      fi
+      shift
+    done
 }
 
 
-# func_quotefast_eval ARG
-# -----------------------
-# Quote one ARG (internal).  This is equivalent to 'func_quote_arg eval ARG',
-# but optimized for speed.  Result is stored in $func_quotefast_eval.
-if test xyes = `(x=; printf -v x %q yes; echo x"$x") 2>/dev/null`; then
-  func_quotefast_eval ()
-  {
-    printf -v func_quotefast_eval_result %q "$1"
-  }
-else
-  func_quotefast_eval ()
-  {
-    func_quote_portable false "$1"
-    func_quotefast_eval_result=$func_quote_portable_result
-  }
-fi
-
+# func_quote_for_expand ARG
+# -------------------------
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
+{
+    $debug_cmd
 
-# func_quote_arg MODEs ARG
-# ------------------------
-# Quote one ARG to be evaled later.  MODEs argument may contain zero ore more
-# specifiers listed below separated by ',' character.  This function returns two
-# values:
-#   i) func_quote_arg_result
-#      double-quoted (when needed), suitable for a subsequent eval
-#  ii) func_quote_arg_unquoted_result
-#      has all characters that are still active within double
-#      quotes backslashified.  Available only if 'unquoted' is specified.
-#
-# Available modes:
-# ----------------
-# 'eval' (default)
-#       - escape shell special characters
-# 'expand'
-#       - the same as 'eval';  but do not quote variable references
-# 'pretty'
-#       - request aesthetic output, i.e. '"a b"' instead of 'a\ b'.  This might
-#         later used in func_quote to get output like: 'echo "a b"' instead of
-#         'echo a\ b'.  This is slower than default on some shells.
-# 'unquoted'
-#       - produce also $func_quote_arg_unquoted_result which does not contain
-#         wrapping double-quotes.
-#
-# Examples for 'func_quote_arg pretty,unquoted string':
-#
-#   string      | *_result              | *_unquoted_result
-#   ------------+-----------------------+-------------------
-#   "           | \"                    | \"
-#   a b         | "a b"                 | a b
-#   "a b"       | "\"a b\""             | \"a b\"
-#   *           | "*"                   | *
-#   z="${x-$y}" | "z=\"\${x-\$y}\""     | z=\"\${x-\$y}\"
-#
-# Examples for 'func_quote_arg pretty,unquoted,expand string':
-#
-#   string        |   *_result          |  *_unquoted_result
-#   --------------+---------------------+--------------------
-#   z="${x-$y}"   | "z=\"${x-$y}\""     | z=\"${x-$y}\"
-func_quote_arg ()
-{
-    _G_quote_expand=false
-    case ,$1, in
-      *,expand,*)
-        _G_quote_expand=:
-        ;;
+    case $1 in
+      *[\\\`\"]*)
+       _G_arg=`$ECHO "$1" | $SED \
+           -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;;
+      *)
+        _G_arg=$1 ;;
     esac
 
-    case ,$1, in
-      *,pretty,*|*,expand,*|*,unquoted,*)
-        func_quote_portable $_G_quote_expand "$2"
-        func_quote_arg_result=$func_quote_portable_result
-        func_quote_arg_unquoted_result=$func_quote_portable_unquoted_result
-        ;;
-      *)
-        # Faster quote-for-eval for some shells.
-        func_quotefast_eval "$2"
-        func_quote_arg_result=$func_quotefast_eval_result
+    case $_G_arg in
+      # Double-quote args containing shell metacharacters to delay
+      # word splitting and command substitution for a subsequent eval.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
+        _G_arg=\"$_G_arg\"
         ;;
     esac
-}
 
-
-# func_quote MODEs ARGs...
-# ------------------------
-# Quote all ARGs to be evaled later and join them into single command.  See
-# func_quote_arg's description for more info.
-func_quote ()
-{
-    $debug_cmd
-    _G_func_quote_mode=$1 ; shift
-    func_quote_result=
-    while test 0 -lt $#; do
-      func_quote_arg "$_G_func_quote_mode" "$1"
-      if test -n "$func_quote_result"; then
-        func_append func_quote_result " $func_quote_arg_result"
-      else
-        func_append func_quote_result "$func_quote_arg_result"
-      fi
-      shift
-    done
+    func_quote_for_expand_result=$_G_arg
 }
 
 
@@ -1311,8 +1215,8 @@ func_show_eval ()
     _G_cmd=$1
     _G_fail_exp=${2-':'}
 
-    func_quote_arg pretty,expand "$_G_cmd"
-    eval "func_notquiet $func_quote_arg_result"
+    func_quote_for_expand "$_G_cmd"
+    eval "func_notquiet $func_quote_for_expand_result"
 
     $opt_dry_run || {
       eval "$_G_cmd"
@@ -1337,8 +1241,8 @@ func_show_eval_locale ()
     _G_fail_exp=${2-':'}
 
     $opt_quiet || {
-      func_quote_arg expand,pretty "$_G_cmd"
-      eval "func_echo $func_quote_arg_result"
+      func_quote_for_expand "$_G_cmd"
+      eval "func_echo $func_quote_for_expand_result"
     }
 
     $opt_dry_run || {
@@ -1466,7 +1370,7 @@ func_lt_ver ()
 #! /bin/sh
 
 # Set a version string for this script.
-scriptversion=2015-10-12.13; # UTC
+scriptversion=2015-10-07.11; # UTC
 
 # A portable, pluggable option parser for Bourne shell.
 # Written by Gary V. Vaughan, 2010
@@ -1676,8 +1580,8 @@ func_run_hooks ()
 #    '
 #        # No change in '$@' (ignored completely by this hook).  There is
 #        # no need to do the equivalent (but slower) action:
-#        # func_quote eval ${1+"$@"}
-#        # my_options_prep_result=$func_quote_result
+#        # func_quote_for_eval ${1+"$@"}
+#        # my_options_prep_result=$func_quote_for_eval_result
 #        false
 #    }
 #    func_add_hook func_options_prep my_options_prep
@@ -1713,8 +1617,8 @@ func_run_hooks ()
 #        done
 #
 #        if $args_changed; then
-#          func_quote eval ${1+"$@"}
-#          my_silent_option_result=$func_quote_result
+#          func_quote_for_eval ${1+"$@"}
+#          my_silent_option_result=$func_quote_for_eval_result
 #        fi
 #
 #        $args_changed
@@ -1781,8 +1685,8 @@ func_options ()
     if $_G_rc_options; then
       func_options_result=$_G_res_var
     else
-      func_quote eval ${1+"$@"}
-      func_options_result=$func_quote_result
+      func_quote_for_eval ${1+"$@"}
+      func_options_result=$func_quote_for_eval_result
     fi
 
     $_G_rc_options
@@ -1925,8 +1829,8 @@ func_parse_options ()
 
     if $_G_rc_parse_options; then
       # save modified positional parameters for caller
-      func_quote eval ${1+"$@"}
-      func_parse_options_result=$func_quote_result
+      func_quote_for_eval ${1+"$@"}
+      func_parse_options_result=$func_quote_for_eval_result
     fi
 
     $_G_rc_parse_options
@@ -2237,7 +2141,7 @@ include the following information:
        compiler:       $LTCC
        compiler flags: $LTCFLAGS
        linker:         $LD (gnu? $with_gnu_ld)
-       version:        $progname $scriptversion Debian-2.4.6-2.1
+       version:        $progname $scriptversion Debian-2.4.6-9
        automake:       `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
        autoconf:       `($AUTOCONF --version) 2>/dev/null |$SED 1q`
 
@@ -2471,8 +2375,8 @@ libtool_options_prep ()
 
     if $_G_rc_lt_options_prep; then
       # Pass back the list of options.
-      func_quote eval ${1+"$@"}
-      libtool_options_prep_result=$func_quote_result
+      func_quote_for_eval ${1+"$@"}
+      libtool_options_prep_result=$func_quote_for_eval_result
     fi
 
     $_G_rc_lt_options_prep
@@ -2578,8 +2482,8 @@ libtool_parse_options ()
 
     if $_G_rc_lt_parse_options; then
       # save modified positional parameters for caller
-      func_quote eval ${1+"$@"}
-      libtool_parse_options_result=$func_quote_result
+      func_quote_for_eval ${1+"$@"}
+      libtool_parse_options_result=$func_quote_for_eval_result
     fi
 
     $_G_rc_lt_parse_options
@@ -2639,8 +2543,8 @@ libtool_validate_options ()
     }
 
     # Pass back the unparsed argument list
-    func_quote eval ${1+"$@"}
-    libtool_validate_options_result=$func_quote_result
+    func_quote_for_eval ${1+"$@"}
+    libtool_validate_options_result=$func_quote_for_eval_result
 }
 func_add_hook func_validate_options libtool_validate_options
 
@@ -3606,8 +3510,8 @@ func_mode_compile ()
       esac
     done
 
-    func_quote_arg pretty "$libobj"
-    test "X$libobj" != "X$func_quote_arg_result" \
+    func_quote_for_eval "$libobj"
+    test "X$libobj" != "X$func_quote_for_eval_result" \
       && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"'   &()|`$[]' \
       && func_warning "libobj name '$libobj' may not contain shell special characters."
     func_dirname_and_basename "$obj" "/" ""
@@ -3680,8 +3584,8 @@ compiler."
 
     func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
     srcfile=$func_to_tool_file_result
-    func_quote_arg pretty "$srcfile"
-    qsrcfile=$func_quote_arg_result
+    func_quote_for_eval "$srcfile"
+    qsrcfile=$func_quote_for_eval_result
 
     # Only build a PIC object if we are building libtool libraries.
     if test yes = "$build_libtool_libs"; then
@@ -4284,8 +4188,8 @@ func_mode_install ()
        case $nonopt in *shtool*) :;; *) false;; esac
     then
       # Aesthetically quote it.
-      func_quote_arg pretty "$nonopt"
-      install_prog="$func_quote_arg_result "
+      func_quote_for_eval "$nonopt"
+      install_prog="$func_quote_for_eval_result "
       arg=$1
       shift
     else
@@ -4295,8 +4199,8 @@ func_mode_install ()
 
     # The real first argument should be the name of the installation program.
     # Aesthetically quote it.
-    func_quote_arg pretty "$arg"
-    func_append install_prog "$func_quote_arg_result"
+    func_quote_for_eval "$arg"
+    func_append install_prog "$func_quote_for_eval_result"
     install_shared_prog=$install_prog
     case " $install_prog " in
       *[\\\ /]cp\ *) install_cp=: ;;
@@ -4353,12 +4257,12 @@ func_mode_install ()
       esac
 
       # Aesthetically quote the argument.
-      func_quote_arg pretty "$arg"
-      func_append install_prog " $func_quote_arg_result"
+      func_quote_for_eval "$arg"
+      func_append install_prog " $func_quote_for_eval_result"
       if test -n "$arg2"; then
-       func_quote_arg pretty "$arg2"
+       func_quote_for_eval "$arg2"
       fi
-      func_append install_shared_prog " $func_quote_arg_result"
+      func_append install_shared_prog " $func_quote_for_eval_result"
     done
 
     test -z "$install_prog" && \
@@ -4369,8 +4273,8 @@ func_mode_install ()
 
     if test -n "$install_override_mode" && $no_mode; then
       if $install_cp; then :; else
-       func_quote_arg pretty "$install_override_mode"
-       func_append install_shared_prog " -m $func_quote_arg_result"
+       func_quote_for_eval "$install_override_mode"
+       func_append install_shared_prog " -m $func_quote_for_eval_result"
       fi
     fi
 
@@ -4666,8 +4570,8 @@ func_mode_install ()
                relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
 
                $opt_quiet || {
-                 func_quote_arg expand,pretty "$relink_command"
-                 eval "func_echo $func_quote_arg_result"
+                 func_quote_for_expand "$relink_command"
+                 eval "func_echo $func_quote_for_expand_result"
                }
                if eval "$relink_command"; then :
                  else
@@ -5446,8 +5350,7 @@ else
   if test \"\$libtool_execute_magic\" != \"$magic\"; then
     file=\"\$0\""
 
-    func_quote_arg pretty "$ECHO"
-    qECHO=$func_quote_arg_result
+    qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
     $ECHO "\
 
 # A function that is used when there is no print builtin or printf.
@@ -5457,7 +5360,7 @@ func_fallback_echo ()
 \$1
 _LTECHO_EOF'
 }
-    ECHO=$qECHO
+    ECHO=\"$qECHO\"
   fi
 
 # Very basic option parsing. These options are (a) specific to
@@ -6800,9 +6703,9 @@ func_mode_link ()
     while test "$#" -gt 0; do
       arg=$1
       shift
-      func_quote_arg pretty,unquoted "$arg"
-      qarg=$func_quote_arg_unquoted_result
-      func_append libtool_args " $func_quote_arg_result"
+      func_quote_for_eval "$arg"
+      qarg=$func_quote_for_eval_unquoted_result
+      func_append libtool_args " $func_quote_for_eval_result"
 
       # If the previous option needs an argument, assign it.
       if test -n "$prev"; then
@@ -7400,9 +7303,9 @@ func_mode_link ()
        save_ifs=$IFS; IFS=,
        for flag in $args; do
          IFS=$save_ifs
-          func_quote_arg pretty "$flag"
-         func_append arg " $func_quote_arg_result"
-         func_append compiler_flags " $func_quote_arg_result"
+          func_quote_for_eval "$flag"
+         func_append arg " $func_quote_for_eval_result"
+         func_append compiler_flags " $func_quote_for_eval_result"
        done
        IFS=$save_ifs
        func_stripname ' ' '' "$arg"
@@ -7416,10 +7319,10 @@ func_mode_link ()
        save_ifs=$IFS; IFS=,
        for flag in $args; do
          IFS=$save_ifs
-          func_quote_arg pretty "$flag"
-         func_append arg " $wl$func_quote_arg_result"
-         func_append compiler_flags " $wl$func_quote_arg_result"
-         func_append linker_flags " $func_quote_arg_result"
+          func_quote_for_eval "$flag"
+         func_append arg " $wl$func_quote_for_eval_result"
+         func_append compiler_flags " $wl$func_quote_for_eval_result"
+         func_append linker_flags " $func_quote_for_eval_result"
        done
        IFS=$save_ifs
        func_stripname ' ' '' "$arg"
@@ -7443,8 +7346,8 @@ func_mode_link ()
 
       # -msg_* for osf cc
       -msg_*)
-       func_quote_arg pretty "$arg"
-       arg=$func_quote_arg_result
+       func_quote_for_eval "$arg"
+       arg=$func_quote_for_eval_result
        ;;
 
       # Flags to be passed through unchanged, with rationale:
@@ -7464,12 +7367,13 @@ func_mode_link ()
       # -specs=*             GCC specs files
       # -stdlib=*            select c++ std lib with clang
       # -fsanitize=*         Clang/GCC memory and address sanitizer
+      # -fuse-ld=*           Linker select flags for GCC
       -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
       -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
       -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
-      -specs=*|-fsanitize=*)
-        func_quote_arg pretty "$arg"
-       arg=$func_quote_arg_result
+      -specs=*|-fsanitize=*|-fuse-ld=*)
+        func_quote_for_eval "$arg"
+       arg=$func_quote_for_eval_result
         func_append compile_command " $arg"
         func_append finalize_command " $arg"
         func_append compiler_flags " $arg"
@@ -7490,15 +7394,15 @@ func_mode_link ()
          continue
         else
          # Otherwise treat like 'Some other compiler flag' below
-         func_quote_arg pretty "$arg"
-         arg=$func_quote_arg_result
+         func_quote_for_eval "$arg"
+         arg=$func_quote_for_eval_result
         fi
        ;;
 
       # Some other compiler flag.
       -* | +*)
-        func_quote_arg pretty "$arg"
-       arg=$func_quote_arg_result
+        func_quote_for_eval "$arg"
+       arg=$func_quote_for_eval_result
        ;;
 
       *.$objext)
@@ -7618,8 +7522,8 @@ func_mode_link ()
       *)
        # Unknown arguments in both finalize_command and compile_command need
        # to be aesthetically quoted because they are evaled later.
-       func_quote_arg pretty "$arg"
-       arg=$func_quote_arg_result
+       func_quote_for_eval "$arg"
+       arg=$func_quote_for_eval_result
        ;;
       esac # arg
 
@@ -10131,8 +10035,8 @@ EOF
            for cmd in $concat_cmds; do
              IFS=$save_ifs
              $opt_quiet || {
-                 func_quote_arg expand,pretty "$cmd"
-                 eval "func_echo $func_quote_arg_result"
+                 func_quote_for_expand "$cmd"
+                 eval "func_echo $func_quote_for_expand_result"
              }
              $opt_dry_run || eval "$cmd" || {
                lt_exit=$?
@@ -10225,8 +10129,8 @@ EOF
          eval cmd=\"$cmd\"
          IFS=$save_ifs
          $opt_quiet || {
-           func_quote_arg expand,pretty "$cmd"
-           eval "func_echo $func_quote_arg_result"
+           func_quote_for_expand "$cmd"
+           eval "func_echo $func_quote_for_expand_result"
          }
          $opt_dry_run || eval "$cmd" || {
            lt_exit=$?
@@ -10700,12 +10604,12 @@ EOF
          elif eval var_value=\$$var; test -z "$var_value"; then
            relink_command="$var=; export $var; $relink_command"
          else
-           func_quote_arg pretty "$var_value"
-           relink_command="$var=$func_quote_arg_result; export $var; $relink_command"
+           func_quote_for_eval "$var_value"
+           relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
          fi
        done
-       func_quote_arg pretty,unquoted "(cd `pwd`; $relink_command)"
-       relink_command=$func_quote_arg_unquoted_result
+       relink_command="(cd `pwd`; $relink_command)"
+       relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
       fi
 
       # Only actually do things if not in dry run mode.
@@ -10945,14 +10849,13 @@ EOF
        elif eval var_value=\$$var; test -z "$var_value"; then
          relink_command="$var=; export $var; $relink_command"
        else
-         func_quote_arg pretty,unquoted "$var_value"
-         relink_command="$var=$func_quote_arg_unquoted_result; export $var; $relink_command"
+         func_quote_for_eval "$var_value"
+         relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
        fi
       done
       # Quote the link command for shipping.
       relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
-      func_quote_arg pretty,unquoted "$relink_command"
-      relink_command=$func_quote_arg_unquoted_result
+      relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
       if test yes = "$hardcode_automatic"; then
        relink_command=
       fi
diff --git a/m4/ac_python_devel.m4 b/m4/ac_python_devel.m4
deleted file mode 100644 (file)
index 4855156..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-dnl @synopsis AC_PYTHON_DEVEL([version])
-dnl
-dnl Note: Defines as a precious variable "PYTHON_VERSION". Don't
-dnl override it in your configure.ac.
-dnl
-dnl This macro checks for Python and tries to get the include path to
-dnl 'Python.h'. It provides the $(PYTHON_CPPFLAGS) and
-dnl $(PYTHON_LDFLAGS) output variables. It also exports
-dnl $(PYTHON_EXTRA_LIBS) and $(PYTHON_EXTRA_LDFLAGS) for embedding
-dnl Python in your code.
-dnl
-dnl You can search for some particular version of Python by passing a
-dnl parameter to this macro, for example ">= '2.3.1'", or "== '2.4'".
-dnl Please note that you *have* to pass also an operator along with the
-dnl version to match, and pay special attention to the single quotes
-dnl surrounding the version number. Don't use "PYTHON_VERSION" for
-dnl this: that environment variable is declared as precious and thus
-dnl reserved for the end-user.
-dnl
-dnl This macro should work for all versions of Python >= 2.1.0. As an
-dnl end user, you can disable the check for the python version by
-dnl setting the PYTHON_NOVERSIONCHECK environment variable to something
-dnl else than the empty string.
-dnl
-dnl If you need to use this macro for an older Python version, please
-dnl contact the authors. We're always open for feedback.
-dnl
-dnl @category InstalledPackages
-dnl @author Sebastian Huber <sebastian-huber@web.de>
-dnl @author Alan W. Irwin <irwin@beluga.phys.uvic.ca>
-dnl @author Rafael Laboissiere <laboissiere@psy.mpg.de>
-dnl @author Andrew Collier <colliera@nu.ac.za>
-dnl @author Matteo Settenvini <matteo@member.fsf.org>
-dnl @author Horst Knorr <hk_classes@knoda.org>
-dnl @version 2006-05-27
-dnl @license GPLWithACException
-
-AC_DEFUN([AC_PYTHON_DEVEL],[
-       #
-       # Allow the use of a (user set) custom python version
-       #
-       AC_ARG_VAR([PYTHON_VERSION],[The installed Python
-               version to use, for example '2.3'. This string
-               will be appended to the Python interpreter
-               canonical name.])
-
-       AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]])
-       if test -z "$PYTHON"; then
-          AC_MSG_ERROR([Cannot find python$PYTHON_VERSION in your system path])
-          PYTHON_VERSION=""
-       fi
-
-       #
-       # Check for a version of Python >= 2.1.0
-       #
-       AC_MSG_CHECKING([for a version of Python >= '2.1.0'])
-       ac_supports_python_ver=`$PYTHON -c "import sys, string; \
-               ver = string.split(sys.version)[[0]]; \
-               print ver >= '2.1.0'"`
-       if test "$ac_supports_python_ver" != "True"; then
-               if test -z "$PYTHON_NOVERSIONCHECK"; then
-                       AC_MSG_RESULT([no])
-                       AC_MSG_FAILURE([
-This version of the AC@&t@_PYTHON_DEVEL macro
-doesn't work properly with versions of Python before
-2.1.0. You may need to re-run configure, setting the
-variables PYTHON_CPPFLAGS, PYTHON_LDFLAGS, PYTHON_SITE_PKG,
-PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand.
-Moreover, to disable this check, set PYTHON_NOVERSIONCHECK
-to something else than an empty string.
-])
-               else
-                       AC_MSG_RESULT([skip at user request])
-               fi
-       else
-               AC_MSG_RESULT([yes])
-       fi
-
-       #
-       # if the macro parameter ``version'' is set, honour it
-       #
-       if test -n "$1"; then
-               AC_MSG_CHECKING([for a version of Python $1])
-               ac_supports_python_ver=`$PYTHON -c "import sys, string; \
-                       ver = string.split(sys.version)[[0]]; \
-                       print ver $1"`
-               if test "$ac_supports_python_ver" = "True"; then
-                  AC_MSG_RESULT([yes])
-               else
-                       AC_MSG_RESULT([no])
-                       AC_MSG_ERROR([this package requires Python $1.
-If you have it installed, but it isn't the default Python
-interpreter in your system path, please pass the PYTHON_VERSION
-variable to configure. See ``configure --help'' for reference.
-])
-                       PYTHON_VERSION=""
-               fi
-       fi
-
-       #
-       # Check if you have distutils, else fail
-       #
-       AC_MSG_CHECKING([for the distutils Python package])
-       ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`
-       if test -z "$ac_distutils_result"; then
-               AC_MSG_RESULT([yes])
-       else
-               AC_MSG_RESULT([no])
-               AC_MSG_ERROR([cannot import Python module "distutils".
-Please check your Python installation. The error was:
-$ac_distutils_result])
-               PYTHON_VERSION=""
-       fi
-
-       #
-       # Check for Python include path
-       #
-       AC_MSG_CHECKING([for Python include path])
-       if test -z "$PYTHON_CPPFLAGS"; then
-               python_path=`$PYTHON -c "import distutils.sysconfig; \
-                       print distutils.sysconfig.get_python_inc();"`
-               if test -n "${python_path}"; then
-                       python_path="-I$python_path"
-               fi
-               PYTHON_CPPFLAGS=$python_path
-       fi
-       AC_MSG_RESULT([$PYTHON_CPPFLAGS])
-       AC_SUBST([PYTHON_CPPFLAGS])
-
-       #
-       # Check for Python library path
-       #
-       AC_MSG_CHECKING([for Python library path])
-       if test -z "$PYTHON_LDFLAGS"; then
-               # (makes two attempts to ensure we've got a version number
-               # from the interpreter)
-               py_version=`$PYTHON -c "from distutils.sysconfig import *; \
-                       from string import join; \
-                       print join(get_config_vars('VERSION'))"`
-               if test "$py_version" == "[None]"; then
-                       if test -n "$PYTHON_VERSION"; then
-                               py_version=$PYTHON_VERSION
-                       else
-                               py_version=`$PYTHON -c "import sys; \
-                                       print sys.version[[:3]]"`
-                       fi
-               fi
-
-               PYTHON_LDFLAGS=`$PYTHON -c "from distutils.sysconfig import *; \
-                       from string import join; \
-                       print '-L' + get_python_lib(0,1), \
-                       '-lpython';"`$py_version
-       fi
-       AC_MSG_RESULT([$PYTHON_LDFLAGS])
-       AC_SUBST([PYTHON_LDFLAGS])
-
-       #
-       # Check for site packages
-       #
-       AC_MSG_CHECKING([for Python site-packages path])
-       if test -z "$PYTHON_SITE_PKG"; then
-               PYTHON_SITE_PKG=`$PYTHON -c "import distutils.sysconfig; \
-                       print distutils.sysconfig.get_python_lib(0,0);"`
-       fi
-       AC_MSG_RESULT([$PYTHON_SITE_PKG])
-       AC_SUBST([PYTHON_SITE_PKG])
-
-       #
-       # libraries which must be linked in when embedding
-       #
-       AC_MSG_CHECKING(python extra libraries)
-       if test -z "$PYTHON_EXTRA_LIBS"; then
-          PYTHON_EXTRA_LIBS=`$PYTHON -c "import distutils.sysconfig; \
-                conf = distutils.sysconfig.get_config_var; \
-                print conf('LOCALMODLIBS'), conf('LIBS')"`
-       fi
-       AC_MSG_RESULT([$PYTHON_EXTRA_LIBS])
-       AC_SUBST(PYTHON_EXTRA_LIBS)
-
-       #
-       # linking flags needed when embedding
-       #
-       AC_MSG_CHECKING(python extra linking flags)
-       if test -z "$PYTHON_EXTRA_LDFLAGS"; then
-               PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "import distutils.sysconfig; \
-                       conf = distutils.sysconfig.get_config_var; \
-                       print conf('LINKFORSHARED')"`
-       fi
-       AC_MSG_RESULT([$PYTHON_EXTRA_LDFLAGS])
-       AC_SUBST(PYTHON_EXTRA_LDFLAGS)
-
-       #
-       # final check to see if everything compiles alright
-       #
-       AC_MSG_CHECKING([consistency of all components of python development environment])
-       AC_LANG_PUSH([C])
-       # save current global flags
-       LIBS="$ac_save_LIBS $PYTHON_LDFLAGS"
-       CPPFLAGS="$ac_save_CPPFLAGS $PYTHON_CPPFLAGS"
-       AC_TRY_LINK([
-               #include <Python.h>
-       ],[
-               Py_Initialize();
-       ],[pythonexists=yes],[pythonexists=no])
-
-       AC_MSG_RESULT([$pythonexists])
-
-        if test ! "$pythonexists" = "yes"; then
-          AC_MSG_ERROR([
-  Could not link test program to Python. Maybe the main Python library has been
-  installed in some non-standard library path. If so, pass it to configure,
-  via the LDFLAGS environment variable.
-  Example: ./configure LDFLAGS="-L/usr/non-standard-path/python/lib"
-  ============================================================================
-   ERROR!
-   You probably have to install the development version of the Python package
-   for your distribution.  The exact name of this package varies among them.
-  ============================================================================
-          ])
-         PYTHON_VERSION=""
-       fi
-       AC_LANG_POP
-       # turn back to default flags
-       CPPFLAGS="$ac_save_CPPFLAGS"
-       LIBS="$ac_save_LIBS"
-
-       #
-       # all done!
-       #
-])
diff --git a/m4/ax_python_devel.m4 b/m4/ax_python_devel.m4
new file mode 100644 (file)
index 0000000..44dbd83
--- /dev/null
@@ -0,0 +1,327 @@
+# ===========================================================================
+#     https://www.gnu.org/software/autoconf-archive/ax_python_devel.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_PYTHON_DEVEL([version])
+#
+# DESCRIPTION
+#
+#   Note: Defines as a precious variable "PYTHON_VERSION". Don't override it
+#   in your configure.ac.
+#
+#   This macro checks for Python and tries to get the include path to
+#   'Python.h'. It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LIBS) output
+#   variables. It also exports $(PYTHON_EXTRA_LIBS) and
+#   $(PYTHON_EXTRA_LDFLAGS) for embedding Python in your code.
+#
+#   You can search for some particular version of Python by passing a
+#   parameter to this macro, for example ">= '2.3.1'", or "== '2.4'". Please
+#   note that you *have* to pass also an operator along with the version to
+#   match, and pay special attention to the single quotes surrounding the
+#   version number. Don't use "PYTHON_VERSION" for this: that environment
+#   variable is declared as precious and thus reserved for the end-user.
+#
+#   This macro should work for all versions of Python >= 2.1.0. As an end
+#   user, you can disable the check for the python version by setting the
+#   PYTHON_NOVERSIONCHECK environment variable to something else than the
+#   empty string.
+#
+#   If you need to use this macro for an older Python version, please
+#   contact the authors. We're always open for feedback.
+#
+# LICENSE
+#
+#   Copyright (c) 2009 Sebastian Huber <sebastian-huber@web.de>
+#   Copyright (c) 2009 Alan W. Irwin
+#   Copyright (c) 2009 Rafael Laboissiere <rafael@laboissiere.net>
+#   Copyright (c) 2009 Andrew Collier
+#   Copyright (c) 2009 Matteo Settenvini <matteo@member.fsf.org>
+#   Copyright (c) 2009 Horst Knorr <hk_classes@knoda.org>
+#   Copyright (c) 2013 Daniel Mullner <muellner@math.stanford.edu>
+#
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <https://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 21
+
+AU_ALIAS([AC_PYTHON_DEVEL], [AX_PYTHON_DEVEL])
+AC_DEFUN([AX_PYTHON_DEVEL],[
+       #
+       # Allow the use of a (user set) custom python version
+       #
+       AC_ARG_VAR([PYTHON_VERSION],[The installed Python
+               version to use, for example '2.3'. This string
+               will be appended to the Python interpreter
+               canonical name.])
+
+       AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]])
+       if test -z "$PYTHON"; then
+          AC_MSG_ERROR([Cannot find python$PYTHON_VERSION in your system path])
+          PYTHON_VERSION=""
+       fi
+
+       #
+       # Check for a version of Python >= 2.1.0
+       #
+       AC_MSG_CHECKING([for a version of Python >= '2.1.0'])
+       ac_supports_python_ver=`$PYTHON -c "import sys; \
+               ver = sys.version.split ()[[0]]; \
+               print (ver >= '2.1.0')"`
+       if test "$ac_supports_python_ver" != "True"; then
+               if test -z "$PYTHON_NOVERSIONCHECK"; then
+                       AC_MSG_RESULT([no])
+                       AC_MSG_FAILURE([
+This version of the AC@&t@_PYTHON_DEVEL macro
+doesn't work properly with versions of Python before
+2.1.0. You may need to re-run configure, setting the
+variables PYTHON_CPPFLAGS, PYTHON_LIBS, PYTHON_SITE_PKG,
+PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand.
+Moreover, to disable this check, set PYTHON_NOVERSIONCHECK
+to something else than an empty string.
+])
+               else
+                       AC_MSG_RESULT([skip at user request])
+               fi
+       else
+               AC_MSG_RESULT([yes])
+       fi
+
+       #
+       # if the macro parameter ``version'' is set, honour it
+       #
+       if test -n "$1"; then
+               AC_MSG_CHECKING([for a version of Python $1])
+               ac_supports_python_ver=`$PYTHON -c "import sys; \
+                       ver = sys.version.split ()[[0]]; \
+                       print (ver $1)"`
+               if test "$ac_supports_python_ver" = "True"; then
+                  AC_MSG_RESULT([yes])
+               else
+                       AC_MSG_RESULT([no])
+                       AC_MSG_ERROR([this package requires Python $1.
+If you have it installed, but it isn't the default Python
+interpreter in your system path, please pass the PYTHON_VERSION
+variable to configure. See ``configure --help'' for reference.
+])
+                       PYTHON_VERSION=""
+               fi
+       fi
+
+       #
+       # Check if you have distutils, else fail
+       #
+       AC_MSG_CHECKING([for the distutils Python package])
+       ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`
+       if test $? -eq 0; then
+               AC_MSG_RESULT([yes])
+       else
+               AC_MSG_RESULT([no])
+               AC_MSG_ERROR([cannot import Python module "distutils".
+Please check your Python installation. The error was:
+$ac_distutils_result])
+               PYTHON_VERSION=""
+       fi
+
+       #
+       # Check for Python include path
+       #
+       AC_MSG_CHECKING([for Python include path])
+       if test -z "$PYTHON_CPPFLAGS"; then
+               python_path=`$PYTHON -c "import distutils.sysconfig; \
+                       print (distutils.sysconfig.get_python_inc ());"`
+               plat_python_path=`$PYTHON -c "import distutils.sysconfig; \
+                       print (distutils.sysconfig.get_python_inc (plat_specific=1));"`
+               if test -n "${python_path}"; then
+                       if test "${plat_python_path}" != "${python_path}"; then
+                               python_path="-I$python_path -I$plat_python_path"
+                       else
+                               python_path="-I$python_path"
+                       fi
+               fi
+               PYTHON_CPPFLAGS=$python_path
+       fi
+       AC_MSG_RESULT([$PYTHON_CPPFLAGS])
+       AC_SUBST([PYTHON_CPPFLAGS])
+
+       #
+       # Check for Python library path
+       #
+       AC_MSG_CHECKING([for Python library path])
+       if test -z "$PYTHON_LIBS"; then
+               # (makes two attempts to ensure we've got a version number
+               # from the interpreter)
+               ac_python_version=`cat<<EOD | $PYTHON -
+
+# join all versioning strings, on some systems
+# major/minor numbers could be in different list elements
+from distutils.sysconfig import *
+e = get_config_var('VERSION')
+if e is not None:
+       print(e)
+EOD`
+
+               if test -z "$ac_python_version"; then
+                       if test -n "$PYTHON_VERSION"; then
+                               ac_python_version=$PYTHON_VERSION
+                       else
+                               ac_python_version=`$PYTHON -c "import sys; \
+                                       print (sys.version[[:3]])"`
+                       fi
+               fi
+
+               # Make the versioning information available to the compiler
+               AC_DEFINE_UNQUOTED([HAVE_PYTHON], ["$ac_python_version"],
+                                   [If available, contains the Python version number currently in use.])
+
+               # First, the library directory:
+               ac_python_libdir=`cat<<EOD | $PYTHON -
+
+# There should be only one
+import distutils.sysconfig
+e = distutils.sysconfig.get_config_var('LIBDIR')
+if e is not None:
+       print (e)
+EOD`
+
+               # Now, for the library:
+               ac_python_library=`cat<<EOD | $PYTHON -
+
+import distutils.sysconfig
+c = distutils.sysconfig.get_config_vars()
+if 'LDVERSION' in c:
+       print ('python'+c[['LDVERSION']])
+else:
+       print ('python'+c[['VERSION']])
+EOD`
+
+               # This small piece shamelessly adapted from PostgreSQL python macro;
+               # credits goes to momjian, I think. I'd like to put the right name
+               # in the credits, if someone can point me in the right direction... ?
+               #
+               if test -n "$ac_python_libdir" -a -n "$ac_python_library"
+               then
+                       # use the official shared library
+                       ac_python_library=`echo "$ac_python_library" | sed "s/^lib//"`
+                       PYTHON_LIBS="-L$ac_python_libdir -l$ac_python_library"
+               else
+                       # old way: use libpython from python_configdir
+                       ac_python_libdir=`$PYTHON -c \
+                         "from distutils.sysconfig import get_python_lib as f; \
+                         import os; \
+                         print (os.path.join(f(plat_specific=1, standard_lib=1), 'config'));"`
+                       PYTHON_LIBS="-L$ac_python_libdir -lpython$ac_python_version"
+               fi
+
+               if test -z "PYTHON_LIBS"; then
+                       AC_MSG_ERROR([
+  Cannot determine location of your Python DSO. Please check it was installed with
+  dynamic libraries enabled, or try setting PYTHON_LIBS by hand.
+                       ])
+               fi
+       fi
+       AC_MSG_RESULT([$PYTHON_LIBS])
+       AC_SUBST([PYTHON_LIBS])
+
+       #
+       # Check for site packages
+       #
+       AC_MSG_CHECKING([for Python site-packages path])
+       if test -z "$PYTHON_SITE_PKG"; then
+               PYTHON_SITE_PKG=`$PYTHON -c "import distutils.sysconfig; \
+                       print (distutils.sysconfig.get_python_lib(0,0));"`
+       fi
+       AC_MSG_RESULT([$PYTHON_SITE_PKG])
+       AC_SUBST([PYTHON_SITE_PKG])
+
+       #
+       # libraries which must be linked in when embedding
+       #
+       AC_MSG_CHECKING(python extra libraries)
+       if test -z "$PYTHON_EXTRA_LIBS"; then
+          PYTHON_EXTRA_LIBS=`$PYTHON -c "import distutils.sysconfig; \
+                conf = distutils.sysconfig.get_config_var; \
+                print (conf('LIBS') + ' ' + conf('SYSLIBS'))"`
+       fi
+       AC_MSG_RESULT([$PYTHON_EXTRA_LIBS])
+       AC_SUBST(PYTHON_EXTRA_LIBS)
+
+       #
+       # linking flags needed when embedding
+       #
+       AC_MSG_CHECKING(python extra linking flags)
+       if test -z "$PYTHON_EXTRA_LDFLAGS"; then
+               PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "import distutils.sysconfig; \
+                       conf = distutils.sysconfig.get_config_var; \
+                       print (conf('LINKFORSHARED'))"`
+       fi
+       AC_MSG_RESULT([$PYTHON_EXTRA_LDFLAGS])
+       AC_SUBST(PYTHON_EXTRA_LDFLAGS)
+
+       #
+       # final check to see if everything compiles alright
+       #
+       AC_MSG_CHECKING([consistency of all components of python development environment])
+       # save current global flags
+       ac_save_LIBS="$LIBS"
+       ac_save_LDFLAGS="$LDFLAGS"
+       ac_save_CPPFLAGS="$CPPFLAGS"
+       LIBS="$ac_save_LIBS $PYTHON_LIBS $PYTHON_EXTRA_LIBS $PYTHON_EXTRA_LIBS"
+       LDFLAGS="$ac_save_LDFLAGS $PYTHON_EXTRA_LDFLAGS"
+       CPPFLAGS="$ac_save_CPPFLAGS $PYTHON_CPPFLAGS"
+       AC_LANG_PUSH([C])
+       AC_LINK_IFELSE([
+               AC_LANG_PROGRAM([[#include <Python.h>]],
+                               [[Py_Initialize();]])
+               ],[pythonexists=yes],[pythonexists=no])
+       AC_LANG_POP([C])
+       # turn back to default flags
+       CPPFLAGS="$ac_save_CPPFLAGS"
+       LIBS="$ac_save_LIBS"
+       LDFLAGS="$ac_save_LDFLAGS"
+
+       AC_MSG_RESULT([$pythonexists])
+
+        if test ! "x$pythonexists" = "xyes"; then
+          AC_MSG_FAILURE([
+  Could not link test program to Python. Maybe the main Python library has been
+  installed in some non-standard library path. If so, pass it to configure,
+  via the LIBS environment variable.
+  Example: ./configure LIBS="-L/usr/non-standard-path/python/lib"
+  ============================================================================
+   ERROR!
+   You probably have to install the development version of the Python package
+   for your distribution.  The exact name of this package varies among them.
+  ============================================================================
+          ])
+         PYTHON_VERSION=""
+       fi
+
+       #
+       # all done!
+       #
+])
index ee80844..c81e669 100644 (file)
@@ -4063,7 +4063,8 @@ _LT_EOF
   if AC_TRY_EVAL(ac_compile); then
     # Now try to grab the symbols.
     nlist=conftest.nm
-    if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
+    $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD
+    if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then
       # Try sorting and uniquifying the output.
       if sort "$nlist" | uniq > "$nlist"T; then
        mv -f "$nlist"T "$nlist"
@@ -6438,7 +6439,7 @@ if test yes != "$_lt_caught_CXX_error"; then
       # Commands to make compiler produce verbose output that lists
       # what "hidden" libraries, object files and flags are used when
       # linking a shared library.
-      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
 
     else
       GXX=no
@@ -6813,7 +6814,7 @@ if test yes != "$_lt_caught_CXX_error"; then
             # explicitly linking system object files so we need to strip them
             # from the output so that they don't get included in the library
             # dependencies.
-            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
             ;;
           *)
             if test yes = "$GXX"; then
@@ -6878,7 +6879,7 @@ if test yes != "$_lt_caught_CXX_error"; then
            # explicitly linking system object files so we need to strip them
            # from the output so that they don't get included in the library
            # dependencies.
-           output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+           output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
            ;;
           *)
            if test yes = "$GXX"; then
@@ -7217,7 +7218,7 @@ if test yes != "$_lt_caught_CXX_error"; then
              # Commands to make compiler produce verbose output that lists
              # what "hidden" libraries, object files and flags are used when
              # linking a shared library.
-             output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+             output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
 
            else
              # FIXME: insert proper C++ library support
@@ -7301,7 +7302,7 @@ if test yes != "$_lt_caught_CXX_error"; then
                # Commands to make compiler produce verbose output that lists
                # what "hidden" libraries, object files and flags are used when
                # linking a shared library.
-               output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+               output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
              else
                # g++ 2.7 appears to require '-G' NOT '-shared' on this
                # platform.
@@ -7312,7 +7313,7 @@ if test yes != "$_lt_caught_CXX_error"; then
                # Commands to make compiler produce verbose output that lists
                # what "hidden" libraries, object files and flags are used when
                # linking a shared library.
-               output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+               output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
              fi
 
              _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
diff --git a/missing b/missing
index f62bbae..625aeb1 100755 (executable)
--- a/missing
+++ b/missing
@@ -1,9 +1,9 @@
 #! /bin/sh
 # Common wrapper for a few potentially missing GNU programs.
 
-scriptversion=2013-10-28.13; # UTC
+scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
 # Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
 
 # This program is free software; you can redistribute it and/or modify
@@ -17,7 +17,7 @@ scriptversion=2013-10-28.13; # UTC
 # GNU General Public License for more details.
 
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -101,9 +101,9 @@ else
   exit $st
 fi
 
-perl_URL=http://www.perl.org/
-flex_URL=http://flex.sourceforge.net/
-gnu_software_URL=http://www.gnu.org/software
+perl_URL=https://www.perl.org/
+flex_URL=https://github.com/westes/flex
+gnu_software_URL=https://www.gnu.org/software
 
 program_details ()
 {
@@ -207,9 +207,9 @@ give_advice "$1" | sed -e '1s/^/WARNING: /' \
 exit $st
 
 # Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-time-zone: "UTC0"
 # time-stamp-end: "; # UTC"
 # End:
index 21d9d41..7dbf1c3 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -89,7 +89,7 @@ build_triplet = @build@
 host_triplet = @host@
 subdir = src
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_python_devel.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
        $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
@@ -135,7 +135,7 @@ am__recursive_targets = \
   $(RECURSIVE_CLEAN_TARGETS) \
   $(am__extra_recursive_targets)
 AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
-       distdir
+       distdir distdir-am
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
 # Read a list of newline-separated strings from the standard input,
 # and print each of them once, without duplicates.  Input order is
@@ -250,7 +250,7 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
@@ -341,8 +341,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
          *config.status*) \
            cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
          *) \
-           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
        esac;
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@@ -459,7 +459,10 @@ cscopelist-am: $(am__tagged_files)
 distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
-distdir: $(DISTFILES)
+distdir: $(BUILT_SOURCES)
+       $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
        @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        list='$(DISTFILES)'; \
index 237b97d..991352c 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -110,7 +110,7 @@ host_triplet = @host@
 @HAVE_BIN_TRUE@        fstunion$(EXEEXT)
 subdir = src/bin
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_python_devel.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
        $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
@@ -412,7 +412,48 @@ am__v_at_0 = @
 am__v_at_1 = 
 DEFAULT_INCLUDES = 
 depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/fstarcsort-main.Po \
+       ./$(DEPDIR)/fstarcsort.Po ./$(DEPDIR)/fstclosure-main.Po \
+       ./$(DEPDIR)/fstclosure.Po ./$(DEPDIR)/fstcompile-main.Po \
+       ./$(DEPDIR)/fstcompile.Po ./$(DEPDIR)/fstcompose-main.Po \
+       ./$(DEPDIR)/fstcompose.Po ./$(DEPDIR)/fstconcat-main.Po \
+       ./$(DEPDIR)/fstconcat.Po ./$(DEPDIR)/fstconnect-main.Po \
+       ./$(DEPDIR)/fstconnect.Po ./$(DEPDIR)/fstconvert-main.Po \
+       ./$(DEPDIR)/fstconvert.Po ./$(DEPDIR)/fstdeterminize-main.Po \
+       ./$(DEPDIR)/fstdeterminize.Po \
+       ./$(DEPDIR)/fstdifference-main.Po ./$(DEPDIR)/fstdifference.Po \
+       ./$(DEPDIR)/fstdisambiguate-main.Po \
+       ./$(DEPDIR)/fstdisambiguate.Po ./$(DEPDIR)/fstdraw-main.Po \
+       ./$(DEPDIR)/fstdraw.Po ./$(DEPDIR)/fstencode-main.Po \
+       ./$(DEPDIR)/fstencode.Po ./$(DEPDIR)/fstepsnormalize-main.Po \
+       ./$(DEPDIR)/fstepsnormalize.Po ./$(DEPDIR)/fstequal-main.Po \
+       ./$(DEPDIR)/fstequal.Po ./$(DEPDIR)/fstequivalent-main.Po \
+       ./$(DEPDIR)/fstequivalent.Po ./$(DEPDIR)/fstinfo-main.Po \
+       ./$(DEPDIR)/fstinfo.Po ./$(DEPDIR)/fstintersect-main.Po \
+       ./$(DEPDIR)/fstintersect.Po ./$(DEPDIR)/fstinvert-main.Po \
+       ./$(DEPDIR)/fstinvert.Po ./$(DEPDIR)/fstisomorphic-main.Po \
+       ./$(DEPDIR)/fstisomorphic.Po ./$(DEPDIR)/fstmap-main.Po \
+       ./$(DEPDIR)/fstmap.Po ./$(DEPDIR)/fstminimize-main.Po \
+       ./$(DEPDIR)/fstminimize.Po ./$(DEPDIR)/fstprint-main.Po \
+       ./$(DEPDIR)/fstprint.Po ./$(DEPDIR)/fstproject-main.Po \
+       ./$(DEPDIR)/fstproject.Po ./$(DEPDIR)/fstprune-main.Po \
+       ./$(DEPDIR)/fstprune.Po ./$(DEPDIR)/fstpush-main.Po \
+       ./$(DEPDIR)/fstpush.Po ./$(DEPDIR)/fstrandgen-main.Po \
+       ./$(DEPDIR)/fstrandgen.Po ./$(DEPDIR)/fstrelabel-main.Po \
+       ./$(DEPDIR)/fstrelabel.Po ./$(DEPDIR)/fstreplace-main.Po \
+       ./$(DEPDIR)/fstreplace.Po ./$(DEPDIR)/fstreverse-main.Po \
+       ./$(DEPDIR)/fstreverse.Po ./$(DEPDIR)/fstreweight-main.Po \
+       ./$(DEPDIR)/fstreweight.Po ./$(DEPDIR)/fstrmepsilon-main.Po \
+       ./$(DEPDIR)/fstrmepsilon.Po \
+       ./$(DEPDIR)/fstshortestdistance-main.Po \
+       ./$(DEPDIR)/fstshortestdistance.Po \
+       ./$(DEPDIR)/fstshortestpath-main.Po \
+       ./$(DEPDIR)/fstshortestpath.Po ./$(DEPDIR)/fstsymbols-main.Po \
+       ./$(DEPDIR)/fstsymbols.Po ./$(DEPDIR)/fstsynchronize-main.Po \
+       ./$(DEPDIR)/fstsynchronize.Po ./$(DEPDIR)/fsttopsort-main.Po \
+       ./$(DEPDIR)/fsttopsort.Po ./$(DEPDIR)/fstunion-main.Po \
+       ./$(DEPDIR)/fstunion.Po
 am__mv = mv -f
 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
        $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
@@ -567,7 +608,7 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
@@ -697,8 +738,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
          *config.status*) \
            cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
          *) \
-           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
        esac;
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@@ -913,80 +954,86 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstarcsort-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstarcsort.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstclosure-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstclosure.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstcompile-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstcompile.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstcompose-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstcompose.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstconcat-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstconcat.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstconnect-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstconnect.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstconvert-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstconvert.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstdeterminize-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstdeterminize.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstdifference-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstdifference.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstdisambiguate-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstdisambiguate.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstdraw-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstdraw.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstencode-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstencode.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstepsnormalize-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstepsnormalize.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstequal-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstequal.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstequivalent-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstequivalent.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstinfo-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstinfo.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstintersect-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstintersect.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstinvert-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstinvert.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstisomorphic-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstisomorphic.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstmap-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstmap.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstminimize-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstminimize.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstprint-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstprint.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstproject-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstproject.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstprune-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstprune.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstpush-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstpush.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstrandgen-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstrandgen.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstrelabel-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstrelabel.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstreplace-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstreplace.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstreverse-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstreverse.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstreweight-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstreweight.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstrmepsilon-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstrmepsilon.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstshortestdistance-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstshortestdistance.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstshortestpath-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstshortestpath.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstsymbols-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstsymbols.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstsynchronize-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstsynchronize.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsttopsort-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsttopsort.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstunion-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstunion.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstarcsort-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstarcsort.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstclosure-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstclosure.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstcompile-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstcompile.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstcompose-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstcompose.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstconcat-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstconcat.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstconnect-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstconnect.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstconvert-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstconvert.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstdeterminize-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstdeterminize.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstdifference-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstdifference.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstdisambiguate-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstdisambiguate.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstdraw-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstdraw.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstencode-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstencode.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstepsnormalize-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstepsnormalize.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstequal-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstequal.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstequivalent-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstequivalent.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstinfo-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstinfo.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstintersect-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstintersect.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstinvert-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstinvert.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstisomorphic-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstisomorphic.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstmap-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstmap.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstminimize-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstminimize.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstprint-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstprint.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstproject-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstproject.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstprune-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstprune.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstpush-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstpush.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstrandgen-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstrandgen.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstrelabel-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstrelabel.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstreplace-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstreplace.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstreverse-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstreverse.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstreweight-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstreweight.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstrmepsilon-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstrmepsilon.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstshortestdistance-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstshortestdistance.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstshortestpath-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstshortestpath.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstsymbols-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstsymbols.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstsynchronize-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstsynchronize.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsttopsort-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsttopsort.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstunion-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstunion.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+       @$(MKDIR_P) $(@D)
+       @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
 
 .cc.o:
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -1070,7 +1117,10 @@ cscopelist-am: $(am__tagged_files)
 distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
-distdir: $(DISTFILES)
+distdir: $(BUILT_SOURCES)
+       $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
        @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        list='$(DISTFILES)'; \
@@ -1142,7 +1192,80 @@ clean: clean-am
 clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
 
 distclean: distclean-am
-       -rm -rf ./$(DEPDIR)
+               -rm -f ./$(DEPDIR)/fstarcsort-main.Po
+       -rm -f ./$(DEPDIR)/fstarcsort.Po
+       -rm -f ./$(DEPDIR)/fstclosure-main.Po
+       -rm -f ./$(DEPDIR)/fstclosure.Po
+       -rm -f ./$(DEPDIR)/fstcompile-main.Po
+       -rm -f ./$(DEPDIR)/fstcompile.Po
+       -rm -f ./$(DEPDIR)/fstcompose-main.Po
+       -rm -f ./$(DEPDIR)/fstcompose.Po
+       -rm -f ./$(DEPDIR)/fstconcat-main.Po
+       -rm -f ./$(DEPDIR)/fstconcat.Po
+       -rm -f ./$(DEPDIR)/fstconnect-main.Po
+       -rm -f ./$(DEPDIR)/fstconnect.Po
+       -rm -f ./$(DEPDIR)/fstconvert-main.Po
+       -rm -f ./$(DEPDIR)/fstconvert.Po
+       -rm -f ./$(DEPDIR)/fstdeterminize-main.Po
+       -rm -f ./$(DEPDIR)/fstdeterminize.Po
+       -rm -f ./$(DEPDIR)/fstdifference-main.Po
+       -rm -f ./$(DEPDIR)/fstdifference.Po
+       -rm -f ./$(DEPDIR)/fstdisambiguate-main.Po
+       -rm -f ./$(DEPDIR)/fstdisambiguate.Po
+       -rm -f ./$(DEPDIR)/fstdraw-main.Po
+       -rm -f ./$(DEPDIR)/fstdraw.Po
+       -rm -f ./$(DEPDIR)/fstencode-main.Po
+       -rm -f ./$(DEPDIR)/fstencode.Po
+       -rm -f ./$(DEPDIR)/fstepsnormalize-main.Po
+       -rm -f ./$(DEPDIR)/fstepsnormalize.Po
+       -rm -f ./$(DEPDIR)/fstequal-main.Po
+       -rm -f ./$(DEPDIR)/fstequal.Po
+       -rm -f ./$(DEPDIR)/fstequivalent-main.Po
+       -rm -f ./$(DEPDIR)/fstequivalent.Po
+       -rm -f ./$(DEPDIR)/fstinfo-main.Po
+       -rm -f ./$(DEPDIR)/fstinfo.Po
+       -rm -f ./$(DEPDIR)/fstintersect-main.Po
+       -rm -f ./$(DEPDIR)/fstintersect.Po
+       -rm -f ./$(DEPDIR)/fstinvert-main.Po
+       -rm -f ./$(DEPDIR)/fstinvert.Po
+       -rm -f ./$(DEPDIR)/fstisomorphic-main.Po
+       -rm -f ./$(DEPDIR)/fstisomorphic.Po
+       -rm -f ./$(DEPDIR)/fstmap-main.Po
+       -rm -f ./$(DEPDIR)/fstmap.Po
+       -rm -f ./$(DEPDIR)/fstminimize-main.Po
+       -rm -f ./$(DEPDIR)/fstminimize.Po
+       -rm -f ./$(DEPDIR)/fstprint-main.Po
+       -rm -f ./$(DEPDIR)/fstprint.Po
+       -rm -f ./$(DEPDIR)/fstproject-main.Po
+       -rm -f ./$(DEPDIR)/fstproject.Po
+       -rm -f ./$(DEPDIR)/fstprune-main.Po
+       -rm -f ./$(DEPDIR)/fstprune.Po
+       -rm -f ./$(DEPDIR)/fstpush-main.Po
+       -rm -f ./$(DEPDIR)/fstpush.Po
+       -rm -f ./$(DEPDIR)/fstrandgen-main.Po
+       -rm -f ./$(DEPDIR)/fstrandgen.Po
+       -rm -f ./$(DEPDIR)/fstrelabel-main.Po
+       -rm -f ./$(DEPDIR)/fstrelabel.Po
+       -rm -f ./$(DEPDIR)/fstreplace-main.Po
+       -rm -f ./$(DEPDIR)/fstreplace.Po
+       -rm -f ./$(DEPDIR)/fstreverse-main.Po
+       -rm -f ./$(DEPDIR)/fstreverse.Po
+       -rm -f ./$(DEPDIR)/fstreweight-main.Po
+       -rm -f ./$(DEPDIR)/fstreweight.Po
+       -rm -f ./$(DEPDIR)/fstrmepsilon-main.Po
+       -rm -f ./$(DEPDIR)/fstrmepsilon.Po
+       -rm -f ./$(DEPDIR)/fstshortestdistance-main.Po
+       -rm -f ./$(DEPDIR)/fstshortestdistance.Po
+       -rm -f ./$(DEPDIR)/fstshortestpath-main.Po
+       -rm -f ./$(DEPDIR)/fstshortestpath.Po
+       -rm -f ./$(DEPDIR)/fstsymbols-main.Po
+       -rm -f ./$(DEPDIR)/fstsymbols.Po
+       -rm -f ./$(DEPDIR)/fstsynchronize-main.Po
+       -rm -f ./$(DEPDIR)/fstsynchronize.Po
+       -rm -f ./$(DEPDIR)/fsttopsort-main.Po
+       -rm -f ./$(DEPDIR)/fsttopsort.Po
+       -rm -f ./$(DEPDIR)/fstunion-main.Po
+       -rm -f ./$(DEPDIR)/fstunion.Po
        -rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
        distclean-tags
@@ -1188,7 +1311,80 @@ install-ps-am:
 installcheck-am:
 
 maintainer-clean: maintainer-clean-am
-       -rm -rf ./$(DEPDIR)
+               -rm -f ./$(DEPDIR)/fstarcsort-main.Po
+       -rm -f ./$(DEPDIR)/fstarcsort.Po
+       -rm -f ./$(DEPDIR)/fstclosure-main.Po
+       -rm -f ./$(DEPDIR)/fstclosure.Po
+       -rm -f ./$(DEPDIR)/fstcompile-main.Po
+       -rm -f ./$(DEPDIR)/fstcompile.Po
+       -rm -f ./$(DEPDIR)/fstcompose-main.Po
+       -rm -f ./$(DEPDIR)/fstcompose.Po
+       -rm -f ./$(DEPDIR)/fstconcat-main.Po
+       -rm -f ./$(DEPDIR)/fstconcat.Po
+       -rm -f ./$(DEPDIR)/fstconnect-main.Po
+       -rm -f ./$(DEPDIR)/fstconnect.Po
+       -rm -f ./$(DEPDIR)/fstconvert-main.Po
+       -rm -f ./$(DEPDIR)/fstconvert.Po
+       -rm -f ./$(DEPDIR)/fstdeterminize-main.Po
+       -rm -f ./$(DEPDIR)/fstdeterminize.Po
+       -rm -f ./$(DEPDIR)/fstdifference-main.Po
+       -rm -f ./$(DEPDIR)/fstdifference.Po
+       -rm -f ./$(DEPDIR)/fstdisambiguate-main.Po
+       -rm -f ./$(DEPDIR)/fstdisambiguate.Po
+       -rm -f ./$(DEPDIR)/fstdraw-main.Po
+       -rm -f ./$(DEPDIR)/fstdraw.Po
+       -rm -f ./$(DEPDIR)/fstencode-main.Po
+       -rm -f ./$(DEPDIR)/fstencode.Po
+       -rm -f ./$(DEPDIR)/fstepsnormalize-main.Po
+       -rm -f ./$(DEPDIR)/fstepsnormalize.Po
+       -rm -f ./$(DEPDIR)/fstequal-main.Po
+       -rm -f ./$(DEPDIR)/fstequal.Po
+       -rm -f ./$(DEPDIR)/fstequivalent-main.Po
+       -rm -f ./$(DEPDIR)/fstequivalent.Po
+       -rm -f ./$(DEPDIR)/fstinfo-main.Po
+       -rm -f ./$(DEPDIR)/fstinfo.Po
+       -rm -f ./$(DEPDIR)/fstintersect-main.Po
+       -rm -f ./$(DEPDIR)/fstintersect.Po
+       -rm -f ./$(DEPDIR)/fstinvert-main.Po
+       -rm -f ./$(DEPDIR)/fstinvert.Po
+       -rm -f ./$(DEPDIR)/fstisomorphic-main.Po
+       -rm -f ./$(DEPDIR)/fstisomorphic.Po
+       -rm -f ./$(DEPDIR)/fstmap-main.Po
+       -rm -f ./$(DEPDIR)/fstmap.Po
+       -rm -f ./$(DEPDIR)/fstminimize-main.Po
+       -rm -f ./$(DEPDIR)/fstminimize.Po
+       -rm -f ./$(DEPDIR)/fstprint-main.Po
+       -rm -f ./$(DEPDIR)/fstprint.Po
+       -rm -f ./$(DEPDIR)/fstproject-main.Po
+       -rm -f ./$(DEPDIR)/fstproject.Po
+       -rm -f ./$(DEPDIR)/fstprune-main.Po
+       -rm -f ./$(DEPDIR)/fstprune.Po
+       -rm -f ./$(DEPDIR)/fstpush-main.Po
+       -rm -f ./$(DEPDIR)/fstpush.Po
+       -rm -f ./$(DEPDIR)/fstrandgen-main.Po
+       -rm -f ./$(DEPDIR)/fstrandgen.Po
+       -rm -f ./$(DEPDIR)/fstrelabel-main.Po
+       -rm -f ./$(DEPDIR)/fstrelabel.Po
+       -rm -f ./$(DEPDIR)/fstreplace-main.Po
+       -rm -f ./$(DEPDIR)/fstreplace.Po
+       -rm -f ./$(DEPDIR)/fstreverse-main.Po
+       -rm -f ./$(DEPDIR)/fstreverse.Po
+       -rm -f ./$(DEPDIR)/fstreweight-main.Po
+       -rm -f ./$(DEPDIR)/fstreweight.Po
+       -rm -f ./$(DEPDIR)/fstrmepsilon-main.Po
+       -rm -f ./$(DEPDIR)/fstrmepsilon.Po
+       -rm -f ./$(DEPDIR)/fstshortestdistance-main.Po
+       -rm -f ./$(DEPDIR)/fstshortestdistance.Po
+       -rm -f ./$(DEPDIR)/fstshortestpath-main.Po
+       -rm -f ./$(DEPDIR)/fstshortestpath.Po
+       -rm -f ./$(DEPDIR)/fstsymbols-main.Po
+       -rm -f ./$(DEPDIR)/fstsymbols.Po
+       -rm -f ./$(DEPDIR)/fstsynchronize-main.Po
+       -rm -f ./$(DEPDIR)/fstsynchronize.Po
+       -rm -f ./$(DEPDIR)/fsttopsort-main.Po
+       -rm -f ./$(DEPDIR)/fsttopsort.Po
+       -rm -f ./$(DEPDIR)/fstunion-main.Po
+       -rm -f ./$(DEPDIR)/fstunion.Po
        -rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
@@ -1209,7 +1405,7 @@ uninstall-am: uninstall-binPROGRAMS
 
 .MAKE: install-am install-strip
 
-.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
        clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \
        ctags ctags-am distclean distclean-compile distclean-generic \
        distclean-libtool distclean-tags distdir dvi dvi-am html \
index dc45cc2..0f4fe5d 100644 (file)
@@ -4,13 +4,13 @@
 // Creates binary FSTs from simple text format used by AT&T.
 
 #include <cstring>
-#include <fstream>
 #include <istream>
 #include <memory>
 #include <string>
 
 #include <fst/flags.h>
 #include <fst/log.h>
+#include <fstream>
 #include <fst/script/compile.h>
 
 DECLARE_bool(acceptor);
index b1dfbad..7cc3097 100644 (file)
@@ -4,13 +4,13 @@
 // Draws a binary FSTs in the Graphviz dot text format.
 
 #include <cstring>
-#include <fstream>
 #include <memory>
 #include <ostream>
 #include <string>
 
 #include <fst/flags.h>
 #include <fst/log.h>
+#include <fstream>
 #include <fst/script/draw.h>
 
 DECLARE_bool(acceptor);
@@ -96,11 +96,11 @@ int fstdraw_main(int argc, char **argv) {
 
   // "dest" is only used for the name of the file in error messages.
   const std::string dest = out_name.empty() ? "stdout" : out_name;
-  s::DrawFst(*fst, isyms.get(), osyms.get(), ssyms.get(), FLAGS_acceptor,
-             FLAGS_title, FLAGS_width, FLAGS_height, FLAGS_portrait,
-             FLAGS_vertical, FLAGS_ranksep, FLAGS_nodesep, FLAGS_fontsize,
-             FLAGS_precision, FLAGS_float_format, FLAGS_show_weight_one,
-             &ostrm, dest);
+  s::Draw(*fst, isyms.get(), osyms.get(), ssyms.get(), FLAGS_acceptor,
+          FLAGS_title, FLAGS_width, FLAGS_height, FLAGS_portrait,
+          FLAGS_vertical, FLAGS_ranksep, FLAGS_nodesep, FLAGS_fontsize,
+          FLAGS_precision, FLAGS_float_format, FLAGS_show_weight_one, ostrm,
+          dest);
 
   return 0;
 }
index a8340e5..37effd7 100644 (file)
@@ -19,12 +19,12 @@ DECLARE_bool(decode);
 
 int fstencode_main(int argc, char **argv) {
   namespace s = fst::script;
-  using fst::script::FstClass;
+  using fst::script::EncodeMapperClass;
   using fst::script::MutableFstClass;
 
   std::string usage = "Encodes transducer labels and/or weights.\n\n  Usage: ";
   usage += argv[0];
-  usage += " in.fst codex [out.fst]\n";
+  usage += " in.fst mapper [out.fst]\n";
 
   std::set_new_handler(FailedNewHandler);
   SET_FLAGS(usage.c_str(), &argc, &argv, true);
@@ -34,7 +34,7 @@ int fstencode_main(int argc, char **argv) {
   }
 
   const std::string in_name = (strcmp(argv[1], "-") != 0) ? argv[1] : "";
-  const std::string codex_name = argv[2];
+  const std::string mapper_name = argv[2];
   const std::string out_name =
       argc > 3 && strcmp(argv[3], "-") != 0 ? argv[3] : "";
 
@@ -42,12 +42,21 @@ int fstencode_main(int argc, char **argv) {
   if (!fst) return 1;
 
   if (FLAGS_decode) {
-    s::Decode(fst.get(), codex_name);
-    return !fst->Write(out_name);
+    std::unique_ptr<EncodeMapperClass> mapper(
+        EncodeMapperClass::Read(mapper_name));
+    s::Decode(fst.get(), *mapper);
+  } else if (FLAGS_encode_reuse) {
+    std::unique_ptr<EncodeMapperClass> mapper(
+        EncodeMapperClass::Read(mapper_name));
+    if (!mapper) return 1;
+    s::Encode(fst.get(), mapper.get());
   } else {
     const auto flags =
         s::GetEncodeFlags(FLAGS_encode_labels, FLAGS_encode_weights);
-    s::Encode(fst.get(), flags, FLAGS_encode_reuse, codex_name);
-    return !fst->Write(out_name);
+    EncodeMapperClass mapper(fst->ArcType(), flags);
+    s::Encode(fst.get(), &mapper);
+    if (!mapper.Write(mapper_name)) return 1;
   }
+
+  return !fst->Write(out_name);
 }
index 94c19aa..ade5a11 100644 (file)
@@ -5,7 +5,7 @@
 
 DEFINE_bool(encode_labels, false, "Encode output labels");
 DEFINE_bool(encode_weights, false, "Encode weights");
-DEFINE_bool(encode_reuse, false, "Re-use existing codex");
+DEFINE_bool(encode_reuse, false, "Re-use existing mapper");
 DEFINE_bool(decode, false, "Decode labels and/or weights");
 
 int fstencode_main(int argc, char **argv);
index c8685d2..5aab254 100644 (file)
@@ -13,7 +13,6 @@
 
 DECLARE_string(arc_filter);
 DECLARE_string(info_type);
-DECLARE_bool(pipe);
 DECLARE_bool(test_properties);
 DECLARE_bool(fst_verify);
 
@@ -38,8 +37,8 @@ int fstinfo_main(int argc, char **argv) {
   std::unique_ptr<FstClass> ifst(FstClass::Read(in_name));
   if (!ifst) return 1;
 
-  s::PrintFstInfo(*ifst, FLAGS_test_properties, FLAGS_arc_filter,
-                  FLAGS_info_type, FLAGS_fst_verify, FLAGS_pipe);
+  s::Info(*ifst, FLAGS_test_properties, FLAGS_arc_filter, FLAGS_info_type,
+          FLAGS_fst_verify);
 
-  return 0;
+      return 0;
 }
index 6d083e8..a085a57 100644 (file)
@@ -10,7 +10,6 @@ DEFINE_string(arc_filter, "any",
               "connected states, and (strongly) connected components");
 DEFINE_string(info_type, "auto",
               "Info format: one of: \"auto\", \"long\", \"short\"");
-DEFINE_bool(pipe, false, "Send info to stderr, input to stdout");
 DEFINE_bool(test_properties, true,
             "Compute property values (if unknown to FST)");
 DEFINE_bool(fst_verify, true, "Verify FST sanity");
index bf7be38..4d5599c 100644 (file)
@@ -4,13 +4,13 @@
 // Prints out binary FSTs in simple text format used by AT&T.
 
 #include <cstring>
-#include <fstream>
 #include <memory>
 #include <ostream>
 #include <string>
 
 #include <fst/flags.h>
 #include <fst/log.h>
+#include <fstream>
 #include <fst/script/print.h>
 
 DECLARE_bool(acceptor);
@@ -91,8 +91,8 @@ int fstprint_main(int argc, char **argv) {
     osyms.reset(fst->OutputSymbols()->Copy());
   }
 
-  s::PrintFst(*fst, ostrm, dest, isyms.get(), osyms.get(), ssyms.get(),
-              FLAGS_acceptor, FLAGS_show_weight_one, FLAGS_missing_symbol);
+  s::Print(*fst, ostrm, dest, isyms.get(), osyms.get(), ssyms.get(),
+           FLAGS_acceptor, FLAGS_show_weight_one, FLAGS_missing_symbol);
 
   if (isyms && !FLAGS_save_isymbols.empty()) {
     if (!isyms->WriteText(FLAGS_save_isymbols)) return 1;
index 8dc4ad5..6e96872 100644 (file)
@@ -6,6 +6,7 @@
 #include <cstring>
 #include <memory>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include <fst/flags.h>
@@ -85,13 +86,13 @@ int fstrelabel_main(int argc, char **argv) {
                attach_new_osymbols);
   } else {
     // Reads in relabeling pairs.
-    std::vector<s::LabelPair> ipairs;
-    std::vector<s::LabelPair> opairs;
+    std::vector<std::pair<int64, int64>> ipairs;
     if (!FLAGS_relabel_ipairs.empty()) {
       if (!fst::ReadLabelPairs(FLAGS_relabel_ipairs, &ipairs,
                                    FLAGS_allow_negative_labels))
         return 1;
     }
+    std::vector<std::pair<int64, int64>> opairs;
     if (!FLAGS_relabel_opairs.empty()) {
       if (!fst::ReadLabelPairs(FLAGS_relabel_opairs, &opairs,
                                    FLAGS_allow_negative_labels))
index 02fb92c..debb8d6 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <cstring>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include <fst/flags.h>
@@ -17,13 +18,19 @@ DECLARE_string(return_arc_labeling);
 DECLARE_int64(return_label);
 DECLARE_bool(epsilon_on_replace);
 
-void Cleanup(std::vector<fst::script::LabelFstClassPair> *pairs) {
-  for (const auto &pair : *pairs) {
-    delete pair.second;
-  }
+namespace fst {
+namespace script {
+namespace {
+
+void Cleanup(std::vector<std::pair<int64, const FstClass *>> *pairs) {
+  for (const auto &pair : *pairs) delete pair.second;
   pairs->clear();
 }
 
+}  // namespace
+}  // namespace script
+}  // namespace fst
+
 int fstreplace_main(int argc, char **argv) {
   namespace s = fst::script;
   using fst::script::FstClass;
@@ -49,7 +56,7 @@ int fstreplace_main(int argc, char **argv) {
   auto *ifst = FstClass::Read(in_name);
   if (!ifst) return 1;
 
-  std::vector<s::LabelFstClassPair> pairs;
+  std::vector<std::pair<int64, const FstClass *>> pairs;
   // Note that if the root label is beyond the range of the underlying FST's
   // labels, truncation will occur.
   const auto root = atoll(argv[2]);
@@ -58,7 +65,7 @@ int fstreplace_main(int argc, char **argv) {
   for (auto i = 3; i < argc - 1; i += 2) {
     ifst = FstClass::Read(argv[i]);
     if (!ifst) {
-      Cleanup(&pairs);
+      s::Cleanup(&pairs);
       return 1;
     }
     // Note that if the root label is beyond the range of the underlying FST's
@@ -85,7 +92,7 @@ int fstreplace_main(int argc, char **argv) {
 
   VectorFstClass ofst(ifst->ArcType());
   s::Replace(pairs, &ofst, opts);
-  Cleanup(&pairs);
+  s::Cleanup(&pairs);
 
   return !ofst.Write(out_name);
 }
index ada55cf..6be28ae 100644 (file)
@@ -34,7 +34,7 @@ int fsttopsort_main(int argc, char **argv) {
   std::unique_ptr<MutableFstClass> fst(MutableFstClass::Read(in_name, true));
   if (!fst) return 1;
 
-  bool acyclic = TopSort(fst.get());
+  bool acyclic = s::TopSort(fst.get());
 
   if (!acyclic) LOG(WARNING) << argv[0] << ": Input FST is cyclic";
 
index f42de1e..bb7f3b0 100644 (file)
@@ -32,7 +32,7 @@ int fstunion_main(int argc, char **argv) {
   const std::string out_name =
       argc > 3 && strcmp(argv[3], "-") != 0 ? argv[3] : "";
 
-  if (in1_name == "" && in2_name == "") {
+  if (in1_name.empty() && in2_name.empty()) {
     LOG(ERROR) << argv[0] << ": Can't take both inputs from standard input";
     return 1;
   }
index 9d28508..6308dcc 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -89,7 +89,7 @@ build_triplet = @build@
 host_triplet = @host@
 subdir = src/extensions
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_python_devel.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
        $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
@@ -135,7 +135,7 @@ am__recursive_targets = \
   $(RECURSIVE_CLEAN_TARGETS) \
   $(am__extra_recursive_targets)
 AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
-       distdir
+       distdir distdir-am
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
 # Read a list of newline-separated strings from the standard input,
 # and print each of them once, without duplicates.  Input order is
@@ -251,7 +251,7 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
@@ -361,8 +361,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
          *config.status*) \
            cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
          *) \
-           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
        esac;
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@@ -479,7 +479,10 @@ cscopelist-am: $(am__tagged_files)
 distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
-distdir: $(DISTFILES)
+distdir: $(BUILT_SOURCES)
+       $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
        @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        list='$(DISTFILES)'; \
index 7c06a72..93050f7 100644 (file)
@@ -1,4 +1,5 @@
 AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
+LIBS = ../../lib/libfst.la -lm $(DL_LIBS)
 
 libfstdir = @libfstdir@
 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
@@ -7,49 +8,48 @@ 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 17:0:0
-libfstcompact_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
 
 compact8_acceptor_fst_la_SOURCES = compact8_acceptor-fst.cc
-compact8_acceptor_fst_la_LDFLAGS = -module
+compact8_acceptor_fst_la_LDFLAGS = -avoid-version -module
 
 compact8_string_fst_la_SOURCES = compact8_string-fst.cc
-compact8_string_fst_la_LDFLAGS = -module
+compact8_string_fst_la_LDFLAGS = -avoid-version -module
 
 compact8_unweighted_fst_la_SOURCES = compact8_unweighted-fst.cc
-compact8_unweighted_fst_la_LDFLAGS = -module
+compact8_unweighted_fst_la_LDFLAGS = -avoid-version -module
 
 compact8_unweighted_acceptor_fst_la_SOURCES = compact8_unweighted_acceptor-fst.cc
-compact8_unweighted_acceptor_fst_la_LDFLAGS = -module
+compact8_unweighted_acceptor_fst_la_LDFLAGS = -avoid-version -module
 
 compact8_weighted_string_fst_la_SOURCES = compact8_weighted_string-fst.cc
-compact8_weighted_string_fst_la_LDFLAGS = -module
+compact8_weighted_string_fst_la_LDFLAGS = -avoid-version -module
 
 compact16_acceptor_fst_la_SOURCES = compact16_acceptor-fst.cc
-compact16_acceptor_fst_la_LDFLAGS = -module
+compact16_acceptor_fst_la_LDFLAGS = -avoid-version -module
 
 compact16_string_fst_la_SOURCES = compact16_string-fst.cc
-compact16_string_fst_la_LDFLAGS = -module
+compact16_string_fst_la_LDFLAGS = -avoid-version -module
 
 compact16_unweighted_fst_la_SOURCES = compact16_unweighted-fst.cc
-compact16_unweighted_fst_la_LDFLAGS = -module
+compact16_unweighted_fst_la_LDFLAGS = -avoid-version -module
 
 compact16_unweighted_acceptor_fst_la_SOURCES = compact16_unweighted_acceptor-fst.cc
-compact16_unweighted_acceptor_fst_la_LDFLAGS = -module
+compact16_unweighted_acceptor_fst_la_LDFLAGS = -avoid-version -module
 
 compact16_weighted_string_fst_la_SOURCES = compact16_weighted_string-fst.cc
-compact16_weighted_string_fst_la_LDFLAGS = -module
+compact16_weighted_string_fst_la_LDFLAGS = -avoid-version -module
 
 compact64_acceptor_fst_la_SOURCES = compact64_acceptor-fst.cc
-compact64_acceptor_fst_la_LDFLAGS = -module
+compact64_acceptor_fst_la_LDFLAGS = -avoid-version -module
 
 compact64_string_fst_la_SOURCES = compact64_string-fst.cc
-compact64_string_fst_la_LDFLAGS = -module
+compact64_string_fst_la_LDFLAGS = -avoid-version -module
 
 compact64_unweighted_fst_la_SOURCES = compact64_unweighted-fst.cc
-compact64_unweighted_fst_la_LDFLAGS = -module
+compact64_unweighted_fst_la_LDFLAGS = -avoid-version -module
 
 compact64_unweighted_acceptor_fst_la_SOURCES = compact64_unweighted_acceptor-fst.cc
-compact64_unweighted_acceptor_fst_la_LDFLAGS = -module
+compact64_unweighted_acceptor_fst_la_LDFLAGS = -avoid-version -module
 
 compact64_weighted_string_fst_la_SOURCES = compact64_weighted_string-fst.cc
-compact64_weighted_string_fst_la_LDFLAGS = -module
+compact64_weighted_string_fst_la_LDFLAGS = -avoid-version -module
index d0398b8..268716f 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -90,7 +90,7 @@ build_triplet = @build@
 host_triplet = @host@
 subdir = src/extensions/compact
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_python_devel.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
        $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
@@ -263,9 +263,7 @@ compact8_weighted_string_fst_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
        $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
        $(AM_CXXFLAGS) $(CXXFLAGS) \
        $(compact8_weighted_string_fst_la_LDFLAGS) $(LDFLAGS) -o $@
-am__DEPENDENCIES_1 =
-libfstcompact_la_DEPENDENCIES = ../../lib/libfst.la \
-       $(am__DEPENDENCIES_1)
+libfstcompact_la_LIBADD =
 am_libfstcompact_la_OBJECTS = compact8_acceptor-fst.lo \
        compact8_string-fst.lo compact8_unweighted-fst.lo \
        compact8_unweighted_acceptor-fst.lo \
@@ -295,7 +293,22 @@ am__v_at_0 = @
 am__v_at_1 = 
 DEFAULT_INCLUDES = 
 depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/compact16_acceptor-fst.Plo \
+       ./$(DEPDIR)/compact16_string-fst.Plo \
+       ./$(DEPDIR)/compact16_unweighted-fst.Plo \
+       ./$(DEPDIR)/compact16_unweighted_acceptor-fst.Plo \
+       ./$(DEPDIR)/compact16_weighted_string-fst.Plo \
+       ./$(DEPDIR)/compact64_acceptor-fst.Plo \
+       ./$(DEPDIR)/compact64_string-fst.Plo \
+       ./$(DEPDIR)/compact64_unweighted-fst.Plo \
+       ./$(DEPDIR)/compact64_unweighted_acceptor-fst.Plo \
+       ./$(DEPDIR)/compact64_weighted_string-fst.Plo \
+       ./$(DEPDIR)/compact8_acceptor-fst.Plo \
+       ./$(DEPDIR)/compact8_string-fst.Plo \
+       ./$(DEPDIR)/compact8_unweighted-fst.Plo \
+       ./$(DEPDIR)/compact8_unweighted_acceptor-fst.Plo \
+       ./$(DEPDIR)/compact8_weighted_string-fst.Plo
 am__mv = mv -f
 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
        $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
@@ -412,7 +425,7 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
+LIBS = ../../lib/libfst.la -lm $(DL_LIBS)
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -440,7 +453,7 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
@@ -515,37 +528,36 @@ 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 17:0:0
-libfstcompact_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
 compact8_acceptor_fst_la_SOURCES = compact8_acceptor-fst.cc
-compact8_acceptor_fst_la_LDFLAGS = -module
+compact8_acceptor_fst_la_LDFLAGS = -avoid-version -module
 compact8_string_fst_la_SOURCES = compact8_string-fst.cc
-compact8_string_fst_la_LDFLAGS = -module
+compact8_string_fst_la_LDFLAGS = -avoid-version -module
 compact8_unweighted_fst_la_SOURCES = compact8_unweighted-fst.cc
-compact8_unweighted_fst_la_LDFLAGS = -module
+compact8_unweighted_fst_la_LDFLAGS = -avoid-version -module
 compact8_unweighted_acceptor_fst_la_SOURCES = compact8_unweighted_acceptor-fst.cc
-compact8_unweighted_acceptor_fst_la_LDFLAGS = -module
+compact8_unweighted_acceptor_fst_la_LDFLAGS = -avoid-version -module
 compact8_weighted_string_fst_la_SOURCES = compact8_weighted_string-fst.cc
-compact8_weighted_string_fst_la_LDFLAGS = -module
+compact8_weighted_string_fst_la_LDFLAGS = -avoid-version -module
 compact16_acceptor_fst_la_SOURCES = compact16_acceptor-fst.cc
-compact16_acceptor_fst_la_LDFLAGS = -module
+compact16_acceptor_fst_la_LDFLAGS = -avoid-version -module
 compact16_string_fst_la_SOURCES = compact16_string-fst.cc
-compact16_string_fst_la_LDFLAGS = -module
+compact16_string_fst_la_LDFLAGS = -avoid-version -module
 compact16_unweighted_fst_la_SOURCES = compact16_unweighted-fst.cc
-compact16_unweighted_fst_la_LDFLAGS = -module
+compact16_unweighted_fst_la_LDFLAGS = -avoid-version -module
 compact16_unweighted_acceptor_fst_la_SOURCES = compact16_unweighted_acceptor-fst.cc
-compact16_unweighted_acceptor_fst_la_LDFLAGS = -module
+compact16_unweighted_acceptor_fst_la_LDFLAGS = -avoid-version -module
 compact16_weighted_string_fst_la_SOURCES = compact16_weighted_string-fst.cc
-compact16_weighted_string_fst_la_LDFLAGS = -module
+compact16_weighted_string_fst_la_LDFLAGS = -avoid-version -module
 compact64_acceptor_fst_la_SOURCES = compact64_acceptor-fst.cc
-compact64_acceptor_fst_la_LDFLAGS = -module
+compact64_acceptor_fst_la_LDFLAGS = -avoid-version -module
 compact64_string_fst_la_SOURCES = compact64_string-fst.cc
-compact64_string_fst_la_LDFLAGS = -module
+compact64_string_fst_la_LDFLAGS = -avoid-version -module
 compact64_unweighted_fst_la_SOURCES = compact64_unweighted-fst.cc
-compact64_unweighted_fst_la_LDFLAGS = -module
+compact64_unweighted_fst_la_LDFLAGS = -avoid-version -module
 compact64_unweighted_acceptor_fst_la_SOURCES = compact64_unweighted_acceptor-fst.cc
-compact64_unweighted_acceptor_fst_la_LDFLAGS = -module
+compact64_unweighted_acceptor_fst_la_LDFLAGS = -avoid-version -module
 compact64_weighted_string_fst_la_SOURCES = compact64_weighted_string-fst.cc
-compact64_weighted_string_fst_la_LDFLAGS = -module
+compact64_weighted_string_fst_la_LDFLAGS = -avoid-version -module
 all: all-am
 
 .SUFFIXES:
@@ -567,8 +579,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
          *config.status*) \
            cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
          *) \
-           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
        esac;
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@@ -704,21 +716,27 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compact16_acceptor-fst.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compact16_string-fst.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compact16_unweighted-fst.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compact16_unweighted_acceptor-fst.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compact16_weighted_string-fst.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compact64_acceptor-fst.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compact64_string-fst.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compact64_unweighted-fst.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compact64_unweighted_acceptor-fst.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compact64_weighted_string-fst.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compact8_acceptor-fst.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compact8_string-fst.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compact8_unweighted-fst.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compact8_unweighted_acceptor-fst.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compact8_weighted_string-fst.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compact16_acceptor-fst.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compact16_string-fst.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compact16_unweighted-fst.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compact16_unweighted_acceptor-fst.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compact16_weighted_string-fst.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compact64_acceptor-fst.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compact64_string-fst.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compact64_unweighted-fst.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compact64_unweighted_acceptor-fst.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compact64_weighted_string-fst.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compact8_acceptor-fst.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compact8_string-fst.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compact8_unweighted-fst.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compact8_unweighted_acceptor-fst.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compact8_weighted_string-fst.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+       @$(MKDIR_P) $(@D)
+       @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
 
 .cc.o:
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -802,7 +820,10 @@ cscopelist-am: $(am__tagged_files)
 distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
-distdir: $(DISTFILES)
+distdir: $(BUILT_SOURCES)
+       $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
        @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        list='$(DISTFILES)'; \
@@ -875,7 +896,21 @@ clean-am: clean-generic clean-libLTLIBRARIES clean-libfstLTLIBRARIES \
        clean-libtool mostlyclean-am
 
 distclean: distclean-am
-       -rm -rf ./$(DEPDIR)
+               -rm -f ./$(DEPDIR)/compact16_acceptor-fst.Plo
+       -rm -f ./$(DEPDIR)/compact16_string-fst.Plo
+       -rm -f ./$(DEPDIR)/compact16_unweighted-fst.Plo
+       -rm -f ./$(DEPDIR)/compact16_unweighted_acceptor-fst.Plo
+       -rm -f ./$(DEPDIR)/compact16_weighted_string-fst.Plo
+       -rm -f ./$(DEPDIR)/compact64_acceptor-fst.Plo
+       -rm -f ./$(DEPDIR)/compact64_string-fst.Plo
+       -rm -f ./$(DEPDIR)/compact64_unweighted-fst.Plo
+       -rm -f ./$(DEPDIR)/compact64_unweighted_acceptor-fst.Plo
+       -rm -f ./$(DEPDIR)/compact64_weighted_string-fst.Plo
+       -rm -f ./$(DEPDIR)/compact8_acceptor-fst.Plo
+       -rm -f ./$(DEPDIR)/compact8_string-fst.Plo
+       -rm -f ./$(DEPDIR)/compact8_unweighted-fst.Plo
+       -rm -f ./$(DEPDIR)/compact8_unweighted_acceptor-fst.Plo
+       -rm -f ./$(DEPDIR)/compact8_weighted_string-fst.Plo
        -rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
        distclean-tags
@@ -921,7 +956,21 @@ install-ps-am:
 installcheck-am:
 
 maintainer-clean: maintainer-clean-am
-       -rm -rf ./$(DEPDIR)
+               -rm -f ./$(DEPDIR)/compact16_acceptor-fst.Plo
+       -rm -f ./$(DEPDIR)/compact16_string-fst.Plo
+       -rm -f ./$(DEPDIR)/compact16_unweighted-fst.Plo
+       -rm -f ./$(DEPDIR)/compact16_unweighted_acceptor-fst.Plo
+       -rm -f ./$(DEPDIR)/compact16_weighted_string-fst.Plo
+       -rm -f ./$(DEPDIR)/compact64_acceptor-fst.Plo
+       -rm -f ./$(DEPDIR)/compact64_string-fst.Plo
+       -rm -f ./$(DEPDIR)/compact64_unweighted-fst.Plo
+       -rm -f ./$(DEPDIR)/compact64_unweighted_acceptor-fst.Plo
+       -rm -f ./$(DEPDIR)/compact64_weighted_string-fst.Plo
+       -rm -f ./$(DEPDIR)/compact8_acceptor-fst.Plo
+       -rm -f ./$(DEPDIR)/compact8_string-fst.Plo
+       -rm -f ./$(DEPDIR)/compact8_unweighted-fst.Plo
+       -rm -f ./$(DEPDIR)/compact8_unweighted_acceptor-fst.Plo
+       -rm -f ./$(DEPDIR)/compact8_weighted_string-fst.Plo
        -rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
@@ -942,21 +991,21 @@ uninstall-am: uninstall-libLTLIBRARIES uninstall-libfstLTLIBRARIES
 
 .MAKE: install-am install-strip
 
-.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
-       clean-libLTLIBRARIES clean-libfstLTLIBRARIES clean-libtool \
-       cscopelist-am ctags ctags-am distclean distclean-compile \
-       distclean-generic distclean-libtool distclean-tags distdir dvi \
-       dvi-am html html-am info info-am install install-am \
-       install-data install-data-am install-dvi install-dvi-am \
-       install-exec install-exec-am install-html install-html-am \
-       install-info install-info-am install-libLTLIBRARIES \
-       install-libfstLTLIBRARIES install-man install-pdf \
-       install-pdf-am install-ps install-ps-am install-strip \
-       installcheck installcheck-am installdirs maintainer-clean \
-       maintainer-clean-generic mostlyclean mostlyclean-compile \
-       mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
-       tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES \
-       uninstall-libfstLTLIBRARIES
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
+       clean-generic clean-libLTLIBRARIES clean-libfstLTLIBRARIES \
+       clean-libtool cscopelist-am ctags ctags-am distclean \
+       distclean-compile distclean-generic distclean-libtool \
+       distclean-tags distdir dvi dvi-am html html-am info info-am \
+       install install-am install-data install-data-am install-dvi \
+       install-dvi-am install-exec install-exec-am install-html \
+       install-html-am install-info install-info-am \
+       install-libLTLIBRARIES install-libfstLTLIBRARIES install-man \
+       install-pdf install-pdf-am install-ps install-ps-am \
+       install-strip installcheck installcheck-am installdirs \
+       maintainer-clean maintainer-clean-generic mostlyclean \
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+       pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \
+       uninstall-libLTLIBRARIES uninstall-libfstLTLIBRARIES
 
 .PRECIOUS: Makefile
 
index 15de88d..1994f42 100644 (file)
@@ -6,7 +6,7 @@ bin_PROGRAMS = fstcompress
 LDADD = libfstcompressscript.la \
         ../../script/libfstscript.la \
         ../../lib/libfst.la \
-        -lm $(DL_LIBS)
+        -lz -lm $(DL_LIBS)
 
 fstcompress_SOURCES = fstcompress.cc fstcompress-main.cc
 endif
@@ -14,9 +14,9 @@ endif
 if HAVE_SCRIPT
 libfstcompressscript_la_SOURCES = compressscript.cc
 libfstcompressscript_la_LDFLAGS = -version-info 17:0:0
-libfstcompressscript_la_LIBADD = \
-        ../../script/libfstscript.la \
-        ../../lib/libfst.la -lz -lm $(DL_LIBS)
+libfstcompressscript_la_LIBADD = ../../script/libfstscript.la \
+                                 ../../lib/libfst.la \
+                                 -lz -lm $(DL_LIBS)
 endif
 
 if HAVE_SCRIPT
index 376b46a..3d6b697 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -92,7 +92,7 @@ host_triplet = @host@
 @HAVE_BIN_TRUE@bin_PROGRAMS = fstcompress$(EXEEXT)
 subdir = src/extensions/compress
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_python_devel.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
        $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
@@ -104,6 +104,8 @@ CONFIG_HEADER = $(top_builddir)/config.h \
        $(top_builddir)/src/include/fst/config.h
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)"
+PROGRAMS = $(bin_PROGRAMS)
 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
 am__vpath_adj = case $$p in \
     $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
@@ -131,7 +133,6 @@ am__uninstall_files_from_dir = { \
     || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
          $(am__cd) "$$dir" && rm -f $$files; }; \
   }
-am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)"
 LTLIBRARIES = $(lib_LTLIBRARIES)
 am__DEPENDENCIES_1 =
 @HAVE_SCRIPT_TRUE@libfstcompressscript_la_DEPENDENCIES =  \
@@ -151,7 +152,6 @@ libfstcompressscript_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
        $(AM_CXXFLAGS) $(CXXFLAGS) $(libfstcompressscript_la_LDFLAGS) \
        $(LDFLAGS) -o $@
 @HAVE_SCRIPT_TRUE@am_libfstcompressscript_la_rpath = -rpath $(libdir)
-PROGRAMS = $(bin_PROGRAMS)
 am__fstcompress_SOURCES_DIST = fstcompress.cc fstcompress-main.cc
 @HAVE_BIN_TRUE@am_fstcompress_OBJECTS = fstcompress.$(OBJEXT) \
 @HAVE_BIN_TRUE@        fstcompress-main.$(OBJEXT)
@@ -174,7 +174,9 @@ am__v_at_0 = @
 am__v_at_1 = 
 DEFAULT_INCLUDES = 
 depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/compressscript.Plo \
+       ./$(DEPDIR)/fstcompress-main.Po ./$(DEPDIR)/fstcompress.Po
 am__mv = mv -f
 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
        $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
@@ -290,7 +292,7 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
@@ -364,14 +366,14 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 @HAVE_BIN_TRUE@LDADD = libfstcompressscript.la \
 @HAVE_BIN_TRUE@        ../../script/libfstscript.la \
 @HAVE_BIN_TRUE@        ../../lib/libfst.la \
-@HAVE_BIN_TRUE@        -lm $(DL_LIBS)
+@HAVE_BIN_TRUE@        -lz -lm $(DL_LIBS)
 
 @HAVE_BIN_TRUE@fstcompress_SOURCES = fstcompress.cc fstcompress-main.cc
 @HAVE_SCRIPT_TRUE@libfstcompressscript_la_SOURCES = compressscript.cc
 @HAVE_SCRIPT_TRUE@libfstcompressscript_la_LDFLAGS = -version-info 17:0:0
-@HAVE_SCRIPT_TRUE@libfstcompressscript_la_LIBADD = \
-@HAVE_SCRIPT_TRUE@        ../../script/libfstscript.la \
-@HAVE_SCRIPT_TRUE@        ../../lib/libfst.la -lz -lm $(DL_LIBS)
+@HAVE_SCRIPT_TRUE@libfstcompressscript_la_LIBADD = ../../script/libfstscript.la \
+@HAVE_SCRIPT_TRUE@                                 ../../lib/libfst.la \
+@HAVE_SCRIPT_TRUE@                                 -lz -lm $(DL_LIBS)
 
 @HAVE_SCRIPT_TRUE@lib_LTLIBRARIES = libfstcompressscript.la
 all: all-am
@@ -395,8 +397,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
          *config.status*) \
            cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
          *) \
-           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
        esac;
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@@ -407,44 +409,6 @@ $(top_srcdir)/configure:  $(am__configure_deps)
 $(ACLOCAL_M4):  $(am__aclocal_m4_deps)
        cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 $(am__aclocal_m4_deps):
-
-install-libLTLIBRARIES: $(lib_LTLIBRARIES)
-       @$(NORMAL_INSTALL)
-       @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
-       list2=; for p in $$list; do \
-         if test -f $$p; then \
-           list2="$$list2 $$p"; \
-         else :; fi; \
-       done; \
-       test -z "$$list2" || { \
-         echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
-         $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
-         echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
-         $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
-       }
-
-uninstall-libLTLIBRARIES:
-       @$(NORMAL_UNINSTALL)
-       @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
-       for p in $$list; do \
-         $(am__strip_dir) \
-         echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
-         $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
-       done
-
-clean-libLTLIBRARIES:
-       -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
-       @list='$(lib_LTLIBRARIES)'; \
-       locs=`for p in $$list; do echo $$p; done | \
-             sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
-             sort -u`; \
-       test -z "$$locs" || { \
-         echo rm -f $${locs}; \
-         rm -f $${locs}; \
-       }
-
-libfstcompressscript.la: $(libfstcompressscript_la_OBJECTS) $(libfstcompressscript_la_DEPENDENCIES) $(EXTRA_libfstcompressscript_la_DEPENDENCIES) 
-       $(AM_V_CXXLD)$(libfstcompressscript_la_LINK) $(am_libfstcompressscript_la_rpath) $(libfstcompressscript_la_OBJECTS) $(libfstcompressscript_la_LIBADD) $(LIBS)
 install-binPROGRAMS: $(bin_PROGRAMS)
        @$(NORMAL_INSTALL)
        @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
@@ -495,6 +459,44 @@ clean-binPROGRAMS:
        echo " rm -f" $$list; \
        rm -f $$list
 
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+       @$(NORMAL_INSTALL)
+       @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+       list2=; for p in $$list; do \
+         if test -f $$p; then \
+           list2="$$list2 $$p"; \
+         else :; fi; \
+       done; \
+       test -z "$$list2" || { \
+         echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+         $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
+         echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+         $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+       }
+
+uninstall-libLTLIBRARIES:
+       @$(NORMAL_UNINSTALL)
+       @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+       for p in $$list; do \
+         $(am__strip_dir) \
+         echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+         $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+       done
+
+clean-libLTLIBRARIES:
+       -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+       @list='$(lib_LTLIBRARIES)'; \
+       locs=`for p in $$list; do echo $$p; done | \
+             sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+             sort -u`; \
+       test -z "$$locs" || { \
+         echo rm -f $${locs}; \
+         rm -f $${locs}; \
+       }
+
+libfstcompressscript.la: $(libfstcompressscript_la_OBJECTS) $(libfstcompressscript_la_DEPENDENCIES) $(EXTRA_libfstcompressscript_la_DEPENDENCIES) 
+       $(AM_V_CXXLD)$(libfstcompressscript_la_LINK) $(am_libfstcompressscript_la_rpath) $(libfstcompressscript_la_OBJECTS) $(libfstcompressscript_la_LIBADD) $(LIBS)
+
 fstcompress$(EXEEXT): $(fstcompress_OBJECTS) $(fstcompress_DEPENDENCIES) $(EXTRA_fstcompress_DEPENDENCIES) 
        @rm -f fstcompress$(EXEEXT)
        $(AM_V_CXXLD)$(CXXLINK) $(fstcompress_OBJECTS) $(fstcompress_LDADD) $(LIBS)
@@ -505,9 +507,15 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compressscript.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstcompress-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstcompress.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compressscript.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstcompress-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstcompress.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+       @$(MKDIR_P) $(@D)
+       @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
 
 .cc.o:
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -591,7 +599,10 @@ cscopelist-am: $(am__tagged_files)
 distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
-distdir: $(DISTFILES)
+distdir: $(BUILT_SOURCES)
+       $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
        @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        list='$(DISTFILES)'; \
@@ -623,11 +634,11 @@ distdir: $(DISTFILES)
        done
 check-am: all-am
 check: check-am
-all-am: Makefile $(LTLIBRARIES) $(PROGRAMS)
+all-am: Makefile $(PROGRAMS) $(LTLIBRARIES)
 install-binPROGRAMS: install-libLTLIBRARIES
 
 installdirs:
-       for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)"; do \
+       for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)"; do \
          test -z "$$dir" || $(MKDIR_P) "$$dir"; \
        done
 install: install-am
@@ -666,7 +677,9 @@ clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
        clean-libtool mostlyclean-am
 
 distclean: distclean-am
-       -rm -rf ./$(DEPDIR)
+               -rm -f ./$(DEPDIR)/compressscript.Plo
+       -rm -f ./$(DEPDIR)/fstcompress-main.Po
+       -rm -f ./$(DEPDIR)/fstcompress.Po
        -rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
        distclean-tags
@@ -712,7 +725,9 @@ install-ps-am:
 installcheck-am:
 
 maintainer-clean: maintainer-clean-am
-       -rm -rf ./$(DEPDIR)
+               -rm -f ./$(DEPDIR)/compressscript.Plo
+       -rm -f ./$(DEPDIR)/fstcompress-main.Po
+       -rm -f ./$(DEPDIR)/fstcompress.Po
        -rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
@@ -733,7 +748,7 @@ uninstall-am: uninstall-binPROGRAMS uninstall-libLTLIBRARIES
 
 .MAKE: install-am install-strip
 
-.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
        clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
        clean-libtool cscopelist-am ctags ctags-am distclean \
        distclean-compile distclean-generic distclean-libtool \
index 0b4a6c3..82c64e8 100644 (file)
@@ -9,31 +9,24 @@
 namespace fst {
 namespace script {
 
-bool Compress(const FstClass &fst, const std::string &filename,
-              const bool gzip) {
-  CompressInnerArgs iargs(fst, filename, gzip);
+bool Compress(const FstClass &fst, const std::string &source, const bool gzip) {
+  CompressInnerArgs iargs(fst, source, gzip);
   CompressArgs args(iargs);
   Apply<Operation<CompressArgs>>("Compress", fst.ArcType(), &args);
   return args.retval;
 }
 
-bool Decompress(const std::string &filename, MutableFstClass *fst,
+REGISTER_FST_OPERATION_3ARCS(Compress, CompressArgs);
+
+bool Decompress(const std::string &source, MutableFstClass *fst,
                 const bool gzip) {
-  DecompressInnerArgs iargs(filename, fst, gzip);
+  DecompressInnerArgs iargs(source, fst, gzip);
   DecompressArgs args(iargs);
   Apply<Operation<DecompressArgs>>("Decompress", fst->ArcType(), &args);
   return args.retval;
 }
 
-// Register operations for common arc types.
-
-REGISTER_FST_OPERATION(Compress, StdArc, CompressArgs);
-REGISTER_FST_OPERATION(Compress, LogArc, CompressArgs);
-REGISTER_FST_OPERATION(Compress, Log64Arc, CompressArgs);
-
-REGISTER_FST_OPERATION(Decompress, StdArc, DecompressArgs);
-REGISTER_FST_OPERATION(Decompress, LogArc, DecompressArgs);
-REGISTER_FST_OPERATION(Decompress, Log64Arc, DecompressArgs);
+REGISTER_FST_OPERATION_3ARCS(Decompress, DecompressArgs);
 
 }  // namespace script
 }  // namespace fst
index 17b16b5..20cbfd8 100644 (file)
@@ -5,10 +5,7 @@
 
 DEFINE_string(arc_type, "standard", "Output arc type");
 DEFINE_bool(decode, false, "Decode");
-DEFINE_bool(gzip, false,
-            "Applies gzip compression after LZA compression and "
-            "gzip decompression before LZA decompression"
-);
+DEFINE_bool(gzip, false, "Also applies gzip (de)compression");
 
 int fstcompress_main(int argc, char **argv);
 
index aa0dbad..71d5109 100644 (file)
@@ -1,4 +1,5 @@
 AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
+LIBS = ../../lib/libfst.la -lm $(DL_LIBS)
 
 libfstdir = @libfstdir@
 libfst_LTLIBRARIES = const8-fst.la const16-fst.la const64-fst.la
@@ -6,14 +7,13 @@ 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 17:0:0 -lm $(DL_LIBS)
-libfstconst_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
+libfstconst_la_LDFLAGS = -version-info 17:0:0
 
 const8_fst_la_SOURCES = const8-fst.cc
-const8_fst_la_LDFLAGS = -module
+const8_fst_la_LDFLAGS = -avoid-version -module
 
 const16_fst_la_SOURCES = const16-fst.cc
-const16_fst_la_LDFLAGS = -module
+const16_fst_la_LDFLAGS = -avoid-version -module
 
 const64_fst_la_SOURCES = const64-fst.cc
-const64_fst_la_LDFLAGS = -module
+const64_fst_la_LDFLAGS = -avoid-version -module
index fc46091..f88f619 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -90,7 +90,7 @@ build_triplet = @build@
 host_triplet = @host@
 subdir = src/extensions/const
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_python_devel.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
        $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
@@ -156,9 +156,7 @@ const8_fst_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
        $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
        $(AM_CXXFLAGS) $(CXXFLAGS) $(const8_fst_la_LDFLAGS) $(LDFLAGS) \
        -o $@
-am__DEPENDENCIES_1 =
-libfstconst_la_DEPENDENCIES = ../../lib/libfst.la \
-       $(am__DEPENDENCIES_1)
+libfstconst_la_LIBADD =
 am_libfstconst_la_OBJECTS = const8-fst.lo const16-fst.lo \
        const64-fst.lo
 libfstconst_la_OBJECTS = $(am_libfstconst_la_OBJECTS)
@@ -180,7 +178,9 @@ am__v_at_0 = @
 am__v_at_1 = 
 DEFAULT_INCLUDES = 
 depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/const16-fst.Plo \
+       ./$(DEPDIR)/const64-fst.Plo ./$(DEPDIR)/const8-fst.Plo
 am__mv = mv -f
 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
        $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
@@ -269,7 +269,7 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
+LIBS = ../../lib/libfst.la -lm $(DL_LIBS)
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -297,7 +297,7 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
@@ -371,14 +371,13 @@ 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 17:0:0 -lm $(DL_LIBS)
-libfstconst_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
+libfstconst_la_LDFLAGS = -version-info 17:0:0
 const8_fst_la_SOURCES = const8-fst.cc
-const8_fst_la_LDFLAGS = -module
+const8_fst_la_LDFLAGS = -avoid-version -module
 const16_fst_la_SOURCES = const16-fst.cc
-const16_fst_la_LDFLAGS = -module
+const16_fst_la_LDFLAGS = -avoid-version -module
 const64_fst_la_SOURCES = const64-fst.cc
-const64_fst_la_LDFLAGS = -module
+const64_fst_la_LDFLAGS = -avoid-version -module
 all: all-am
 
 .SUFFIXES:
@@ -400,8 +399,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
          *config.status*) \
            cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
          *) \
-           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
        esac;
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@@ -501,9 +500,15 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/const16-fst.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/const64-fst.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/const8-fst.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/const16-fst.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/const64-fst.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/const8-fst.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+       @$(MKDIR_P) $(@D)
+       @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
 
 .cc.o:
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -587,7 +592,10 @@ cscopelist-am: $(am__tagged_files)
 distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
-distdir: $(DISTFILES)
+distdir: $(BUILT_SOURCES)
+       $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
        @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        list='$(DISTFILES)'; \
@@ -660,7 +668,9 @@ clean-am: clean-generic clean-libLTLIBRARIES clean-libfstLTLIBRARIES \
        clean-libtool mostlyclean-am
 
 distclean: distclean-am
-       -rm -rf ./$(DEPDIR)
+               -rm -f ./$(DEPDIR)/const16-fst.Plo
+       -rm -f ./$(DEPDIR)/const64-fst.Plo
+       -rm -f ./$(DEPDIR)/const8-fst.Plo
        -rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
        distclean-tags
@@ -706,7 +716,9 @@ install-ps-am:
 installcheck-am:
 
 maintainer-clean: maintainer-clean-am
-       -rm -rf ./$(DEPDIR)
+               -rm -f ./$(DEPDIR)/const16-fst.Plo
+       -rm -f ./$(DEPDIR)/const64-fst.Plo
+       -rm -f ./$(DEPDIR)/const8-fst.Plo
        -rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
@@ -727,21 +739,21 @@ uninstall-am: uninstall-libLTLIBRARIES uninstall-libfstLTLIBRARIES
 
 .MAKE: install-am install-strip
 
-.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
-       clean-libLTLIBRARIES clean-libfstLTLIBRARIES clean-libtool \
-       cscopelist-am ctags ctags-am distclean distclean-compile \
-       distclean-generic distclean-libtool distclean-tags distdir dvi \
-       dvi-am html html-am info info-am install install-am \
-       install-data install-data-am install-dvi install-dvi-am \
-       install-exec install-exec-am install-html install-html-am \
-       install-info install-info-am install-libLTLIBRARIES \
-       install-libfstLTLIBRARIES install-man install-pdf \
-       install-pdf-am install-ps install-ps-am install-strip \
-       installcheck installcheck-am installdirs maintainer-clean \
-       maintainer-clean-generic mostlyclean mostlyclean-compile \
-       mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
-       tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES \
-       uninstall-libfstLTLIBRARIES
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
+       clean-generic clean-libLTLIBRARIES clean-libfstLTLIBRARIES \
+       clean-libtool cscopelist-am ctags ctags-am distclean \
+       distclean-compile distclean-generic distclean-libtool \
+       distclean-tags distdir dvi dvi-am html html-am info info-am \
+       install install-am install-data install-data-am install-dvi \
+       install-dvi-am install-exec install-exec-am install-html \
+       install-html-am install-info install-info-am \
+       install-libLTLIBRARIES install-libfstLTLIBRARIES install-man \
+       install-pdf install-pdf-am install-ps install-ps-am \
+       install-strip installcheck installcheck-am installdirs \
+       maintainer-clean maintainer-clean-generic mostlyclean \
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+       pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \
+       uninstall-libLTLIBRARIES uninstall-libfstLTLIBRARIES
 
 .PRECIOUS: Makefile
 
index 36a97da..9d91943 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -95,7 +95,7 @@ host_triplet = @host@
 @HAVE_BIN_TRUE@        farisomorphic$(EXEEXT) farprintstrings$(EXEEXT)
 subdir = src/extensions/far
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_python_devel.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
        $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
@@ -107,6 +107,8 @@ CONFIG_HEADER = $(top_builddir)/config.h \
        $(top_builddir)/src/include/fst/config.h
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)"
+PROGRAMS = $(bin_PROGRAMS)
 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
 am__vpath_adj = case $$p in \
     $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
@@ -134,7 +136,6 @@ am__uninstall_files_from_dir = { \
     || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
          $(am__cd) "$$dir" && rm -f $$files; }; \
   }
-am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)"
 LTLIBRARIES = $(lib_LTLIBRARIES)
 am__DEPENDENCIES_1 =
 libfstfar_la_DEPENDENCIES = ../../lib/libfst.la $(am__DEPENDENCIES_1)
@@ -163,7 +164,6 @@ libfstfarscript_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
        $(AM_CXXFLAGS) $(CXXFLAGS) $(libfstfarscript_la_LDFLAGS) \
        $(LDFLAGS) -o $@
 @HAVE_SCRIPT_TRUE@am_libfstfarscript_la_rpath = -rpath $(libdir)
-PROGRAMS = $(bin_PROGRAMS)
 am__farcompilestrings_SOURCES_DIST = farcompilestrings.cc \
        farcompilestrings-main.cc
 @HAVE_BIN_TRUE@am_farcompilestrings_OBJECTS =  \
@@ -238,7 +238,20 @@ am__v_at_0 = @
 am__v_at_1 = 
 DEFAULT_INCLUDES = 
 depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/far-class.Plo \
+       ./$(DEPDIR)/farcompilestrings-main.Po \
+       ./$(DEPDIR)/farcompilestrings.Po ./$(DEPDIR)/farcreate-main.Po \
+       ./$(DEPDIR)/farcreate.Po ./$(DEPDIR)/farequal-main.Po \
+       ./$(DEPDIR)/farequal.Po ./$(DEPDIR)/farextract-main.Po \
+       ./$(DEPDIR)/farextract.Po ./$(DEPDIR)/farinfo-main.Po \
+       ./$(DEPDIR)/farinfo.Po ./$(DEPDIR)/farisomorphic-main.Po \
+       ./$(DEPDIR)/farisomorphic.Po \
+       ./$(DEPDIR)/farprintstrings-main.Po \
+       ./$(DEPDIR)/farprintstrings.Po ./$(DEPDIR)/farscript.Plo \
+       ./$(DEPDIR)/getters.Plo ./$(DEPDIR)/script-impl.Plo \
+       ./$(DEPDIR)/stlist.Plo ./$(DEPDIR)/strings.Plo \
+       ./$(DEPDIR)/sttable.Plo
 am__mv = mv -f
 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
        $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
@@ -362,7 +375,7 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
@@ -477,8 +490,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
          *config.status*) \
            cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
          *) \
-           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
        esac;
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@@ -489,47 +502,6 @@ $(top_srcdir)/configure:  $(am__configure_deps)
 $(ACLOCAL_M4):  $(am__aclocal_m4_deps)
        cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 $(am__aclocal_m4_deps):
-
-install-libLTLIBRARIES: $(lib_LTLIBRARIES)
-       @$(NORMAL_INSTALL)
-       @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
-       list2=; for p in $$list; do \
-         if test -f $$p; then \
-           list2="$$list2 $$p"; \
-         else :; fi; \
-       done; \
-       test -z "$$list2" || { \
-         echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
-         $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
-         echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
-         $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
-       }
-
-uninstall-libLTLIBRARIES:
-       @$(NORMAL_UNINSTALL)
-       @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
-       for p in $$list; do \
-         $(am__strip_dir) \
-         echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
-         $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
-       done
-
-clean-libLTLIBRARIES:
-       -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
-       @list='$(lib_LTLIBRARIES)'; \
-       locs=`for p in $$list; do echo $$p; done | \
-             sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
-             sort -u`; \
-       test -z "$$locs" || { \
-         echo rm -f $${locs}; \
-         rm -f $${locs}; \
-       }
-
-libfstfar.la: $(libfstfar_la_OBJECTS) $(libfstfar_la_DEPENDENCIES) $(EXTRA_libfstfar_la_DEPENDENCIES) 
-       $(AM_V_CXXLD)$(libfstfar_la_LINK) $(am_libfstfar_la_rpath) $(libfstfar_la_OBJECTS) $(libfstfar_la_LIBADD) $(LIBS)
-
-libfstfarscript.la: $(libfstfarscript_la_OBJECTS) $(libfstfarscript_la_DEPENDENCIES) $(EXTRA_libfstfarscript_la_DEPENDENCIES) 
-       $(AM_V_CXXLD)$(libfstfarscript_la_LINK) $(am_libfstfarscript_la_rpath) $(libfstfarscript_la_OBJECTS) $(libfstfarscript_la_LIBADD) $(LIBS)
 install-binPROGRAMS: $(bin_PROGRAMS)
        @$(NORMAL_INSTALL)
        @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
@@ -580,6 +552,47 @@ clean-binPROGRAMS:
        echo " rm -f" $$list; \
        rm -f $$list
 
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+       @$(NORMAL_INSTALL)
+       @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+       list2=; for p in $$list; do \
+         if test -f $$p; then \
+           list2="$$list2 $$p"; \
+         else :; fi; \
+       done; \
+       test -z "$$list2" || { \
+         echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+         $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
+         echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+         $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+       }
+
+uninstall-libLTLIBRARIES:
+       @$(NORMAL_UNINSTALL)
+       @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+       for p in $$list; do \
+         $(am__strip_dir) \
+         echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+         $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+       done
+
+clean-libLTLIBRARIES:
+       -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+       @list='$(lib_LTLIBRARIES)'; \
+       locs=`for p in $$list; do echo $$p; done | \
+             sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+             sort -u`; \
+       test -z "$$locs" || { \
+         echo rm -f $${locs}; \
+         rm -f $${locs}; \
+       }
+
+libfstfar.la: $(libfstfar_la_OBJECTS) $(libfstfar_la_DEPENDENCIES) $(EXTRA_libfstfar_la_DEPENDENCIES) 
+       $(AM_V_CXXLD)$(libfstfar_la_LINK) $(am_libfstfar_la_rpath) $(libfstfar_la_OBJECTS) $(libfstfar_la_LIBADD) $(LIBS)
+
+libfstfarscript.la: $(libfstfarscript_la_OBJECTS) $(libfstfarscript_la_DEPENDENCIES) $(EXTRA_libfstfarscript_la_DEPENDENCIES) 
+       $(AM_V_CXXLD)$(libfstfarscript_la_LINK) $(am_libfstfarscript_la_rpath) $(libfstfarscript_la_OBJECTS) $(libfstfarscript_la_LIBADD) $(LIBS)
+
 farcompilestrings$(EXEEXT): $(farcompilestrings_OBJECTS) $(farcompilestrings_DEPENDENCIES) $(EXTRA_farcompilestrings_DEPENDENCIES) 
        @rm -f farcompilestrings$(EXEEXT)
        $(AM_V_CXXLD)$(CXXLINK) $(farcompilestrings_OBJECTS) $(farcompilestrings_LDADD) $(LIBS)
@@ -614,27 +627,33 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/far-class.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farcompilestrings-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farcompilestrings.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farcreate-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farcreate.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farequal-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farequal.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farextract-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farextract.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farinfo-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farinfo.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farisomorphic-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farisomorphic.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farprintstrings-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farprintstrings.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farscript.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getters.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/script-impl.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stlist.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strings.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sttable.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/far-class.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farcompilestrings-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farcompilestrings.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farcreate-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farcreate.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farequal-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farequal.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farextract-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farextract.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farinfo-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farinfo.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farisomorphic-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farisomorphic.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farprintstrings-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farprintstrings.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farscript.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getters.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/script-impl.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stlist.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strings.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sttable.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+       @$(MKDIR_P) $(@D)
+       @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
 
 .cc.o:
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -718,7 +737,10 @@ cscopelist-am: $(am__tagged_files)
 distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
-distdir: $(DISTFILES)
+distdir: $(BUILT_SOURCES)
+       $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
        @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        list='$(DISTFILES)'; \
@@ -750,11 +772,11 @@ distdir: $(DISTFILES)
        done
 check-am: all-am
 check: check-am
-all-am: Makefile $(LTLIBRARIES) $(PROGRAMS)
+all-am: Makefile $(PROGRAMS) $(LTLIBRARIES)
 install-binPROGRAMS: install-libLTLIBRARIES
 
 installdirs:
-       for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)"; do \
+       for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)"; do \
          test -z "$$dir" || $(MKDIR_P) "$$dir"; \
        done
 install: install-am
@@ -793,7 +815,27 @@ clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
        clean-libtool mostlyclean-am
 
 distclean: distclean-am
-       -rm -rf ./$(DEPDIR)
+               -rm -f ./$(DEPDIR)/far-class.Plo
+       -rm -f ./$(DEPDIR)/farcompilestrings-main.Po
+       -rm -f ./$(DEPDIR)/farcompilestrings.Po
+       -rm -f ./$(DEPDIR)/farcreate-main.Po
+       -rm -f ./$(DEPDIR)/farcreate.Po
+       -rm -f ./$(DEPDIR)/farequal-main.Po
+       -rm -f ./$(DEPDIR)/farequal.Po
+       -rm -f ./$(DEPDIR)/farextract-main.Po
+       -rm -f ./$(DEPDIR)/farextract.Po
+       -rm -f ./$(DEPDIR)/farinfo-main.Po
+       -rm -f ./$(DEPDIR)/farinfo.Po
+       -rm -f ./$(DEPDIR)/farisomorphic-main.Po
+       -rm -f ./$(DEPDIR)/farisomorphic.Po
+       -rm -f ./$(DEPDIR)/farprintstrings-main.Po
+       -rm -f ./$(DEPDIR)/farprintstrings.Po
+       -rm -f ./$(DEPDIR)/farscript.Plo
+       -rm -f ./$(DEPDIR)/getters.Plo
+       -rm -f ./$(DEPDIR)/script-impl.Plo
+       -rm -f ./$(DEPDIR)/stlist.Plo
+       -rm -f ./$(DEPDIR)/strings.Plo
+       -rm -f ./$(DEPDIR)/sttable.Plo
        -rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
        distclean-tags
@@ -839,7 +881,27 @@ install-ps-am:
 installcheck-am:
 
 maintainer-clean: maintainer-clean-am
-       -rm -rf ./$(DEPDIR)
+               -rm -f ./$(DEPDIR)/far-class.Plo
+       -rm -f ./$(DEPDIR)/farcompilestrings-main.Po
+       -rm -f ./$(DEPDIR)/farcompilestrings.Po
+       -rm -f ./$(DEPDIR)/farcreate-main.Po
+       -rm -f ./$(DEPDIR)/farcreate.Po
+       -rm -f ./$(DEPDIR)/farequal-main.Po
+       -rm -f ./$(DEPDIR)/farequal.Po
+       -rm -f ./$(DEPDIR)/farextract-main.Po
+       -rm -f ./$(DEPDIR)/farextract.Po
+       -rm -f ./$(DEPDIR)/farinfo-main.Po
+       -rm -f ./$(DEPDIR)/farinfo.Po
+       -rm -f ./$(DEPDIR)/farisomorphic-main.Po
+       -rm -f ./$(DEPDIR)/farisomorphic.Po
+       -rm -f ./$(DEPDIR)/farprintstrings-main.Po
+       -rm -f ./$(DEPDIR)/farprintstrings.Po
+       -rm -f ./$(DEPDIR)/farscript.Plo
+       -rm -f ./$(DEPDIR)/getters.Plo
+       -rm -f ./$(DEPDIR)/script-impl.Plo
+       -rm -f ./$(DEPDIR)/stlist.Plo
+       -rm -f ./$(DEPDIR)/strings.Plo
+       -rm -f ./$(DEPDIR)/sttable.Plo
        -rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
@@ -860,7 +922,7 @@ uninstall-am: uninstall-binPROGRAMS uninstall-libLTLIBRARIES
 
 .MAKE: install-am install-strip
 
-.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
        clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
        clean-libtool cscopelist-am ctags ctags-am distclean \
        distclean-compile distclean-generic distclean-libtool \
index e41a196..380f884 100644 (file)
@@ -12,20 +12,19 @@ namespace script {
 
 // FarReaderClass.
 
-FarReaderClass *FarReaderClass::Open(const std::string &filename) {
-  const std::vector<std::string> filenames{filename};
-  return FarReaderClass::Open(filenames);
+FarReaderClass *FarReaderClass::Open(const std::string &source) {
+  const std::vector<std::string> sources{source};
+  return FarReaderClass::Open(sources);
 }
 
-FarReaderClass *FarReaderClass::Open(
-    const std::vector<std::string> &filenames) {
-  if (filenames.empty()) {
+FarReaderClass *FarReaderClass::Open(const std::vector<std::string> &sources) {
+  if (sources.empty()) {
     LOG(ERROR) << "FarReaderClass::Open: No files specified";
     return nullptr;
   }
-  const auto arc_type = LoadArcTypeFromFar(filenames.front());
+  const auto arc_type = LoadArcTypeFromFar(sources.front());
   if (arc_type.empty()) return nullptr;
-  OpenFarReaderClassArgs args(filenames);
+  OpenFarReaderClassArgs args(sources);
   args.retval = nullptr;
   Apply<Operation<OpenFarReaderClassArgs>>("OpenFarReaderClass", arc_type,
                                             &args);
@@ -38,10 +37,10 @@ REGISTER_FST_OPERATION(OpenFarReaderClass, Log64Arc, OpenFarReaderClassArgs);
 
 // FarWriterClass.
 
-FarWriterClass *FarWriterClass::Create(const std::string &filename,
+FarWriterClass *FarWriterClass::Create(const std::string &source,
                                        const std::string &arc_type,
                                        FarType type) {
-  CreateFarWriterClassInnerArgs iargs(filename, type);
+  CreateFarWriterClassInnerArgs iargs(source, type);
   CreateFarWriterClassArgs args(iargs);
   args.retval = nullptr;
   Apply<Operation<CreateFarWriterClassArgs>>("CreateFarWriterClass", arc_type,
index da47097..e9dc14f 100644 (file)
@@ -38,27 +38,27 @@ int farcompilestrings_main(int argc, char **argv) {
   SET_FLAGS(usage.c_str(), &argc, &argv, true);
   s::ExpandArgs(argc, argv, &argc, &argv);
 
-  std::vector<std::string> in_fnames;
+  std::vector<std::string> in_sources;
   if (FLAGS_file_list_input) {
     for (int i = 1; i < argc - 1; ++i) {
       std::ifstream istrm(argv[i]);
       std::string str;
-      while (getline(istrm, str)) in_fnames.push_back(str);
+      while (getline(istrm, str)) in_sources.push_back(str);
     }
   } else {
     for (int i = 1; i < argc - 1; ++i)
-      in_fnames.push_back(strcmp(argv[i], "-") != 0 ? argv[i] : "");
+      in_sources.push_back(strcmp(argv[i], "-") != 0 ? argv[i] : "");
   }
-  if (in_fnames.empty()) {
+  if (in_sources.empty()) {
     // argc == 1 || argc == 2.  This cleverly handles both the no-file case
     // and the one (input) file case together.
     // TODO(jrosenstock): This probably shouldn't happen for the
     // --file_list_input case.
-    in_fnames.push_back(argc == 2 && strcmp(argv[1], "-") != 0 ? argv[1] : "");
+    in_sources.push_back(argc == 2 && strcmp(argv[1], "-") != 0 ? argv[1] : "");
   }
 
   // argc <= 2 means the file (if any) is an input file, so write to stdout.
-  const std::string out_fname =
+  const std::string out_source =
       argc > 2 && strcmp(argv[argc - 1], "-") != 0 ? argv[argc - 1] : "";
 
   fst::FarEntryType entry_type;
@@ -75,7 +75,7 @@ int farcompilestrings_main(int argc, char **argv) {
 
   const auto far_type = s::GetFarType(FLAGS_far_type);
 
-  s::FarCompileStrings(in_fnames, out_fname, FLAGS_arc_type, FLAGS_fst_type,
+  s::FarCompileStrings(in_sources, out_source, FLAGS_arc_type, FLAGS_fst_type,
                        far_type, FLAGS_generate_keys, entry_type, token_type,
                        FLAGS_symbols, FLAGS_unknown_symbol, FLAGS_keep_symbols,
                        FLAGS_initial_symbols, FLAGS_allow_negative_labels,
index e1844f3..9d05e54 100644 (file)
@@ -28,6 +28,7 @@ DEFINE_bool(initial_symbols, true,
             " FST in archive.");
 
 int farcompilestrings_main(int argc, char **argv);
+
 int main(int argc, char **argv) {
   return farcompilestrings_main(argc, argv);
 }
index 493abbd..9b399cf 100644 (file)
@@ -29,35 +29,35 @@ int farcreate_main(int argc, char **argv) {
   SET_FLAGS(usage.c_str(), &argc, &argv, true);
   s::ExpandArgs(argc, argv, &argc, &argv);
 
-  std::vector<std::string> in_fnames;
+  std::vector<std::string> in_sources;
   if (FLAGS_file_list_input) {
     for (int i = 1; i < argc - 1; ++i) {
       std::ifstream istrm(argv[i]);
       std::string str;
-      while (getline(istrm, str)) in_fnames.push_back(str);
+      while (getline(istrm, str)) in_sources.push_back(str);
     }
   } else {
     for (int i = 1; i < argc - 1; ++i)
-      in_fnames.push_back(strcmp(argv[i], "-") != 0 ? argv[i] : "");
+      in_sources.push_back(strcmp(argv[i], "-") != 0 ? argv[i] : "");
   }
-  if (in_fnames.empty()) {
+  if (in_sources.empty()) {
     // argc == 1 || argc == 2.  This cleverly handles both the no-file case
     // and the one (input) file case together.
     // TODO(jrosenstock): This probably shouldn't happen for the
     // --file_list_input case.
-    in_fnames.push_back(argc == 2 && strcmp(argv[1], "-") != 0 ? argv[1] : "");
+    in_sources.push_back(argc == 2 && strcmp(argv[1], "-") != 0 ? argv[1] : "");
   }
 
   // argc <= 2 means the file (if any) is an input file, so write to stdout.
-  const std::string out_fname =
+  const std::string out_source =
       argc > 2 && strcmp(argv[argc - 1], "-") != 0 ? argv[argc - 1] : "";
 
-  const auto arc_type = s::LoadArcTypeFromFst(in_fnames[0]);
+  const auto arc_type = s::LoadArcTypeFromFst(in_sources[0]);
   if (arc_type.empty()) return 1;
 
   const auto far_type = s::GetFarType(FLAGS_far_type);
 
-  s::FarCreate(in_fnames, out_fname, arc_type, FLAGS_generate_keys, far_type,
+  s::FarCreate(in_sources, out_source, arc_type, FLAGS_generate_keys, far_type,
                FLAGS_key_prefix, FLAGS_key_suffix);
 
   return 0;
index 1d04be3..c20cebd 100644 (file)
@@ -11,6 +11,7 @@ DEFINE_bool(file_list_input, false,
             "Each input file contains a list of files to be processed");
 
 int farcreate_main(int argc, char **argv);
+
 int main(int argc, char **argv) {
   return farcreate_main(argc, argv);
 }
index 4890f87..69d5853 100644 (file)
@@ -7,6 +7,7 @@ DEFINE_string(end_key, "", "Last key to extract (def: last key in archive)");
 DEFINE_double(delta, fst::kDelta, "Comparison/quantization delta");
 
 int farequal_main(int argc, char **argv);
+
 int main(int argc, char **argv) {
   return farequal_main(argc, argv);
 }
index 78e6a06..01778bf 100644 (file)
@@ -28,14 +28,14 @@ int farextract_main(int argc, char **argv) {
   SET_FLAGS(usage.c_str(), &argc, &argv, true);
   s::ExpandArgs(argc, argv, &argc, &argv);
 
-  std::vector<std::string> in_fnames;
-  for (int i = 1; i < argc; ++i) in_fnames.push_back(argv[i]);
-  if (in_fnames.empty()) in_fnames.push_back("");
+  std::vector<std::string> in_sources;
+  for (int i = 1; i < argc; ++i) in_sources.push_back(argv[i]);
+  if (in_sources.empty()) in_sources.push_back("");
 
-  const auto arc_type = s::LoadArcTypeFromFar(in_fnames[0]);
+  const auto arc_type = s::LoadArcTypeFromFar(in_sources[0]);
   if (arc_type.empty()) return 1;
 
-  s::FarExtract(in_fnames, arc_type, FLAGS_generate_filenames, FLAGS_keys,
+  s::FarExtract(in_sources, arc_type, FLAGS_generate_filenames, FLAGS_keys,
                 FLAGS_key_separator, FLAGS_range_delimiter,
                 FLAGS_filename_prefix, FLAGS_filename_suffix);
 
index b31d51a..839f623 100644 (file)
@@ -11,6 +11,7 @@ DEFINE_string(key_separator, ",", "Separator for individual keys");
 DEFINE_string(range_delimiter, "-", "Delimiter for ranges of keys");
 
 int farextract_main(int argc, char **argv);
+
 int main(int argc, char **argv) {
   return farextract_main(argc, argv);
 }
index 687a0cf..3c39366 100644 (file)
@@ -27,14 +27,14 @@ int farinfo_main(int argc, char **argv) {
   SET_FLAGS(usage.c_str(), &argc, &argv, true);
   s::ExpandArgs(argc, argv, &argc, &argv);
 
-  std::vector<std::string> in_fnames;
-  for (int i = 1; i < argc; ++i) in_fnames.push_back(argv[i]);
-  if (in_fnames.empty()) in_fnames.push_back("");
+  std::vector<std::string> in_sources;
+  for (int i = 1; i < argc; ++i) in_sources.push_back(argv[i]);
+  if (in_sources.empty()) in_sources.push_back("");
 
-  const auto arc_type = s::LoadArcTypeFromFar(in_fnames[0]);
+  const auto arc_type = s::LoadArcTypeFromFar(in_sources[0]);
   if (arc_type.empty()) return 1;
 
-  s::FarInfo(in_fnames, arc_type, FLAGS_begin_key, FLAGS_end_key,
+  s::FarInfo(in_sources, arc_type, FLAGS_begin_key, FLAGS_end_key,
              FLAGS_list_fsts);
 
   return 0;
index 3029685..ab67cf7 100644 (file)
@@ -8,6 +8,7 @@ DEFINE_string(end_key, "",
 DEFINE_bool(list_fsts, false, "Display FST information for each key");
 
 int farinfo_main(int argc, char **argv);
+
 int main(int argc, char **argv) {
   return farinfo_main(argc, argv);
 }
index 1ca9263..5ea4118 100644 (file)
@@ -7,6 +7,7 @@ DEFINE_string(end_key, "", "Last key to extract (def: last key in archive)");
 DEFINE_double(delta, fst::kDelta, "Comparison/quantization delta");
 
 int farisomorphic_main(int argc, char **argv);
+
 int main(int argc, char **argv) {
   return farisomorphic_main(argc, argv);
 }
index 6c1d9f4..37feb6c 100644 (file)
@@ -34,11 +34,11 @@ int farprintstrings_main(int argc, char **argv) {
   SET_FLAGS(usage.c_str(), &argc, &argv, true);
   s::ExpandArgs(argc, argv, &argc, &argv);
 
-  std::vector<std::string> in_fnames;
-  for (int i = 1; i < argc; ++i) in_fnames.push_back(argv[i]);
-  if (in_fnames.empty()) in_fnames.push_back("");
+  std::vector<std::string> in_sources;
+  for (int i = 1; i < argc; ++i) in_sources.push_back(argv[i]);
+  if (in_sources.empty()) in_sources.push_back("");
 
-  const auto arc_type = s::LoadArcTypeFromFar(in_fnames[0]);
+  const auto arc_type = s::LoadArcTypeFromFar(in_sources[0]);
   if (arc_type.empty()) return 1;
 
   fst::FarEntryType entry_type;
@@ -53,7 +53,7 @@ int farprintstrings_main(int argc, char **argv) {
     return 1;
   }
 
-  s::FarPrintStrings(in_fnames, arc_type, entry_type, token_type,
+  s::FarPrintStrings(in_sources, arc_type, entry_type, token_type,
                      FLAGS_begin_key, FLAGS_end_key, FLAGS_print_key,
                      FLAGS_print_weight, FLAGS_symbols, FLAGS_initial_symbols,
                      FLAGS_generate_filenames, FLAGS_filename_prefix,
index 05f42e8..27db6d4 100644 (file)
@@ -21,6 +21,7 @@ DEFINE_bool(initial_symbols, true,
             "Uses symbol table from the first Fst in archive for all entries.");
 
 int farprintstrings_main(int argc, char **argv);
+
 int main(int argc, char **argv) {
   return farprintstrings_main(argc, argv);
 }
index 1783085..07819c8 100644 (file)
 namespace fst {
 namespace script {
 
-void FarCompileStrings(const std::vector<std::string> &in_fnames,
-                       const std::string &out_fname,
+void FarCompileStrings(const std::vector<std::string> &in_sources,
+                       const std::string &out_source,
                        const std::string &arc_type, const std::string &fst_type,
                        const FarType &far_type, int32 generate_keys,
                        FarEntryType fet, FarTokenType tt,
-                       const std::string &symbols_fname,
+                       const std::string &symbols_source,
                        const std::string &unknown_symbol, bool keep_symbols,
                        bool initial_symbols, bool allow_negative_labels,
                        const std::string &key_prefix,
                        const std::string &key_suffix) {
-  FarCompileStringsArgs args(in_fnames, out_fname, fst_type, far_type,
-                             generate_keys, fet, tt, symbols_fname,
+  FarCompileStringsArgs args(in_sources, out_source, fst_type, far_type,
+                             generate_keys, fet, tt, symbols_source,
                              unknown_symbol, keep_symbols, initial_symbols,
                              allow_negative_labels, key_prefix, key_suffix);
   Apply<Operation<FarCompileStringsArgs>>("FarCompileStrings", arc_type, &args);
 }
 
-void FarCreate(const std::vector<std::string> &in_fnames,
-               const std::string &out_fname, const std::string &arc_type,
+REGISTER_FST_OPERATION_3ARCS(FarCompileStrings, FarCompileStringsArgs);
+
+void FarCreate(const std::vector<std::string> &in_sources,
+               const std::string &out_source, const std::string &arc_type,
                const int32 generate_keys, const FarType &far_type,
                const std::string &key_prefix, const std::string &key_suffix) {
-  FarCreateArgs args(in_fnames, out_fname, generate_keys, far_type, key_prefix,
-                     key_suffix);
+  FarCreateArgs args(in_sources, out_source, generate_keys, far_type,
+                     key_prefix, key_suffix);
   Apply<Operation<FarCreateArgs>>("FarCreate", arc_type, &args);
 }
 
-bool FarEqual(const std::string &filename1, const std::string &filename2,
+REGISTER_FST_OPERATION_3ARCS(FarCreate, FarCreateArgs);
+
+bool FarEqual(const std::string &source1, const std::string &source2,
               const std::string &arc_type, float delta,
               const std::string &begin_key, const std::string &end_key) {
-  FarEqualInnerArgs args(filename1, filename2, delta, begin_key, end_key);
+  FarEqualInnerArgs args(source1, source2, delta, begin_key, end_key);
   FarEqualArgs args_with_retval(args);
   Apply<Operation<FarEqualArgs>>("FarEqual", arc_type, &args_with_retval);
   return args_with_retval.retval;
 }
 
-void FarExtract(const std::vector<std::string> &ifilenames,
-                const std::string &arc_type, int32 generate_filenames,
+REGISTER_FST_OPERATION_3ARCS(FarEqual, FarEqualArgs);
+
+void FarExtract(const std::vector<std::string> &isources,
+                const std::string &arc_type, int32 generate_sources,
                 const std::string &keys, const std::string &key_separator,
                 const std::string &range_delimiter,
-                const std::string &filename_prefix,
-                const std::string &filename_suffix) {
-  FarExtractArgs args(ifilenames, generate_filenames, keys, key_separator,
-                      range_delimiter, filename_prefix, filename_suffix);
+                const std::string &source_prefix,
+                const std::string &source_suffix) {
+  FarExtractArgs args(isources, generate_sources, keys, key_separator,
+                      range_delimiter, source_prefix, source_suffix);
   Apply<Operation<FarExtractArgs>>("FarExtract", arc_type, &args);
 }
 
-void FarInfo(const std::vector<std::string> &filenames,
+REGISTER_FST_OPERATION_3ARCS(FarExtract, FarExtractArgs);
+
+void FarInfo(const std::vector<std::string> &sources,
              const std::string &arc_type, const std::string &begin_key,
-             const std::string &end_key, const bool list_fsts) {
-  FarInfoArgs args(filenames, begin_key, end_key, list_fsts);
+             const std::string &end_key, bool list_fsts) {
+  FarInfoArgs args(sources, begin_key, end_key, list_fsts);
   Apply<Operation<FarInfoArgs>>("FarInfo", arc_type, &args);
 }
 
-void GetFarInfo(const std::vector<std::string> &filenames,
+REGISTER_FST_OPERATION_3ARCS(FarInfo, FarInfoArgs);
+
+void GetFarInfo(const std::vector<std::string> &sources,
                 const std::string &arc_type, const std::string &begin_key,
-                const std::string &end_key, const bool list_fsts,
-                FarInfoData *data) {
-  GetFarInfoArgs args(filenames, begin_key, end_key, list_fsts, data);
+                const std::string &end_key, bool list_fsts, FarInfoData *data) {
+  GetFarInfoArgs args(sources, begin_key, end_key, list_fsts, data);
   Apply<Operation<GetFarInfoArgs>>("GetFarInfo", arc_type, &args);
 }
 
-bool FarIsomorphic(const std::string &filename1, const std::string &filename2,
+REGISTER_FST_OPERATION_3ARCS(GetFarInfo, GetFarInfoArgs);
+
+bool FarIsomorphic(const std::string &source1, const std::string &source2,
                    const std::string &arc_type, float delta,
                    const std::string &begin_key, const std::string &end_key) {
-  FarIsomorphicInnerArgs args(filename1, filename2, delta, begin_key, end_key);
+  FarIsomorphicInnerArgs args(source1, source2, delta, begin_key, end_key);
   FarIsomorphicArgs args_with_retval(args);
   Apply<Operation<FarIsomorphicArgs>>("FarIsomorphic", arc_type,
                                       &args_with_retval);
   return args_with_retval.retval;
 }
 
-void FarPrintStrings(const std::vector<std::string> &ifilenames,
+REGISTER_FST_OPERATION_3ARCS(FarIsomorphic, FarIsomorphicArgs);
+
+void FarPrintStrings(const std::vector<std::string> &isources,
                      const std::string &arc_type, const FarEntryType entry_type,
                      const FarTokenType token_type,
                      const std::string &begin_key, const std::string &end_key,
-                     const bool print_key, const bool print_weight,
-                     const std::string &symbols_fname,
-                     const bool initial_symbols, const int32 generate_filenames,
-                     const std::string &filename_prefix,
-                     const std::string &filename_suffix) {
-  FarPrintStringsArgs args(ifilenames, entry_type, token_type, begin_key,
-                           end_key, print_key, print_weight, symbols_fname,
-                           initial_symbols, generate_filenames, filename_prefix,
-                           filename_suffix);
+                     bool print_key, bool print_weight,
+                     const std::string &symbols_source, bool initial_symbols,
+                     const int32 generate_sources,
+                     const std::string &source_prefix,
+                     const std::string &source_suffix) {
+  FarPrintStringsArgs args(isources, entry_type, token_type, begin_key, end_key,
+                           print_key, print_weight, symbols_source,
+                           initial_symbols, generate_sources, source_prefix,
+                           source_suffix);
   Apply<Operation<FarPrintStringsArgs>>("FarPrintStrings", arc_type, &args);
 }
 
-// Instantiate all templates for common arc types.
-
-REGISTER_FST_FAR_OPERATIONS(StdArc);
-REGISTER_FST_FAR_OPERATIONS(LogArc);
-REGISTER_FST_FAR_OPERATIONS(Log64Arc);
+REGISTER_FST_OPERATION_3ARCS(FarPrintStrings, FarPrintStringsArgs);
 
 }  // namespace script
 }  // namespace fst
index 4882dfc..27d49b6 100644 (file)
 namespace fst {
 namespace script {
 
-std::string LoadArcTypeFromFar(const std::string &far_fname) {
+std::string LoadArcTypeFromFar(const std::string &far_source) {
   FarHeader hdr;
-  if (!hdr.Read(far_fname)) {
-    LOG(ERROR) << "Error reading FAR: " << far_fname;
+  if (!hdr.Read(far_source)) {
+    LOG(ERROR) << "Error reading FAR: " << far_source;
     return "";
   }
   std::string atype = hdr.ArcType();
   if (atype == "unknown") {
-    LOG(ERROR) << "Empty FST archive: " << far_fname;
+    LOG(ERROR) << "Empty FST archive: " << far_source;
     return "";
   }
   return atype;
 }
 
-std::string LoadArcTypeFromFst(const std::string &fst_fname) {
+std::string LoadArcTypeFromFst(const std::string &fst_source) {
   FstHeader hdr;
-  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;
+  std::ifstream in(fst_source, std::ios_base::in | std::ios_base::binary);
+  if (!hdr.Read(in, fst_source)) {
+    LOG(ERROR) << "Error reading FST: " << fst_source;
     return "";
   }
   return hdr.ArcType();
index d7c9d72..ff406da 100644 (file)
@@ -8,8 +8,8 @@
 
 namespace fst {
 
-bool IsSTList(const std::string &filename) {
-  std::ifstream strm(filename, std::ios_base::in | std::ios_base::binary);
+bool IsSTList(const std::string &source) {
+  std::ifstream strm(source, std::ios_base::in | std::ios_base::binary);
   if (!strm) return false;
   int32 magic_number = 0;
   ReadType(strm, &magic_number);
index 8e68153..ac4740b 100644 (file)
@@ -16,10 +16,11 @@ namespace fst {
 // Computes the minimal length required to encode each line number as a decimal
 // number, or zero if the number of lines could not be determined because the
 // file was not seekable.
-int KeySize(const char *filename) {
-  std::ifstream istrm(filename);
+int KeySize(const char *source) {
+  std::ifstream istrm(source);
   istrm.seekg(0);
-  // TODO(jrosenstock): Change this to is_regular_file when we can use C++17.
+  // TODO(jrosenstock): Change this to is_regular_file when <filesystem> is
+  // no longer banned.
   // Stream not seekable. This is really a hack to approximate is_regular_file.
   // What we really want is that opening and reading the file twice gives the
   // same result, which is only true for regular files. There may be devices
index e08b8d6..950a680 100644 (file)
@@ -6,8 +6,8 @@
 
 namespace fst {
 
-bool IsSTTable(const std::string &filename) {
-  std::ifstream strm(filename);
+bool IsSTTable(const std::string &source) {
+  std::ifstream strm(source);
   if (!strm.good()) return false;
 
   int32 magic_number = 0;
index 8737dde..27b3c56 100644 (file)
@@ -1,35 +1,30 @@
 AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
+LIBS = ../../lib/libfst.la -lm $(DL_LIBS)
 
 if HAVE_BIN
 bin_PROGRAMS = fstlinear fstloglinearapply
 
-LDADD = libfstlinearscript.la ../../script/libfstscript.la \
-    ../../lib/libfst.la -lm $(DL_LIBS)
-
 fstlinear_SOURCES = fstlinear.cc fstlinear-main.cc
+fstlinear_LDADD = libfstlinearscript.la ../../script/libfstscript.la
 
 fstloglinearapply_SOURCES = fstloglinearapply.cc fstloglinearapply-main.cc
+fstloglinearapply_LDADD = libfstlinearscript.la ../../script/libfstscript.la
 endif
 
 if HAVE_SCRIPT
+lib_LTLIBRARIES = libfstlinearscript.la
+
 libfstlinearscript_la_SOURCES = linearscript.cc
-libfstlinearscript_la_LDFLAGS = -version-info 17:0:0 -lm $(DL_LIBS)
-libfstlinearscript_la_LIBADD = ../../script/libfstscript.la \
-                               ../../lib/libfst.la -lm $(DL_LIBS)
+libfstlinearscript_la_LDFLAGS = -version-info 17:0:0
+libfstlinearscript_la_LIBADD = ../../script/libfstscript.la
 endif
 
-if HAVE_SCRIPT
-libfst_LTLIBRARIES = linear_tagger-fst.la \
-    linear_classifier-fst.la
-lib_LTLIBRARIES = libfstlinearscript.la
-else
 libfst_LTLIBRARIES = linear_tagger-fst.la linear_classifier-fst.la
-endif
 
 libfstdir = @libfstdir@
 
 linear_tagger_fst_la_SOURCES = linear-tagger-fst.cc
-linear_tagger_fst_la_LDFLAGS = -module
+linear_tagger_fst_la_LDFLAGS = -avoid-version -module
 
 linear_classifier_fst_la_SOURCES = linear-classifier-fst.cc
-linear_classifier_fst_la_LDFLAGS = -module
+linear_classifier_fst_la_LDFLAGS = -avoid-version -module
index 4297313..7fd8656 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -93,7 +93,7 @@ host_triplet = @host@
 @HAVE_BIN_TRUE@        fstloglinearapply$(EXEEXT)
 subdir = src/extensions/linear
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_python_devel.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
        $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
@@ -105,6 +105,9 @@ CONFIG_HEADER = $(top_builddir)/config.h \
        $(top_builddir)/src/include/fst/config.h
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)" \
+       "$(DESTDIR)$(libfstdir)"
+PROGRAMS = $(bin_PROGRAMS)
 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
 am__vpath_adj = case $$p in \
     $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
@@ -132,13 +135,9 @@ am__uninstall_files_from_dir = { \
     || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
          $(am__cd) "$$dir" && rm -f $$files; }; \
   }
-am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libfstdir)" \
-       "$(DESTDIR)$(bindir)"
 LTLIBRARIES = $(lib_LTLIBRARIES) $(libfst_LTLIBRARIES)
-am__DEPENDENCIES_1 =
 @HAVE_SCRIPT_TRUE@libfstlinearscript_la_DEPENDENCIES =  \
-@HAVE_SCRIPT_TRUE@     ../../script/libfstscript.la \
-@HAVE_SCRIPT_TRUE@     ../../lib/libfst.la $(am__DEPENDENCIES_1)
+@HAVE_SCRIPT_TRUE@     ../../script/libfstscript.la
 am__libfstlinearscript_la_SOURCES_DIST = linearscript.cc
 @HAVE_SCRIPT_TRUE@am_libfstlinearscript_la_OBJECTS = linearscript.lo
 libfstlinearscript_la_OBJECTS = $(am_libfstlinearscript_la_OBJECTS)
@@ -159,10 +158,6 @@ linear_classifier_fst_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
        $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
        $(AM_CXXFLAGS) $(CXXFLAGS) $(linear_classifier_fst_la_LDFLAGS) \
        $(LDFLAGS) -o $@
-@HAVE_SCRIPT_FALSE@am_linear_classifier_fst_la_rpath = -rpath \
-@HAVE_SCRIPT_FALSE@    $(libfstdir)
-@HAVE_SCRIPT_TRUE@am_linear_classifier_fst_la_rpath = -rpath \
-@HAVE_SCRIPT_TRUE@     $(libfstdir)
 linear_tagger_fst_la_LIBADD =
 am_linear_tagger_fst_la_OBJECTS = linear-tagger-fst.lo
 linear_tagger_fst_la_OBJECTS = $(am_linear_tagger_fst_la_OBJECTS)
@@ -170,27 +165,20 @@ linear_tagger_fst_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
        $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
        $(AM_CXXFLAGS) $(CXXFLAGS) $(linear_tagger_fst_la_LDFLAGS) \
        $(LDFLAGS) -o $@
-@HAVE_SCRIPT_FALSE@am_linear_tagger_fst_la_rpath = -rpath $(libfstdir)
-@HAVE_SCRIPT_TRUE@am_linear_tagger_fst_la_rpath = -rpath $(libfstdir)
-PROGRAMS = $(bin_PROGRAMS)
 am__fstlinear_SOURCES_DIST = fstlinear.cc fstlinear-main.cc
 @HAVE_BIN_TRUE@am_fstlinear_OBJECTS = fstlinear.$(OBJEXT) \
 @HAVE_BIN_TRUE@        fstlinear-main.$(OBJEXT)
 fstlinear_OBJECTS = $(am_fstlinear_OBJECTS)
-fstlinear_LDADD = $(LDADD)
 @HAVE_BIN_TRUE@fstlinear_DEPENDENCIES = libfstlinearscript.la \
-@HAVE_BIN_TRUE@        ../../script/libfstscript.la \
-@HAVE_BIN_TRUE@        ../../lib/libfst.la $(am__DEPENDENCIES_1)
+@HAVE_BIN_TRUE@        ../../script/libfstscript.la
 am__fstloglinearapply_SOURCES_DIST = fstloglinearapply.cc \
        fstloglinearapply-main.cc
 @HAVE_BIN_TRUE@am_fstloglinearapply_OBJECTS =  \
 @HAVE_BIN_TRUE@        fstloglinearapply.$(OBJEXT) \
 @HAVE_BIN_TRUE@        fstloglinearapply-main.$(OBJEXT)
 fstloglinearapply_OBJECTS = $(am_fstloglinearapply_OBJECTS)
-fstloglinearapply_LDADD = $(LDADD)
 @HAVE_BIN_TRUE@fstloglinearapply_DEPENDENCIES = libfstlinearscript.la \
-@HAVE_BIN_TRUE@        ../../script/libfstscript.la \
-@HAVE_BIN_TRUE@        ../../lib/libfst.la $(am__DEPENDENCIES_1)
+@HAVE_BIN_TRUE@        ../../script/libfstscript.la
 AM_V_P = $(am__v_P_@AM_V@)
 am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
 am__v_P_0 = false
@@ -205,7 +193,12 @@ am__v_at_0 = @
 am__v_at_1 = 
 DEFAULT_INCLUDES = 
 depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/fstlinear-main.Po \
+       ./$(DEPDIR)/fstlinear.Po ./$(DEPDIR)/fstloglinearapply-main.Po \
+       ./$(DEPDIR)/fstloglinearapply.Po \
+       ./$(DEPDIR)/linear-classifier-fst.Plo \
+       ./$(DEPDIR)/linear-tagger-fst.Plo ./$(DEPDIR)/linearscript.Plo
 am__mv = mv -f
 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
        $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
@@ -298,7 +291,7 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
+LIBS = ../../lib/libfst.la -lm $(DL_LIBS)
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -326,7 +319,7 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
@@ -397,25 +390,19 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
-@HAVE_BIN_TRUE@LDADD = libfstlinearscript.la ../../script/libfstscript.la \
-@HAVE_BIN_TRUE@    ../../lib/libfst.la -lm $(DL_LIBS)
-
 @HAVE_BIN_TRUE@fstlinear_SOURCES = fstlinear.cc fstlinear-main.cc
+@HAVE_BIN_TRUE@fstlinear_LDADD = libfstlinearscript.la ../../script/libfstscript.la
 @HAVE_BIN_TRUE@fstloglinearapply_SOURCES = fstloglinearapply.cc fstloglinearapply-main.cc
-@HAVE_SCRIPT_TRUE@libfstlinearscript_la_SOURCES = linearscript.cc
-@HAVE_SCRIPT_TRUE@libfstlinearscript_la_LDFLAGS = -version-info 17:0:0 -lm $(DL_LIBS)
-@HAVE_SCRIPT_TRUE@libfstlinearscript_la_LIBADD = ../../script/libfstscript.la \
-@HAVE_SCRIPT_TRUE@                               ../../lib/libfst.la -lm $(DL_LIBS)
-
-@HAVE_SCRIPT_FALSE@libfst_LTLIBRARIES = linear_tagger-fst.la linear_classifier-fst.la
-@HAVE_SCRIPT_TRUE@libfst_LTLIBRARIES = linear_tagger-fst.la \
-@HAVE_SCRIPT_TRUE@    linear_classifier-fst.la
-
+@HAVE_BIN_TRUE@fstloglinearapply_LDADD = libfstlinearscript.la ../../script/libfstscript.la
 @HAVE_SCRIPT_TRUE@lib_LTLIBRARIES = libfstlinearscript.la
+@HAVE_SCRIPT_TRUE@libfstlinearscript_la_SOURCES = linearscript.cc
+@HAVE_SCRIPT_TRUE@libfstlinearscript_la_LDFLAGS = -version-info 17:0:0
+@HAVE_SCRIPT_TRUE@libfstlinearscript_la_LIBADD = ../../script/libfstscript.la
+libfst_LTLIBRARIES = linear_tagger-fst.la linear_classifier-fst.la
 linear_tagger_fst_la_SOURCES = linear-tagger-fst.cc
-linear_tagger_fst_la_LDFLAGS = -module
+linear_tagger_fst_la_LDFLAGS = -avoid-version -module
 linear_classifier_fst_la_SOURCES = linear-classifier-fst.cc
-linear_classifier_fst_la_LDFLAGS = -module
+linear_classifier_fst_la_LDFLAGS = -avoid-version -module
 all: all-am
 
 .SUFFIXES:
@@ -437,8 +424,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
          *config.status*) \
            cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
          *) \
-           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
        esac;
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@@ -449,6 +436,55 @@ $(top_srcdir)/configure:  $(am__configure_deps)
 $(ACLOCAL_M4):  $(am__aclocal_m4_deps)
        cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 $(am__aclocal_m4_deps):
+install-binPROGRAMS: $(bin_PROGRAMS)
+       @$(NORMAL_INSTALL)
+       @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+       if test -n "$$list"; then \
+         echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+         $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+       fi; \
+       for p in $$list; do echo "$$p $$p"; done | \
+       sed 's/$(EXEEXT)$$//' | \
+       while read p p1; do if test -f $$p \
+        || test -f $$p1 \
+         ; then echo "$$p"; echo "$$p"; else :; fi; \
+       done | \
+       sed -e 'p;s,.*/,,;n;h' \
+           -e 's|.*|.|' \
+           -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+       sed 'N;N;N;s,\n, ,g' | \
+       $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+         { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+           if ($$2 == $$4) files[d] = files[d] " " $$1; \
+           else { print "f", $$3 "/" $$4, $$1; } } \
+         END { for (d in files) print "f", d, files[d] }' | \
+       while read type dir files; do \
+           if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+           test -z "$$files" || { \
+           echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+           $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+           } \
+       ; done
+
+uninstall-binPROGRAMS:
+       @$(NORMAL_UNINSTALL)
+       @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+       files=`for p in $$list; do echo "$$p"; done | \
+         sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+             -e 's/$$/$(EXEEXT)/' \
+       `; \
+       test -n "$$list" || exit 0; \
+       echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+       cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+       @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
+       echo " rm -f" $$list; \
+       rm -f $$list || exit $$?; \
+       test -n "$(EXEEXT)" || exit 0; \
+       list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+       echo " rm -f" $$list; \
+       rm -f $$list
 
 install-libLTLIBRARIES: $(lib_LTLIBRARIES)
        @$(NORMAL_INSTALL)
@@ -524,59 +560,10 @@ libfstlinearscript.la: $(libfstlinearscript_la_OBJECTS) $(libfstlinearscript_la_
        $(AM_V_CXXLD)$(libfstlinearscript_la_LINK) $(am_libfstlinearscript_la_rpath) $(libfstlinearscript_la_OBJECTS) $(libfstlinearscript_la_LIBADD) $(LIBS)
 
 linear_classifier-fst.la: $(linear_classifier_fst_la_OBJECTS) $(linear_classifier_fst_la_DEPENDENCIES) $(EXTRA_linear_classifier_fst_la_DEPENDENCIES) 
-       $(AM_V_CXXLD)$(linear_classifier_fst_la_LINK) $(am_linear_classifier_fst_la_rpath) $(linear_classifier_fst_la_OBJECTS) $(linear_classifier_fst_la_LIBADD) $(LIBS)
+       $(AM_V_CXXLD)$(linear_classifier_fst_la_LINK) -rpath $(libfstdir) $(linear_classifier_fst_la_OBJECTS) $(linear_classifier_fst_la_LIBADD) $(LIBS)
 
 linear_tagger-fst.la: $(linear_tagger_fst_la_OBJECTS) $(linear_tagger_fst_la_DEPENDENCIES) $(EXTRA_linear_tagger_fst_la_DEPENDENCIES) 
-       $(AM_V_CXXLD)$(linear_tagger_fst_la_LINK) $(am_linear_tagger_fst_la_rpath) $(linear_tagger_fst_la_OBJECTS) $(linear_tagger_fst_la_LIBADD) $(LIBS)
-install-binPROGRAMS: $(bin_PROGRAMS)
-       @$(NORMAL_INSTALL)
-       @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
-       if test -n "$$list"; then \
-         echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
-         $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
-       fi; \
-       for p in $$list; do echo "$$p $$p"; done | \
-       sed 's/$(EXEEXT)$$//' | \
-       while read p p1; do if test -f $$p \
-        || test -f $$p1 \
-         ; then echo "$$p"; echo "$$p"; else :; fi; \
-       done | \
-       sed -e 'p;s,.*/,,;n;h' \
-           -e 's|.*|.|' \
-           -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
-       sed 'N;N;N;s,\n, ,g' | \
-       $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
-         { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
-           if ($$2 == $$4) files[d] = files[d] " " $$1; \
-           else { print "f", $$3 "/" $$4, $$1; } } \
-         END { for (d in files) print "f", d, files[d] }' | \
-       while read type dir files; do \
-           if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
-           test -z "$$files" || { \
-           echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
-           $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
-           } \
-       ; done
-
-uninstall-binPROGRAMS:
-       @$(NORMAL_UNINSTALL)
-       @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
-       files=`for p in $$list; do echo "$$p"; done | \
-         sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
-             -e 's/$$/$(EXEEXT)/' \
-       `; \
-       test -n "$$list" || exit 0; \
-       echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
-       cd "$(DESTDIR)$(bindir)" && rm -f $$files
-
-clean-binPROGRAMS:
-       @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
-       echo " rm -f" $$list; \
-       rm -f $$list || exit $$?; \
-       test -n "$(EXEEXT)" || exit 0; \
-       list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
-       echo " rm -f" $$list; \
-       rm -f $$list
+       $(AM_V_CXXLD)$(linear_tagger_fst_la_LINK) -rpath $(libfstdir) $(linear_tagger_fst_la_OBJECTS) $(linear_tagger_fst_la_LIBADD) $(LIBS)
 
 fstlinear$(EXEEXT): $(fstlinear_OBJECTS) $(fstlinear_DEPENDENCIES) $(EXTRA_fstlinear_DEPENDENCIES) 
        @rm -f fstlinear$(EXEEXT)
@@ -592,13 +579,19 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstlinear-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstlinear.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstloglinearapply-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstloglinearapply.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linear-classifier-fst.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linear-tagger-fst.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linearscript.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstlinear-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstlinear.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstloglinearapply-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstloglinearapply.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linear-classifier-fst.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linear-tagger-fst.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linearscript.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+       @$(MKDIR_P) $(@D)
+       @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
 
 .cc.o:
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -682,7 +675,10 @@ cscopelist-am: $(am__tagged_files)
 distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
-distdir: $(DISTFILES)
+distdir: $(BUILT_SOURCES)
+       $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
        @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        list='$(DISTFILES)'; \
@@ -714,11 +710,11 @@ distdir: $(DISTFILES)
        done
 check-am: all-am
 check: check-am
-all-am: Makefile $(LTLIBRARIES) $(PROGRAMS)
+all-am: Makefile $(PROGRAMS) $(LTLIBRARIES)
 install-binPROGRAMS: install-libLTLIBRARIES
 
 installdirs:
-       for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libfstdir)" "$(DESTDIR)$(bindir)"; do \
+       for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libfstdir)"; do \
          test -z "$$dir" || $(MKDIR_P) "$$dir"; \
        done
 install: install-am
@@ -757,7 +753,13 @@ clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
        clean-libfstLTLIBRARIES clean-libtool mostlyclean-am
 
 distclean: distclean-am
-       -rm -rf ./$(DEPDIR)
+               -rm -f ./$(DEPDIR)/fstlinear-main.Po
+       -rm -f ./$(DEPDIR)/fstlinear.Po
+       -rm -f ./$(DEPDIR)/fstloglinearapply-main.Po
+       -rm -f ./$(DEPDIR)/fstloglinearapply.Po
+       -rm -f ./$(DEPDIR)/linear-classifier-fst.Plo
+       -rm -f ./$(DEPDIR)/linear-tagger-fst.Plo
+       -rm -f ./$(DEPDIR)/linearscript.Plo
        -rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
        distclean-tags
@@ -803,7 +805,13 @@ install-ps-am:
 installcheck-am:
 
 maintainer-clean: maintainer-clean-am
-       -rm -rf ./$(DEPDIR)
+               -rm -f ./$(DEPDIR)/fstlinear-main.Po
+       -rm -f ./$(DEPDIR)/fstlinear.Po
+       -rm -f ./$(DEPDIR)/fstloglinearapply-main.Po
+       -rm -f ./$(DEPDIR)/fstloglinearapply.Po
+       -rm -f ./$(DEPDIR)/linear-classifier-fst.Plo
+       -rm -f ./$(DEPDIR)/linear-tagger-fst.Plo
+       -rm -f ./$(DEPDIR)/linearscript.Plo
        -rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
@@ -825,7 +833,7 @@ uninstall-am: uninstall-binPROGRAMS uninstall-libLTLIBRARIES \
 
 .MAKE: install-am install-strip
 
-.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
        clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
        clean-libfstLTLIBRARIES clean-libtool cscopelist-am ctags \
        ctags-am distclean distclean-compile distclean-generic \
index 3e7ccc8..ac85cb4 100644 (file)
@@ -1,9 +1,8 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/extensions/linear/linearscript.h>
-
 #include <fst/flags.h>
+#include <fst/extensions/linear/linearscript.h>
 
 DECLARE_string(arc_type);
 DECLARE_string(epsilon_symbol);
index 4d39e13..58f8dca 100644 (file)
@@ -1,13 +1,12 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
+#include <fst/flags.h>
+#include <fst/log.h>
 #include <fst/extensions/linear/linear-fst.h>
 #include <fst/extensions/linear/loglinear-apply.h>
 #include <fst/vector-fst.h>
 
-#include <fst/flags.h>
-#include <fst/log.h>
-
 DECLARE_bool(normalize);
 
 int fstloglinearapply_main(int argc, char **argv) {
index 46c2600..f237c4a 100644 (file)
@@ -1,13 +1,14 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
+#include <fst/compat.h>
+#include <fst/extensions/linear/linearscript.h>
+
 #include <cctype>
 #include <cstdio>
 #include <set>
 
-#include <fst/compat.h>
 #include <fst/flags.h>
-#include <fst/extensions/linear/linearscript.h>
 #include <fst/arc.h>
 #include <fstream>
 #include <fst/script/script-impl.h>
@@ -28,9 +29,7 @@ namespace fst {
 namespace script {
 
 bool ValidateDelimiter() {
-  if (FLAGS_delimiter.size() == 1 && !std::isspace(FLAGS_delimiter[0]))
-    return true;
-  return false;
+  return FLAGS_delimiter.size() == 1 && !std::isspace(FLAGS_delimiter[0]);
 }
 
 bool ValidateEmptySymbol() {
@@ -55,9 +54,7 @@ void LinearCompile(const std::string &arc_type,
   Apply<Operation<LinearCompileArgs>>("LinearCompileTpl", arc_type, &args);
 }
 
-// Instantiate templates for common arc types
-REGISTER_FST_LINEAR_OPERATIONS(StdArc);
-REGISTER_FST_LINEAR_OPERATIONS(LogArc);
+REGISTER_FST_OPERATION_3ARCS(LinearCompileTpl, LinearCompileArgs);
 
 void SplitByWhitespace(const std::string &str, std::vector<std::string> *out) {
   out->clear();
@@ -71,10 +68,8 @@ int ScanNumClasses(char **models, int models_len) {
   for (int i = 0; i < models_len; ++i) {
     std::ifstream in(models[i]);
     if (!in) LOG(FATAL) << "Failed to open " << models[i];
-
     std::string line;
     std::getline(in, line);
-
     size_t num_line = 1;
     while (std::getline(in, line)) {
       ++num_line;
index 3c6e6e4..9372fc8 100644 (file)
@@ -1,4 +1,5 @@
 AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
+LIBS = ../../lib/libfst.la -lm $(DL_LIBS)
 
 libfstdir = @libfstdir@
 libfst_LTLIBRARIES = arc_lookahead-fst.la \
@@ -9,13 +10,12 @@ lib_LTLIBRARIES = libfstlookahead.la
 libfstlookahead_la_SOURCES = arc_lookahead-fst.cc ilabel_lookahead-fst.cc \
                              olabel_lookahead-fst.cc
 libfstlookahead_la_LDFLAGS = -version-info 17:0:0
-libfstlookahead_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
 
 arc_lookahead_fst_la_SOURCES = arc_lookahead-fst.cc
-arc_lookahead_fst_la_LDFLAGS = -module
+arc_lookahead_fst_la_LDFLAGS = -avoid-version -module
 
 ilabel_lookahead_fst_la_SOURCES = ilabel_lookahead-fst.cc
-ilabel_lookahead_fst_la_LDFLAGS = -module
+ilabel_lookahead_fst_la_LDFLAGS = -avoid-version -module
 
 olabel_lookahead_fst_la_SOURCES = olabel_lookahead-fst.cc
-olabel_lookahead_fst_la_LDFLAGS = -module
+olabel_lookahead_fst_la_LDFLAGS = -avoid-version -module
index 20c76c2..122af87 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -90,7 +90,7 @@ build_triplet = @build@
 host_triplet = @host@
 subdir = src/extensions/lookahead
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_python_devel.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
        $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
@@ -150,9 +150,7 @@ ilabel_lookahead_fst_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
        $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
        $(AM_CXXFLAGS) $(CXXFLAGS) $(ilabel_lookahead_fst_la_LDFLAGS) \
        $(LDFLAGS) -o $@
-am__DEPENDENCIES_1 =
-libfstlookahead_la_DEPENDENCIES = ../../lib/libfst.la \
-       $(am__DEPENDENCIES_1)
+libfstlookahead_la_LIBADD =
 am_libfstlookahead_la_OBJECTS = arc_lookahead-fst.lo \
        ilabel_lookahead-fst.lo olabel_lookahead-fst.lo
 libfstlookahead_la_OBJECTS = $(am_libfstlookahead_la_OBJECTS)
@@ -182,7 +180,10 @@ am__v_at_0 = @
 am__v_at_1 = 
 DEFAULT_INCLUDES = 
 depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/arc_lookahead-fst.Plo \
+       ./$(DEPDIR)/ilabel_lookahead-fst.Plo \
+       ./$(DEPDIR)/olabel_lookahead-fst.Plo
 am__mv = mv -f
 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
        $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
@@ -275,7 +276,7 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
+LIBS = ../../lib/libfst.la -lm $(DL_LIBS)
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -303,7 +304,7 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
@@ -382,13 +383,12 @@ libfstlookahead_la_SOURCES = arc_lookahead-fst.cc ilabel_lookahead-fst.cc \
                              olabel_lookahead-fst.cc
 
 libfstlookahead_la_LDFLAGS = -version-info 17:0:0
-libfstlookahead_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
 arc_lookahead_fst_la_SOURCES = arc_lookahead-fst.cc
-arc_lookahead_fst_la_LDFLAGS = -module
+arc_lookahead_fst_la_LDFLAGS = -avoid-version -module
 ilabel_lookahead_fst_la_SOURCES = ilabel_lookahead-fst.cc
-ilabel_lookahead_fst_la_LDFLAGS = -module
+ilabel_lookahead_fst_la_LDFLAGS = -avoid-version -module
 olabel_lookahead_fst_la_SOURCES = olabel_lookahead-fst.cc
-olabel_lookahead_fst_la_LDFLAGS = -module
+olabel_lookahead_fst_la_LDFLAGS = -avoid-version -module
 all: all-am
 
 .SUFFIXES:
@@ -410,8 +410,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
          *config.status*) \
            cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
          *) \
-           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
        esac;
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@@ -511,9 +511,15 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arc_lookahead-fst.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ilabel_lookahead-fst.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/olabel_lookahead-fst.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arc_lookahead-fst.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ilabel_lookahead-fst.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/olabel_lookahead-fst.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+       @$(MKDIR_P) $(@D)
+       @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
 
 .cc.o:
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -597,7 +603,10 @@ cscopelist-am: $(am__tagged_files)
 distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
-distdir: $(DISTFILES)
+distdir: $(BUILT_SOURCES)
+       $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
        @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        list='$(DISTFILES)'; \
@@ -670,7 +679,9 @@ clean-am: clean-generic clean-libLTLIBRARIES clean-libfstLTLIBRARIES \
        clean-libtool mostlyclean-am
 
 distclean: distclean-am
-       -rm -rf ./$(DEPDIR)
+               -rm -f ./$(DEPDIR)/arc_lookahead-fst.Plo
+       -rm -f ./$(DEPDIR)/ilabel_lookahead-fst.Plo
+       -rm -f ./$(DEPDIR)/olabel_lookahead-fst.Plo
        -rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
        distclean-tags
@@ -716,7 +727,9 @@ install-ps-am:
 installcheck-am:
 
 maintainer-clean: maintainer-clean-am
-       -rm -rf ./$(DEPDIR)
+               -rm -f ./$(DEPDIR)/arc_lookahead-fst.Plo
+       -rm -f ./$(DEPDIR)/ilabel_lookahead-fst.Plo
+       -rm -f ./$(DEPDIR)/olabel_lookahead-fst.Plo
        -rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
@@ -737,21 +750,21 @@ uninstall-am: uninstall-libLTLIBRARIES uninstall-libfstLTLIBRARIES
 
 .MAKE: install-am install-strip
 
-.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
-       clean-libLTLIBRARIES clean-libfstLTLIBRARIES clean-libtool \
-       cscopelist-am ctags ctags-am distclean distclean-compile \
-       distclean-generic distclean-libtool distclean-tags distdir dvi \
-       dvi-am html html-am info info-am install install-am \
-       install-data install-data-am install-dvi install-dvi-am \
-       install-exec install-exec-am install-html install-html-am \
-       install-info install-info-am install-libLTLIBRARIES \
-       install-libfstLTLIBRARIES install-man install-pdf \
-       install-pdf-am install-ps install-ps-am install-strip \
-       installcheck installcheck-am installdirs maintainer-clean \
-       maintainer-clean-generic mostlyclean mostlyclean-compile \
-       mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
-       tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES \
-       uninstall-libfstLTLIBRARIES
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
+       clean-generic clean-libLTLIBRARIES clean-libfstLTLIBRARIES \
+       clean-libtool cscopelist-am ctags ctags-am distclean \
+       distclean-compile distclean-generic distclean-libtool \
+       distclean-tags distdir dvi dvi-am html html-am info info-am \
+       install install-am install-data install-data-am install-dvi \
+       install-dvi-am install-exec install-exec-am install-html \
+       install-html-am install-info install-info-am \
+       install-libLTLIBRARIES install-libfstLTLIBRARIES install-man \
+       install-pdf install-pdf-am install-ps install-ps-am \
+       install-strip installcheck installcheck-am installdirs \
+       maintainer-clean maintainer-clean-generic mostlyclean \
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+       pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \
+       uninstall-libLTLIBRARIES uninstall-libfstLTLIBRARIES
 
 .PRECIOUS: Makefile
 
index 4f57440..1fa56bb 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -93,7 +93,7 @@ host_triplet = @host@
 @HAVE_BIN_TRUE@        mpdtinfo$(EXEEXT) mpdtreverse$(EXEEXT)
 subdir = src/extensions/mpdt
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_python_devel.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
        $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
@@ -105,6 +105,8 @@ CONFIG_HEADER = $(top_builddir)/config.h \
        $(top_builddir)/src/include/fst/config.h
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)"
+PROGRAMS = $(bin_PROGRAMS)
 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
 am__vpath_adj = case $$p in \
     $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
@@ -132,7 +134,6 @@ am__uninstall_files_from_dir = { \
     || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
          $(am__cd) "$$dir" && rm -f $$files; }; \
   }
-am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)"
 LTLIBRARIES = $(lib_LTLIBRARIES)
 am__DEPENDENCIES_1 =
 @HAVE_SCRIPT_TRUE@libfstmpdtscript_la_DEPENDENCIES =  \
@@ -150,7 +151,6 @@ libfstmpdtscript_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
        $(AM_CXXFLAGS) $(CXXFLAGS) $(libfstmpdtscript_la_LDFLAGS) \
        $(LDFLAGS) -o $@
 @HAVE_SCRIPT_TRUE@am_libfstmpdtscript_la_rpath = -rpath $(libdir)
-PROGRAMS = $(bin_PROGRAMS)
 am__mpdtcompose_SOURCES_DIST = mpdtcompose.cc mpdtcompose-main.cc
 @HAVE_BIN_TRUE@am_mpdtcompose_OBJECTS = mpdtcompose.$(OBJEXT) \
 @HAVE_BIN_TRUE@        mpdtcompose-main.$(OBJEXT)
@@ -201,7 +201,12 @@ am__v_at_0 = @
 am__v_at_1 = 
 DEFAULT_INCLUDES = 
 depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/mpdtcompose-main.Po \
+       ./$(DEPDIR)/mpdtcompose.Po ./$(DEPDIR)/mpdtexpand-main.Po \
+       ./$(DEPDIR)/mpdtexpand.Po ./$(DEPDIR)/mpdtinfo-main.Po \
+       ./$(DEPDIR)/mpdtinfo.Po ./$(DEPDIR)/mpdtreverse-main.Po \
+       ./$(DEPDIR)/mpdtreverse.Po ./$(DEPDIR)/mpdtscript.Plo
 am__mv = mv -f
 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
        $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
@@ -320,7 +325,7 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
@@ -427,8 +432,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
          *config.status*) \
            cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
          *) \
-           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
        esac;
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@@ -439,44 +444,6 @@ $(top_srcdir)/configure:  $(am__configure_deps)
 $(ACLOCAL_M4):  $(am__aclocal_m4_deps)
        cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 $(am__aclocal_m4_deps):
-
-install-libLTLIBRARIES: $(lib_LTLIBRARIES)
-       @$(NORMAL_INSTALL)
-       @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
-       list2=; for p in $$list; do \
-         if test -f $$p; then \
-           list2="$$list2 $$p"; \
-         else :; fi; \
-       done; \
-       test -z "$$list2" || { \
-         echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
-         $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
-         echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
-         $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
-       }
-
-uninstall-libLTLIBRARIES:
-       @$(NORMAL_UNINSTALL)
-       @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
-       for p in $$list; do \
-         $(am__strip_dir) \
-         echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
-         $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
-       done
-
-clean-libLTLIBRARIES:
-       -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
-       @list='$(lib_LTLIBRARIES)'; \
-       locs=`for p in $$list; do echo $$p; done | \
-             sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
-             sort -u`; \
-       test -z "$$locs" || { \
-         echo rm -f $${locs}; \
-         rm -f $${locs}; \
-       }
-
-libfstmpdtscript.la: $(libfstmpdtscript_la_OBJECTS) $(libfstmpdtscript_la_DEPENDENCIES) $(EXTRA_libfstmpdtscript_la_DEPENDENCIES) 
-       $(AM_V_CXXLD)$(libfstmpdtscript_la_LINK) $(am_libfstmpdtscript_la_rpath) $(libfstmpdtscript_la_OBJECTS) $(libfstmpdtscript_la_LIBADD) $(LIBS)
 install-binPROGRAMS: $(bin_PROGRAMS)
        @$(NORMAL_INSTALL)
        @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
@@ -527,6 +494,44 @@ clean-binPROGRAMS:
        echo " rm -f" $$list; \
        rm -f $$list
 
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+       @$(NORMAL_INSTALL)
+       @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+       list2=; for p in $$list; do \
+         if test -f $$p; then \
+           list2="$$list2 $$p"; \
+         else :; fi; \
+       done; \
+       test -z "$$list2" || { \
+         echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+         $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
+         echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+         $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+       }
+
+uninstall-libLTLIBRARIES:
+       @$(NORMAL_UNINSTALL)
+       @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+       for p in $$list; do \
+         $(am__strip_dir) \
+         echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+         $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+       done
+
+clean-libLTLIBRARIES:
+       -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+       @list='$(lib_LTLIBRARIES)'; \
+       locs=`for p in $$list; do echo $$p; done | \
+             sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+             sort -u`; \
+       test -z "$$locs" || { \
+         echo rm -f $${locs}; \
+         rm -f $${locs}; \
+       }
+
+libfstmpdtscript.la: $(libfstmpdtscript_la_OBJECTS) $(libfstmpdtscript_la_DEPENDENCIES) $(EXTRA_libfstmpdtscript_la_DEPENDENCIES) 
+       $(AM_V_CXXLD)$(libfstmpdtscript_la_LINK) $(am_libfstmpdtscript_la_rpath) $(libfstmpdtscript_la_OBJECTS) $(libfstmpdtscript_la_LIBADD) $(LIBS)
+
 mpdtcompose$(EXEEXT): $(mpdtcompose_OBJECTS) $(mpdtcompose_DEPENDENCIES) $(EXTRA_mpdtcompose_DEPENDENCIES) 
        @rm -f mpdtcompose$(EXEEXT)
        $(AM_V_CXXLD)$(CXXLINK) $(mpdtcompose_OBJECTS) $(mpdtcompose_LDADD) $(LIBS)
@@ -549,15 +554,21 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpdtcompose-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpdtcompose.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpdtexpand-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpdtexpand.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpdtinfo-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpdtinfo.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpdtreverse-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpdtreverse.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpdtscript.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpdtcompose-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpdtcompose.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpdtexpand-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpdtexpand.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpdtinfo-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpdtinfo.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpdtreverse-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpdtreverse.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpdtscript.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+       @$(MKDIR_P) $(@D)
+       @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
 
 .cc.o:
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -641,7 +652,10 @@ cscopelist-am: $(am__tagged_files)
 distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
-distdir: $(DISTFILES)
+distdir: $(BUILT_SOURCES)
+       $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
        @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        list='$(DISTFILES)'; \
@@ -673,11 +687,11 @@ distdir: $(DISTFILES)
        done
 check-am: all-am
 check: check-am
-all-am: Makefile $(LTLIBRARIES) $(PROGRAMS)
+all-am: Makefile $(PROGRAMS) $(LTLIBRARIES)
 install-binPROGRAMS: install-libLTLIBRARIES
 
 installdirs:
-       for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)"; do \
+       for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)"; do \
          test -z "$$dir" || $(MKDIR_P) "$$dir"; \
        done
 install: install-am
@@ -716,7 +730,15 @@ clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
        clean-libtool mostlyclean-am
 
 distclean: distclean-am
-       -rm -rf ./$(DEPDIR)
+               -rm -f ./$(DEPDIR)/mpdtcompose-main.Po
+       -rm -f ./$(DEPDIR)/mpdtcompose.Po
+       -rm -f ./$(DEPDIR)/mpdtexpand-main.Po
+       -rm -f ./$(DEPDIR)/mpdtexpand.Po
+       -rm -f ./$(DEPDIR)/mpdtinfo-main.Po
+       -rm -f ./$(DEPDIR)/mpdtinfo.Po
+       -rm -f ./$(DEPDIR)/mpdtreverse-main.Po
+       -rm -f ./$(DEPDIR)/mpdtreverse.Po
+       -rm -f ./$(DEPDIR)/mpdtscript.Plo
        -rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
        distclean-tags
@@ -762,7 +784,15 @@ install-ps-am:
 installcheck-am:
 
 maintainer-clean: maintainer-clean-am
-       -rm -rf ./$(DEPDIR)
+               -rm -f ./$(DEPDIR)/mpdtcompose-main.Po
+       -rm -f ./$(DEPDIR)/mpdtcompose.Po
+       -rm -f ./$(DEPDIR)/mpdtexpand-main.Po
+       -rm -f ./$(DEPDIR)/mpdtexpand.Po
+       -rm -f ./$(DEPDIR)/mpdtinfo-main.Po
+       -rm -f ./$(DEPDIR)/mpdtinfo.Po
+       -rm -f ./$(DEPDIR)/mpdtreverse-main.Po
+       -rm -f ./$(DEPDIR)/mpdtreverse.Po
+       -rm -f ./$(DEPDIR)/mpdtscript.Plo
        -rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
@@ -783,7 +813,7 @@ uninstall-am: uninstall-binPROGRAMS uninstall-libLTLIBRARIES
 
 .MAKE: install-am install-strip
 
-.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
        clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
        clean-libtool cscopelist-am ctags ctags-am distclean \
        distclean-compile distclean-generic distclean-libtool \
index 35434c6..ea50f0b 100644 (file)
@@ -6,6 +6,7 @@
 #include <cstring>
 #include <memory>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include <fst/flags.h>
@@ -60,7 +61,7 @@ int mpdtcompose_main(int argc, char **argv) {
     return 1;
   }
 
-  std::vector<s::LabelPair> parens;
+  std::vector<std::pair<int64, int64>> parens;
   std::vector<int64> assignments;
   if (!ReadLabelTriples(FLAGS_mpdt_parentheses, &parens, &assignments, false)) {
     return 1;
index a484cbf..7cf91b9 100644 (file)
@@ -6,6 +6,7 @@
 #include <cstring>
 #include <memory>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include <fst/flags.h>
@@ -49,7 +50,7 @@ int mpdtexpand_main(int argc, char **argv) {
     return 1;
   }
 
-  std::vector<s::LabelPair> parens;
+  std::vector<std::pair<int64, int64>> parens;
   std::vector<int64> assignments;
   if (!ReadLabelTriples(FLAGS_mpdt_parentheses, &parens, &assignments, false)) {
     return 1;
index 74d56b9..5563f26 100644 (file)
@@ -5,14 +5,13 @@
 // and parentheses.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include <fst/flags.h>
 #include <fst/log.h>
-
 #include <fst/extensions/mpdt/mpdtscript.h>
 #include <fst/extensions/mpdt/read_write_utils.h>
 #include <fst/util.h>
@@ -46,7 +45,7 @@ int mpdtinfo_main(int argc, char **argv) {
     return 1;
   }
 
-  std::vector<s::LabelPair> parens;
+  std::vector<std::pair<int64, int64>> parens;
   std::vector<int64> assignments;
   if (!ReadLabelTriples(FLAGS_mpdt_parentheses, &parens, &assignments, false)) {
     return 1;
index d266905..0a2bec3 100644 (file)
@@ -6,6 +6,7 @@
 #include <cstring>
 #include <memory>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include <fst/flags.h>
@@ -53,7 +54,7 @@ int mpdtreverse_main(int argc, char **argv) {
     return 1;
   }
 
-  std::vector<s::LabelPair> parens;
+  std::vector<std::pair<int64, int64>> parens;
   std::vector<int64> assignments;
   if (!ReadLabelTriples(FLAGS_mpdt_parentheses, &parens, &assignments, false)) {
     return 1;
index 7573494..cc807f7 100644 (file)
@@ -7,12 +7,14 @@
 // See comments in nlp/fst/script/script-impl.h for how the registration
 // mechanism allows these to work with various arc types.
 
+#include <fst/extensions/mpdt/mpdtscript.h>
+
 #include <string>
+#include <utility>
 #include <vector>
 
 #include <fst/extensions/mpdt/compose.h>
 #include <fst/extensions/mpdt/expand.h>
-#include <fst/extensions/mpdt/mpdtscript.h>
 #include <fst/extensions/mpdt/reverse.h>
 #include <fst/script/script-impl.h>
 
@@ -20,7 +22,7 @@ namespace fst {
 namespace script {
 
 void MPdtCompose(const FstClass &ifst1, const FstClass &ifst2,
-                 const std::vector<LabelPair> &parens,
+                 const std::vector<std::pair<int64, int64>> &parens,
                  const std::vector<int64> &assignments, MutableFstClass *ofst,
                  const MPdtComposeOptions &copts, bool left_pdt) {
   if (!internal::ArcTypesMatch(ifst1, ifst2, "MPdtCompose") ||
@@ -30,36 +32,42 @@ void MPdtCompose(const FstClass &ifst1, const FstClass &ifst2,
   Apply<Operation<MPdtComposeArgs>>("MPdtCompose", ifst1.ArcType(), &args);
 }
 
-void MPdtExpand(const FstClass &ifst, const std::vector<LabelPair> &parens,
+REGISTER_FST_OPERATION_3ARCS(MPdtCompose, MPdtComposeArgs);
+
+void MPdtExpand(const FstClass &ifst,
+                const std::vector<std::pair<int64, int64>> &parens,
                 const std::vector<int64> &assignments, MutableFstClass *ofst,
                 const MPdtExpandOptions &opts) {
   MPdtExpandArgs args(ifst, parens, assignments, ofst, opts);
   Apply<Operation<MPdtExpandArgs>>("MPdtExpand", ifst.ArcType(), &args);
 }
 
-void MPdtExpand(const FstClass &ifst, const std::vector<LabelPair> &parens,
+REGISTER_FST_OPERATION_3ARCS(MPdtExpand, MPdtExpandArgs);
+
+void MPdtExpand(const FstClass &ifst,
+                const std::vector<std::pair<int64, int64>> &parens,
                 const std::vector<int64> &assignments, MutableFstClass *ofst,
                 bool connect) {
   MPdtExpand(ifst, parens, assignments, ofst, MPdtExpandOptions(connect));
 }
 
-void MPdtReverse(const FstClass &ifst, const std::vector<LabelPair> &parens,
+void MPdtReverse(const FstClass &ifst,
+                 const std::vector<std::pair<int64, int64>> &parens,
                  std::vector<int64> *assignments, MutableFstClass *ofst) {
   MPdtReverseArgs args(ifst, parens, assignments, ofst);
   Apply<Operation<MPdtReverseArgs>>("MPdtReverse", ifst.ArcType(), &args);
 }
 
-void PrintMPdtInfo(const FstClass &ifst, const std::vector<LabelPair> &parens,
+REGISTER_FST_OPERATION_3ARCS(MPdtReverse, MPdtReverseArgs);
+
+void PrintMPdtInfo(const FstClass &ifst,
+                   const std::vector<std::pair<int64, int64>> &parens,
                    const std::vector<int64> &assignments) {
   PrintMPdtInfoArgs args(ifst, parens, assignments);
   Apply<Operation<PrintMPdtInfoArgs>>("PrintMPdtInfo", ifst.ArcType(), &args);
 }
 
-// Register operations for common arc types.
-
-REGISTER_FST_MPDT_OPERATIONS(StdArc);
-REGISTER_FST_MPDT_OPERATIONS(LogArc);
-REGISTER_FST_MPDT_OPERATIONS(Log64Arc);
+REGISTER_FST_OPERATION_3ARCS(PrintMPdtInfo, PrintMPdtInfoArgs);
 
 }  // namespace script
 }  // namespace fst
index ebdda86..f7111b2 100644 (file)
@@ -1,4 +1,5 @@
 AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
+LIBS = ../../lib/libfst.la -lm $(DL_LIBS)
 
 libfstdir = @libfstdir@
 libfst_LTLIBRARIES = ngram-fst.la
@@ -6,8 +7,7 @@ libfst_LTLIBRARIES = ngram-fst.la
 lib_LTLIBRARIES = libfstngram.la
 
 ngram_fst_la_SOURCES = bitmap-index.cc ngram-fst.cc nthbit.cc
-ngram_fst_la_LDFLAGS = -module
+ngram_fst_la_LDFLAGS = -avoid-version -module
 
 libfstngram_la_SOURCES = bitmap-index.cc ngram-fst.cc nthbit.cc
 libfstngram_la_LDFLAGS = -version-info 17:0:0
-libfstngram_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
index 425f657..5a2d5fa 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -90,7 +90,7 @@ build_triplet = @build@
 host_triplet = @host@
 subdir = src/extensions/ngram
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_python_devel.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
        $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
@@ -131,9 +131,7 @@ am__uninstall_files_from_dir = { \
   }
 am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libfstdir)"
 LTLIBRARIES = $(lib_LTLIBRARIES) $(libfst_LTLIBRARIES)
-am__DEPENDENCIES_1 =
-libfstngram_la_DEPENDENCIES = ../../lib/libfst.la \
-       $(am__DEPENDENCIES_1)
+libfstngram_la_LIBADD =
 am_libfstngram_la_OBJECTS = bitmap-index.lo ngram-fst.lo nthbit.lo
 libfstngram_la_OBJECTS = $(am_libfstngram_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
@@ -164,7 +162,9 @@ am__v_at_0 = @
 am__v_at_1 = 
 DEFAULT_INCLUDES = 
 depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/bitmap-index.Plo \
+       ./$(DEPDIR)/ngram-fst.Plo ./$(DEPDIR)/nthbit.Plo
 am__mv = mv -f
 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
        $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
@@ -251,7 +251,7 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
+LIBS = ../../lib/libfst.la -lm $(DL_LIBS)
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -279,7 +279,7 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
@@ -353,10 +353,9 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 libfst_LTLIBRARIES = ngram-fst.la
 lib_LTLIBRARIES = libfstngram.la
 ngram_fst_la_SOURCES = bitmap-index.cc ngram-fst.cc nthbit.cc
-ngram_fst_la_LDFLAGS = -module
+ngram_fst_la_LDFLAGS = -avoid-version -module
 libfstngram_la_SOURCES = bitmap-index.cc ngram-fst.cc nthbit.cc
 libfstngram_la_LDFLAGS = -version-info 17:0:0
-libfstngram_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
 all: all-am
 
 .SUFFIXES:
@@ -378,8 +377,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
          *config.status*) \
            cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
          *) \
-           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
        esac;
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@@ -473,9 +472,15 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bitmap-index.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ngram-fst.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nthbit.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bitmap-index.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ngram-fst.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nthbit.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+       @$(MKDIR_P) $(@D)
+       @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
 
 .cc.o:
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -559,7 +564,10 @@ cscopelist-am: $(am__tagged_files)
 distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
-distdir: $(DISTFILES)
+distdir: $(BUILT_SOURCES)
+       $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
        @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        list='$(DISTFILES)'; \
@@ -632,7 +640,9 @@ clean-am: clean-generic clean-libLTLIBRARIES clean-libfstLTLIBRARIES \
        clean-libtool mostlyclean-am
 
 distclean: distclean-am
-       -rm -rf ./$(DEPDIR)
+               -rm -f ./$(DEPDIR)/bitmap-index.Plo
+       -rm -f ./$(DEPDIR)/ngram-fst.Plo
+       -rm -f ./$(DEPDIR)/nthbit.Plo
        -rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
        distclean-tags
@@ -678,7 +688,9 @@ install-ps-am:
 installcheck-am:
 
 maintainer-clean: maintainer-clean-am
-       -rm -rf ./$(DEPDIR)
+               -rm -f ./$(DEPDIR)/bitmap-index.Plo
+       -rm -f ./$(DEPDIR)/ngram-fst.Plo
+       -rm -f ./$(DEPDIR)/nthbit.Plo
        -rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
@@ -699,21 +711,21 @@ uninstall-am: uninstall-libLTLIBRARIES uninstall-libfstLTLIBRARIES
 
 .MAKE: install-am install-strip
 
-.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
-       clean-libLTLIBRARIES clean-libfstLTLIBRARIES clean-libtool \
-       cscopelist-am ctags ctags-am distclean distclean-compile \
-       distclean-generic distclean-libtool distclean-tags distdir dvi \
-       dvi-am html html-am info info-am install install-am \
-       install-data install-data-am install-dvi install-dvi-am \
-       install-exec install-exec-am install-html install-html-am \
-       install-info install-info-am install-libLTLIBRARIES \
-       install-libfstLTLIBRARIES install-man install-pdf \
-       install-pdf-am install-ps install-ps-am install-strip \
-       installcheck installcheck-am installdirs maintainer-clean \
-       maintainer-clean-generic mostlyclean mostlyclean-compile \
-       mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
-       tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES \
-       uninstall-libfstLTLIBRARIES
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
+       clean-generic clean-libLTLIBRARIES clean-libfstLTLIBRARIES \
+       clean-libtool cscopelist-am ctags ctags-am distclean \
+       distclean-compile distclean-generic distclean-libtool \
+       distclean-tags distdir dvi dvi-am html html-am info info-am \
+       install install-am install-data install-data-am install-dvi \
+       install-dvi-am install-exec install-exec-am install-html \
+       install-html-am install-info install-info-am \
+       install-libLTLIBRARIES install-libfstLTLIBRARIES install-man \
+       install-pdf install-pdf-am install-ps install-ps-am \
+       install-strip installcheck installcheck-am installdirs \
+       maintainer-clean maintainer-clean-generic mostlyclean \
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+       pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \
+       uninstall-libLTLIBRARIES uninstall-libfstLTLIBRARIES
 
 .PRECIOUS: Makefile
 
index b62bb98..4b45f51 100644 (file)
@@ -14,6 +14,9 @@ namespace {
 const size_t kPrimaryBlockBits =
     BitmapIndex::kStorageBitSize * BitmapIndex::kSecondaryBlockSize;
 
+static_assert(sizeof(long long) >= sizeof(uint64),  // NOLINT
+              "__builtin_...ll is used on uint64 values.");
+
 // If [begin, begin+size) is a monotonically increasing running sum of
 // popcounts for a bitmap, this will return the index of the word that contains
 // the value'th zero.  If value is larger then the number of zeros in the
@@ -164,14 +167,16 @@ size_t BitmapIndex::get_index_ones_count(size_t array_index) const {
   return sum;
 }
 
-void BitmapIndex::BuildIndex(const uint64 *bits, size_t size) {
+void BitmapIndex::BuildIndex(const uint64 *bits, size_t num_bits) {
   bits_ = bits;
-  size_ = size;
+  num_bits_ = num_bits;
   primary_index_.resize(primary_index_size());
   secondary_index_.resize(ArraySize());
   const uint64 zero = 0;
   const uint64 ones = ~zero;
   uint32 popcount = 0;
+  // We keep the primary index zero for empty bitmaps.
+  if (ArraySize() == 0) primary_index_.at(0) = 0;
   for (uint32 block = 0; block * kSecondaryBlockSize < ArraySize(); block++) {
     uint32 block_popcount = 0;
     uint32 block_begin = block * kSecondaryBlockSize;
@@ -180,7 +185,7 @@ void BitmapIndex::BuildIndex(const uint64 *bits, size_t size) {
     for (uint32 j = block_begin; j < block_end; ++j) {
       uint64 mask = ones;
       if (j == ArraySize() - 1) {
-        mask = ones >> (-size_ & BitmapIndex::kStorageBlockMask);
+        mask = ones >> (-num_bits_ & BitmapIndex::kStorageBlockMask);
       }
       block_popcount += __builtin_popcountll(bits_[j] & mask);
       secondary_index_[j] = block_popcount;
@@ -213,8 +218,7 @@ size_t BitmapIndex::find_inverted_secondary_block(size_t block_begin,
 inline size_t BitmapIndex::find_primary_block(size_t bit_index) const {
   return std::distance(
       primary_index_.begin(),
-      std::lower_bound(primary_index_.begin(),
-                       primary_index_.begin() + primary_index_size(),
+      std::lower_bound(primary_index_.begin(), primary_index_.end(),
                        bit_index));
 }
 
index ea769f9..2cd6e0e 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -94,7 +94,7 @@ host_triplet = @host@
 @HAVE_BIN_TRUE@        pdtreverse$(EXEEXT) pdtshortestpath$(EXEEXT)
 subdir = src/extensions/pdt
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_python_devel.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
        $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
@@ -106,6 +106,8 @@ CONFIG_HEADER = $(top_builddir)/config.h \
        $(top_builddir)/src/include/fst/config.h
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)"
+PROGRAMS = $(bin_PROGRAMS)
 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
 am__vpath_adj = case $$p in \
     $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
@@ -133,7 +135,6 @@ am__uninstall_files_from_dir = { \
     || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
          $(am__cd) "$$dir" && rm -f $$files; }; \
   }
-am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)"
 LTLIBRARIES = $(lib_LTLIBRARIES)
 am__DEPENDENCIES_1 =
 @HAVE_SCRIPT_TRUE@libfstpdtscript_la_DEPENDENCIES =  \
@@ -152,7 +153,6 @@ libfstpdtscript_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
        $(AM_CXXFLAGS) $(CXXFLAGS) $(libfstpdtscript_la_LDFLAGS) \
        $(LDFLAGS) -o $@
 @HAVE_SCRIPT_TRUE@am_libfstpdtscript_la_rpath = -rpath $(libdir)
-PROGRAMS = $(bin_PROGRAMS)
 am__pdtcompose_SOURCES_DIST = pdtcompose.cc pdtcompose-main.cc
 @HAVE_BIN_TRUE@am_pdtcompose_OBJECTS = pdtcompose.$(OBJEXT) \
 @HAVE_BIN_TRUE@        pdtcompose-main.$(OBJEXT)
@@ -216,7 +216,15 @@ am__v_at_0 = @
 am__v_at_1 = 
 DEFAULT_INCLUDES = 
 depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/getters.Plo \
+       ./$(DEPDIR)/pdtcompose-main.Po ./$(DEPDIR)/pdtcompose.Po \
+       ./$(DEPDIR)/pdtexpand-main.Po ./$(DEPDIR)/pdtexpand.Po \
+       ./$(DEPDIR)/pdtinfo-main.Po ./$(DEPDIR)/pdtinfo.Po \
+       ./$(DEPDIR)/pdtreplace-main.Po ./$(DEPDIR)/pdtreplace.Po \
+       ./$(DEPDIR)/pdtreverse-main.Po ./$(DEPDIR)/pdtreverse.Po \
+       ./$(DEPDIR)/pdtscript.Plo ./$(DEPDIR)/pdtshortestpath-main.Po \
+       ./$(DEPDIR)/pdtshortestpath.Po
 am__mv = mv -f
 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
        $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
@@ -337,7 +345,7 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
@@ -445,8 +453,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
          *config.status*) \
            cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
          *) \
-           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
        esac;
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@@ -457,44 +465,6 @@ $(top_srcdir)/configure:  $(am__configure_deps)
 $(ACLOCAL_M4):  $(am__aclocal_m4_deps)
        cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 $(am__aclocal_m4_deps):
-
-install-libLTLIBRARIES: $(lib_LTLIBRARIES)
-       @$(NORMAL_INSTALL)
-       @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
-       list2=; for p in $$list; do \
-         if test -f $$p; then \
-           list2="$$list2 $$p"; \
-         else :; fi; \
-       done; \
-       test -z "$$list2" || { \
-         echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
-         $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
-         echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
-         $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
-       }
-
-uninstall-libLTLIBRARIES:
-       @$(NORMAL_UNINSTALL)
-       @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
-       for p in $$list; do \
-         $(am__strip_dir) \
-         echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
-         $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
-       done
-
-clean-libLTLIBRARIES:
-       -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
-       @list='$(lib_LTLIBRARIES)'; \
-       locs=`for p in $$list; do echo $$p; done | \
-             sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
-             sort -u`; \
-       test -z "$$locs" || { \
-         echo rm -f $${locs}; \
-         rm -f $${locs}; \
-       }
-
-libfstpdtscript.la: $(libfstpdtscript_la_OBJECTS) $(libfstpdtscript_la_DEPENDENCIES) $(EXTRA_libfstpdtscript_la_DEPENDENCIES) 
-       $(AM_V_CXXLD)$(libfstpdtscript_la_LINK) $(am_libfstpdtscript_la_rpath) $(libfstpdtscript_la_OBJECTS) $(libfstpdtscript_la_LIBADD) $(LIBS)
 install-binPROGRAMS: $(bin_PROGRAMS)
        @$(NORMAL_INSTALL)
        @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
@@ -545,6 +515,44 @@ clean-binPROGRAMS:
        echo " rm -f" $$list; \
        rm -f $$list
 
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+       @$(NORMAL_INSTALL)
+       @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+       list2=; for p in $$list; do \
+         if test -f $$p; then \
+           list2="$$list2 $$p"; \
+         else :; fi; \
+       done; \
+       test -z "$$list2" || { \
+         echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+         $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
+         echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+         $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+       }
+
+uninstall-libLTLIBRARIES:
+       @$(NORMAL_UNINSTALL)
+       @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+       for p in $$list; do \
+         $(am__strip_dir) \
+         echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+         $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+       done
+
+clean-libLTLIBRARIES:
+       -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+       @list='$(lib_LTLIBRARIES)'; \
+       locs=`for p in $$list; do echo $$p; done | \
+             sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+             sort -u`; \
+       test -z "$$locs" || { \
+         echo rm -f $${locs}; \
+         rm -f $${locs}; \
+       }
+
+libfstpdtscript.la: $(libfstpdtscript_la_OBJECTS) $(libfstpdtscript_la_DEPENDENCIES) $(EXTRA_libfstpdtscript_la_DEPENDENCIES) 
+       $(AM_V_CXXLD)$(libfstpdtscript_la_LINK) $(am_libfstpdtscript_la_rpath) $(libfstpdtscript_la_OBJECTS) $(libfstpdtscript_la_LIBADD) $(LIBS)
+
 pdtcompose$(EXEEXT): $(pdtcompose_OBJECTS) $(pdtcompose_DEPENDENCIES) $(EXTRA_pdtcompose_DEPENDENCIES) 
        @rm -f pdtcompose$(EXEEXT)
        $(AM_V_CXXLD)$(CXXLINK) $(pdtcompose_OBJECTS) $(pdtcompose_LDADD) $(LIBS)
@@ -575,20 +583,26 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getters.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtcompose-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtcompose.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtexpand-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtexpand.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtinfo-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtinfo.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtreplace-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtreplace.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtreverse-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtreverse.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtscript.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtshortestpath-main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtshortestpath.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getters.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtcompose-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtcompose.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtexpand-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtexpand.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtinfo-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtinfo.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtreplace-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtreplace.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtreverse-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtreverse.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtscript.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtshortestpath-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtshortestpath.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+       @$(MKDIR_P) $(@D)
+       @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
 
 .cc.o:
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -672,7 +686,10 @@ cscopelist-am: $(am__tagged_files)
 distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
-distdir: $(DISTFILES)
+distdir: $(BUILT_SOURCES)
+       $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
        @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        list='$(DISTFILES)'; \
@@ -704,11 +721,11 @@ distdir: $(DISTFILES)
        done
 check-am: all-am
 check: check-am
-all-am: Makefile $(LTLIBRARIES) $(PROGRAMS)
+all-am: Makefile $(PROGRAMS) $(LTLIBRARIES)
 install-binPROGRAMS: install-libLTLIBRARIES
 
 installdirs:
-       for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)"; do \
+       for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)"; do \
          test -z "$$dir" || $(MKDIR_P) "$$dir"; \
        done
 install: install-am
@@ -747,7 +764,20 @@ clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
        clean-libtool mostlyclean-am
 
 distclean: distclean-am
-       -rm -rf ./$(DEPDIR)
+               -rm -f ./$(DEPDIR)/getters.Plo
+       -rm -f ./$(DEPDIR)/pdtcompose-main.Po
+       -rm -f ./$(DEPDIR)/pdtcompose.Po
+       -rm -f ./$(DEPDIR)/pdtexpand-main.Po
+       -rm -f ./$(DEPDIR)/pdtexpand.Po
+       -rm -f ./$(DEPDIR)/pdtinfo-main.Po
+       -rm -f ./$(DEPDIR)/pdtinfo.Po
+       -rm -f ./$(DEPDIR)/pdtreplace-main.Po
+       -rm -f ./$(DEPDIR)/pdtreplace.Po
+       -rm -f ./$(DEPDIR)/pdtreverse-main.Po
+       -rm -f ./$(DEPDIR)/pdtreverse.Po
+       -rm -f ./$(DEPDIR)/pdtscript.Plo
+       -rm -f ./$(DEPDIR)/pdtshortestpath-main.Po
+       -rm -f ./$(DEPDIR)/pdtshortestpath.Po
        -rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
        distclean-tags
@@ -793,7 +823,20 @@ install-ps-am:
 installcheck-am:
 
 maintainer-clean: maintainer-clean-am
-       -rm -rf ./$(DEPDIR)
+               -rm -f ./$(DEPDIR)/getters.Plo
+       -rm -f ./$(DEPDIR)/pdtcompose-main.Po
+       -rm -f ./$(DEPDIR)/pdtcompose.Po
+       -rm -f ./$(DEPDIR)/pdtexpand-main.Po
+       -rm -f ./$(DEPDIR)/pdtexpand.Po
+       -rm -f ./$(DEPDIR)/pdtinfo-main.Po
+       -rm -f ./$(DEPDIR)/pdtinfo.Po
+       -rm -f ./$(DEPDIR)/pdtreplace-main.Po
+       -rm -f ./$(DEPDIR)/pdtreplace.Po
+       -rm -f ./$(DEPDIR)/pdtreverse-main.Po
+       -rm -f ./$(DEPDIR)/pdtreverse.Po
+       -rm -f ./$(DEPDIR)/pdtscript.Plo
+       -rm -f ./$(DEPDIR)/pdtshortestpath-main.Po
+       -rm -f ./$(DEPDIR)/pdtshortestpath.Po
        -rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
@@ -814,7 +857,7 @@ uninstall-am: uninstall-binPROGRAMS uninstall-libLTLIBRARIES
 
 .MAKE: install-am install-strip
 
-.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
        clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
        clean-libtool cscopelist-am ctags ctags-am distclean \
        distclean-compile distclean-generic distclean-libtool \
index 4221e6a..1250141 100644 (file)
@@ -6,6 +6,7 @@
 #include <cstring>
 #include <memory>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include <fst/flags.h>
@@ -59,7 +60,7 @@ int pdtcompose_main(int argc, char **argv) {
     return 1;
   }
 
-  std::vector<s::LabelPair> parens;
+  std::vector<std::pair<int64, int64>> parens;
   if (!ReadLabelPairs(FLAGS_pdt_parentheses, &parens, false)) return 1;
 
   VectorFstClass ofst(ifst1->ArcType());
index 7085b0a..3d0d767 100644 (file)
@@ -6,6 +6,7 @@
 #include <cstring>
 #include <memory>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include <fst/flags.h>
@@ -49,7 +50,7 @@ int pdtexpand_main(int argc, char **argv) {
     return 1;
   }
 
-  std::vector<s::LabelPair> parens;
+  std::vector<std::pair<int64, int64>> parens;
   if (!ReadLabelPairs(FLAGS_pdt_parentheses, &parens, false)) return 1;
 
   const auto weight_threshold =
index 7f0ce2e..3915b40 100644 (file)
@@ -7,6 +7,7 @@
 #include <cstring>
 #include <memory>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include <fst/flags.h>
@@ -43,7 +44,7 @@ int pdtinfo_main(int argc, char **argv) {
     return 1;
   }
 
-  std::vector<s::LabelPair> parens;
+  std::vector<std::pair<int64, int64>> parens;
   if (!ReadLabelPairs(FLAGS_pdt_parentheses, &parens, false)) return 1;
 
   s::PrintPdtInfo(*ifst, parens);
index cd6f0fc..cc83dce 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <cstring>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include <fst/flags.h>
@@ -21,14 +22,14 @@ DECLARE_string(right_paren_prefix);
 
 namespace fst {
 namespace script {
+namespace {
 
-void Cleanup(std::vector<LabelFstClassPair> *pairs) {
-  for (const auto &pair : *pairs) {
-    delete pair.second;
-  }
+void Cleanup(std::vector<std::pair<int64, const FstClass *>> *pairs) {
+  for (const auto &pair : *pairs) delete pair.second;
   pairs->clear();
 }
 
+}  // namespace
 }  // namespace script
 }  // namespace fst
 
@@ -65,7 +66,7 @@ int pdtreplace_main(int argc, char **argv) {
     return 1;
   }
 
-  std::vector<s::LabelFstClassPair> pairs;
+  std::vector<std::pair<int64, const FstClass *>> pairs;
   // Note that if the root label is beyond the range of the underlying FST's
   // labels, truncation will occur.
   const auto root = atoll(argv[2]);
@@ -84,7 +85,7 @@ int pdtreplace_main(int argc, char **argv) {
   }
 
   VectorFstClass ofst(ifst->ArcType());
-  std::vector<s::LabelPair> parens;
+  std::vector<std::pair<int64, int64>> parens;
   s::PdtReplace(pairs, &ofst, &parens, root, parser_type,
                 FLAGS_start_paren_labels, FLAGS_left_paren_prefix,
                 FLAGS_right_paren_prefix);
index 1167bdc..e882d99 100644 (file)
@@ -6,6 +6,7 @@
 #include <cstring>
 #include <memory>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include <fst/flags.h>
@@ -45,7 +46,7 @@ int pdtreverse_main(int argc, char **argv) {
     return 1;
   }
 
-  std::vector<s::LabelPair> parens;
+  std::vector<std::pair<int64, int64>> parens;
   if (!ReadLabelPairs(FLAGS_pdt_parentheses, &parens, false)) return 1;
 
   VectorFstClass ofst(ifst->ArcType());
index 9881834..dd9896f 100644 (file)
@@ -10,6 +10,7 @@
 #include <fst/extensions/pdt/pdtscript.h>
 
 #include <string>
+#include <utility>
 #include <vector>
 
 #include <fst/extensions/pdt/compose.h>
@@ -23,23 +24,28 @@ namespace fst {
 namespace script {
 
 void PdtCompose(const FstClass &ifst1, const FstClass &ifst2,
-                const std::vector<LabelPair> &parens,
+                const std::vector<std::pair<int64, int64>> &parens,
                 MutableFstClass *ofst, const PdtComposeOptions &copts,
                 bool left_pdt) {
   if (!internal::ArcTypesMatch(ifst1, ifst2, "PdtCompose") ||
-      !internal::ArcTypesMatch(ifst1, *ofst, "PdtCompose"))
+      !internal::ArcTypesMatch(ifst1, *ofst, "PdtCompose")) {
     return;
+  }
   PdtComposeArgs args(ifst1, ifst2, parens, ofst, copts, left_pdt);
   Apply<Operation<PdtComposeArgs>>("PdtCompose", ifst1.ArcType(), &args);
 }
 
+REGISTER_FST_OPERATION_3ARCS(PdtCompose, PdtComposeArgs);
+
 void PdtExpand(const FstClass &ifst,
-               const std::vector<LabelPair> &parens,
+               const std::vector<std::pair<int64, int64>> &parens,
                MutableFstClass *ofst, const PdtExpandOptions &opts) {
   PdtExpandArgs args(ifst, parens, ofst, opts);
   Apply<Operation<PdtExpandArgs>>("PdtExpand", ifst.ArcType(), &args);
 }
 
+REGISTER_FST_OPERATION_3ARCS(PdtExpand, PdtExpandArgs);
+
 void PdtExpand(const FstClass &ifst,
                const std::vector<std::pair<int64, int64>> &parens,
                MutableFstClass *ofst, bool connect, bool keep_parentheses,
@@ -48,9 +54,10 @@ void PdtExpand(const FstClass &ifst,
             PdtExpandOptions(connect, keep_parentheses, weight_threshold));
 }
 
-void PdtReplace(const std::vector<LabelFstClassPair> &pairs,
-                MutableFstClass *ofst, std::vector<LabelPair> *parens,
-                int64 root, PdtParserType parser_type, int64 start_paren_labels,
+void PdtReplace(const std::vector<std::pair<int64, const FstClass *>> &pairs,
+                MutableFstClass *ofst,
+                std::vector<std::pair<int64, int64>> *parens, int64 root,
+                PdtParserType parser_type, int64 start_paren_labels,
                 const std::string &left_paren_prefix,
                 const std::string &right_paren_prefix) {
   for (size_t i = 1; i < pairs.size(); ++i) {
@@ -65,15 +72,19 @@ void PdtReplace(const std::vector<LabelFstClassPair> &pairs,
   Apply<Operation<PdtReplaceArgs>>("PdtReplace", ofst->ArcType(), &args);
 }
 
+REGISTER_FST_OPERATION_3ARCS(PdtReplace, PdtReplaceArgs);
+
 void PdtReverse(const FstClass &ifst,
-                const std::vector<LabelPair> &parens,
+                const std::vector<std::pair<int64, int64>> &parens,
                 MutableFstClass *ofst) {
   PdtReverseArgs args(ifst, parens, ofst);
   Apply<Operation<PdtReverseArgs>>("PdtReverse", ifst.ArcType(), &args);
 }
 
+REGISTER_FST_OPERATION_3ARCS(PdtReverse, PdtReverseArgs);
+
 void PdtShortestPath(const FstClass &ifst,
-                     const std::vector<LabelPair> &parens,
+                     const std::vector<std::pair<int64, int64>> &parens,
                      MutableFstClass *ofst,
                      const PdtShortestPathOptions &opts) {
   PdtShortestPathArgs args(ifst, parens, ofst, opts);
@@ -81,17 +92,15 @@ void PdtShortestPath(const FstClass &ifst,
                                         &args);
 }
 
+REGISTER_FST_OPERATION_3ARCS(PdtShortestPath, PdtShortestPathArgs);
+
 void PrintPdtInfo(const FstClass &ifst,
-                  const std::vector<LabelPair> &parens) {
+                  const std::vector<std::pair<int64, int64>> &parens) {
   PrintPdtInfoArgs args(ifst, parens);
   Apply<Operation<PrintPdtInfoArgs>>("PrintPdtInfo", ifst.ArcType(), &args);
 }
 
-// Register operations for common arc types.
-
-REGISTER_FST_PDT_OPERATIONS(StdArc);
-REGISTER_FST_PDT_OPERATIONS(LogArc);
-REGISTER_FST_PDT_OPERATIONS(Log64Arc);
+REGISTER_FST_OPERATION_3ARCS(PrintPdtInfo, PrintPdtInfoArgs);
 
 }  // namespace script
 }  // namespace fst
index 2d3a4b1..6c38f79 100644 (file)
@@ -6,6 +6,7 @@
 #include <cstring>
 #include <memory>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include <fst/flags.h>
@@ -49,7 +50,7 @@ int pdtshortestpath_main(int argc, char **argv) {
     return 1;
   }
 
-  std::vector<s::LabelPair> parens;
+  std::vector<std::pair<int64, int64>> parens;
   if (!ReadLabelPairs(FLAGS_pdt_parentheses, &parens, false)) return 1;
 
   VectorFstClass ofst(ifst->ArcType());
index 3406524..36aa4d2 100644 (file)
@@ -8,11 +8,11 @@ pyexec_LTILIBRARIES = pywrapfst.la
 
 pywrapfst_la_SOURCES = pywrapfst.cc
 pywrapfst_la_CPPFLAGS = -I$(srcdir)/../../include $(PYTHON_CPPFLAGS)
-pywrapfst_la_LDFLAGS = $(PYTHON_LDFLAGS) -avoid-version -module
+pywrapfst_la_CXXFLAGS = -fexceptions
+pywrapfst_la_LDFLAGS = -avoid-version -module
 pywrapfst_la_LIBADD = ../far/libfstfarscript.la ../far/libfstfar.la \
                       ../../script/libfstscript.la ../../lib/libfst.la \
-                      -lm $(DL_LIBS)
+                      -lm $(DL_LIBS) $(PYTHON_LIBS)
 
 # Exports the *.pxd/*.pxd source files.
-EXTRA_DIST = basictypes.pxd fst.pxd ios.pxd memory.pxd pywrapfst.pxd \
-             pywrapfst.pyx
+EXTRA_DIST = basictypes.pxd fst.pxd ios.pxd pywrapfst.pxd pywrapfst.pyx
index 9742573..fed0707 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -94,7 +94,7 @@ build_triplet = @build@
 host_triplet = @host@
 subdir = src/extensions/python
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_python_devel.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
        $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
@@ -138,7 +138,8 @@ LTLIBRARIES = $(python_LTLIBRARIES)
 am__DEPENDENCIES_1 =
 pywrapfst_la_DEPENDENCIES = ../far/libfstfarscript.la \
        ../far/libfstfar.la ../../script/libfstscript.la \
-       ../../lib/libfst.la $(am__DEPENDENCIES_1)
+       ../../lib/libfst.la $(am__DEPENDENCIES_1) \
+       $(am__DEPENDENCIES_1)
 am_pywrapfst_la_OBJECTS = pywrapfst_la-pywrapfst.lo
 pywrapfst_la_OBJECTS = $(am_pywrapfst_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
@@ -146,7 +147,7 @@ am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
 am__v_lt_0 = --silent
 am__v_lt_1 = 
 pywrapfst_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
-       $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+       $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(pywrapfst_la_CXXFLAGS) \
        $(CXXFLAGS) $(pywrapfst_la_LDFLAGS) $(LDFLAGS) -o $@
 AM_V_P = $(am__v_P_@AM_V@)
 am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
@@ -162,7 +163,8 @@ am__v_at_0 = @
 am__v_at_1 = 
 DEFAULT_INCLUDES = 
 depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pywrapfst_la-pywrapfst.Plo
 am__mv = mv -f
 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
        $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
@@ -277,7 +279,7 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
@@ -351,16 +353,15 @@ python_LTLIBRARIES = pywrapfst.la
 pyexec_LTILIBRARIES = pywrapfst.la
 pywrapfst_la_SOURCES = pywrapfst.cc
 pywrapfst_la_CPPFLAGS = -I$(srcdir)/../../include $(PYTHON_CPPFLAGS)
-pywrapfst_la_LDFLAGS = $(PYTHON_LDFLAGS) -avoid-version -module
+pywrapfst_la_CXXFLAGS = -fexceptions
+pywrapfst_la_LDFLAGS = -avoid-version -module
 pywrapfst_la_LIBADD = ../far/libfstfarscript.la ../far/libfstfar.la \
                       ../../script/libfstscript.la ../../lib/libfst.la \
-                      -lm $(DL_LIBS)
+                      -lm $(DL_LIBS) $(PYTHON_LIBS)
 
 
 # Exports the *.pxd/*.pxd source files.
-EXTRA_DIST = basictypes.pxd fst.pxd ios.pxd memory.pxd pywrapfst.pxd \
-             pywrapfst.pyx
-
+EXTRA_DIST = basictypes.pxd fst.pxd ios.pxd pywrapfst.pxd pywrapfst.pyx
 all: all-am
 
 .SUFFIXES:
@@ -382,8 +383,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
          *config.status*) \
            cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
          *) \
-           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
        esac;
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@@ -439,7 +440,13 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pywrapfst_la-pywrapfst.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pywrapfst_la-pywrapfst.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+       @$(MKDIR_P) $(@D)
+       @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
 
 .cc.o:
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -466,11 +473,11 @@ distclean-compile:
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
 
 pywrapfst_la-pywrapfst.lo: pywrapfst.cc
-@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pywrapfst_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT pywrapfst_la-pywrapfst.lo -MD -MP -MF $(DEPDIR)/pywrapfst_la-pywrapfst.Tpo -c -o pywrapfst_la-pywrapfst.lo `test -f 'pywrapfst.cc' || echo '$(srcdir)/'`pywrapfst.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pywrapfst_la_CPPFLAGS) $(CPPFLAGS) $(pywrapfst_la_CXXFLAGS) $(CXXFLAGS) -MT pywrapfst_la-pywrapfst.lo -MD -MP -MF $(DEPDIR)/pywrapfst_la-pywrapfst.Tpo -c -o pywrapfst_la-pywrapfst.lo `test -f 'pywrapfst.cc' || echo '$(srcdir)/'`pywrapfst.cc
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/pywrapfst_la-pywrapfst.Tpo $(DEPDIR)/pywrapfst_la-pywrapfst.Plo
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='pywrapfst.cc' object='pywrapfst_la-pywrapfst.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pywrapfst_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o pywrapfst_la-pywrapfst.lo `test -f 'pywrapfst.cc' || echo '$(srcdir)/'`pywrapfst.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pywrapfst_la_CPPFLAGS) $(CPPFLAGS) $(pywrapfst_la_CXXFLAGS) $(CXXFLAGS) -c -o pywrapfst_la-pywrapfst.lo `test -f 'pywrapfst.cc' || echo '$(srcdir)/'`pywrapfst.cc
 
 mostlyclean-libtool:
        -rm -f *.lo
@@ -530,7 +537,10 @@ cscopelist-am: $(am__tagged_files)
 distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
-distdir: $(DISTFILES)
+distdir: $(BUILT_SOURCES)
+       $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
        @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        list='$(DISTFILES)'; \
@@ -603,7 +613,7 @@ clean-am: clean-generic clean-libtool clean-pythonLTLIBRARIES \
        mostlyclean-am
 
 distclean: distclean-am
-       -rm -rf ./$(DEPDIR)
+               -rm -f ./$(DEPDIR)/pywrapfst_la-pywrapfst.Plo
        -rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
        distclean-tags
@@ -649,7 +659,7 @@ install-ps-am:
 installcheck-am:
 
 maintainer-clean: maintainer-clean-am
-       -rm -rf ./$(DEPDIR)
+               -rm -f ./$(DEPDIR)/pywrapfst_la-pywrapfst.Plo
        -rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
@@ -670,19 +680,20 @@ uninstall-am: uninstall-pythonLTLIBRARIES
 
 .MAKE: install-am install-strip
 
-.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
-       clean-libtool clean-pythonLTLIBRARIES cscopelist-am ctags \
-       ctags-am distclean distclean-compile distclean-generic \
-       distclean-libtool distclean-tags distdir dvi dvi-am html \
-       html-am info info-am install install-am install-data \
-       install-data-am install-dvi install-dvi-am install-exec \
-       install-exec-am install-html install-html-am install-info \
-       install-info-am install-man install-pdf install-pdf-am \
-       install-ps install-ps-am install-pythonLTLIBRARIES \
-       install-strip installcheck installcheck-am installdirs \
-       maintainer-clean maintainer-clean-generic mostlyclean \
-       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
-       pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
+       clean-generic clean-libtool clean-pythonLTLIBRARIES \
+       cscopelist-am ctags ctags-am distclean distclean-compile \
+       distclean-generic distclean-libtool distclean-tags distdir dvi \
+       dvi-am html html-am info info-am install install-am \
+       install-data install-data-am install-dvi install-dvi-am \
+       install-exec install-exec-am install-html install-html-am \
+       install-info install-info-am install-man install-pdf \
+       install-pdf-am install-ps install-ps-am \
+       install-pythonLTLIBRARIES install-strip installcheck \
+       installcheck-am installdirs maintainer-clean \
+       maintainer-clean-generic mostlyclean mostlyclean-compile \
+       mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+       tags tags-am uninstall uninstall-am \
        uninstall-pythonLTLIBRARIES
 
 .PRECIOUS: Makefile
index 1763e43..fb80e4e 100644 (file)
@@ -10,18 +10,12 @@ from libcpp.string cimport string
 from libcpp.vector cimport vector
 from libcpp.utility cimport pair
 
-from basictypes cimport int32
-from basictypes cimport int64
-from basictypes cimport uint32
-from basictypes cimport uint64
-from ios cimport istream
-from ios cimport ostream
+from basictypes cimport *
+from ios cimport *
 
 
 cdef extern from "<fst/util.h>" nogil:
 
-  # Note that this is a copy, so it should be viewed as read-only.
-
   bool FLAGS_fst_error_fatal
 
 
@@ -88,18 +82,18 @@ cdef extern from "<fst/fstlib.h>" namespace "fst" nogil:
   const uint64 kFstProperties
 
   # ArcIterator flags.
-  const uint32 kArcILabelValue
-  const uint32 kArcOLabelValue
-  const uint32 kArcWeightValue
-  const uint32 kArcNextStateValue
-  const uint32 kArcNoCache
-  const uint32 kArcValueFlags
-  const uint32 kArcFlags
+  const uint8 kArcILabelValue
+  const uint8 kArcOLabelValue
+  const uint8 kArcWeightValue
+  const uint8 kArcNextStateValue
+  const uint8 kArcNoCache
+  const uint8 kArcValueFlags
+  const uint8 kArcFlags
 
   # EncodeMapper flags.
-  const uint32 kEncodeLabels
-  const uint32 kEncodeWeights
-  const uint32 kEncodeFlags
+  const uint8 kEncodeLabels
+  const uint8 kEncodeWeights
+  const uint8 kEncodeFlags
 
   # Default argument constants.
   const float kDelta
@@ -108,12 +102,10 @@ cdef extern from "<fst/fstlib.h>" namespace "fst" nogil:
   const int kNoStateId
   const int64 kNoSymbol
 
-
   enum ClosureType:
     CLOSURE_STAR
     CLOSURE_PLUS
 
-
   enum ComposeFilter:
     AUTO_FILTER
     NULL_FILTER
@@ -122,33 +114,27 @@ cdef extern from "<fst/fstlib.h>" namespace "fst" nogil:
     MATCH_FILTER
     TRIVIAL_FILTER
 
-
   cdef cppclass ComposeOptions:
 
     ComposeOptions(bool, ComposeFilter)
 
-
   enum DeterminizeType:
     DETERMINIZE_FUNCTIONAL
     DETERMINIZE_NONFUNCTIONAL
     DETERMINIZE_DISAMBIGUATE
 
-
   enum EncodeType:
     DECODE
     ENCODE
 
-
   enum EpsNormalizeType:
     EPS_NORM_INPUT
     EPS_NORM_OUTPUT
 
-
   enum ProjectType:
     PROJECT_INPUT
     PROJECT_OUTPUT
 
-
   enum QueueType:
     TRIVIAL_QUEUE
     FIFO_QUEUE
@@ -160,26 +146,22 @@ cdef extern from "<fst/fstlib.h>" namespace "fst" nogil:
     AUTO_QUEUE
     OTHER_QUEUE
 
-
   # This is a templated struct at the C++ level, but Cython does not support
   # templated structs unless we pretend they are full-blown classes.
   cdef cppclass RandGenOptions[RandArcSelection]:
 
     RandGenOptions(const RandArcSelection &, int32, int32, bool, bool)
 
-
   enum ReplaceLabelType:
     REPLACE_LABEL_NEITHER
     REPLACE_LABEL_INPUT
     REPLACE_LABEL_OUTPUT
     REPLACE_LABEL_BOTH
 
-
   enum ReweightType:
     REWEIGHT_TO_INITIAL
     REWEIGHT_TO_FINAL
 
-
   cdef cppclass SymbolTableTextOptions:
 
     SymbolTableTextOptions(bool)
@@ -214,10 +196,10 @@ cdef extern from "<fst/fstlib.h>" namespace "fst" nogil:
     string FindSymbol "Find"(int64)
 
     # Aliased for overload.
-    int64 FindIndex "Find"(string)
+    int64 FindIndex "Find"(const string &)
 
     # Aliased for overload.
-    bool MemberSymbol "Member"(string)
+    bool MemberSymbol "Member"(const string &)
 
     # Aliased for overload.
     bool MemberIndex "Member"(int64)
@@ -238,10 +220,6 @@ cdef extern from "<fst/fstlib.h>" namespace "fst" nogil:
 
     bool Write(const string &)
 
-    bool WriteToString(ostream &)
-
-    bool WriteToString(const string &)
-
     bool WriteText(ostream &)
 
     bool WriteText(const string &)
@@ -250,7 +228,6 @@ cdef extern from "<fst/fstlib.h>" namespace "fst" nogil:
 
     size_t NumSymbols()
 
-
   SymbolTable *CompactSymbolTable(const SymbolTable &syms)
 
   SymbolTable *MergeSymbolTable(const SymbolTable &, const SymbolTable &,
@@ -258,7 +235,6 @@ cdef extern from "<fst/fstlib.h>" namespace "fst" nogil:
 
   SymbolTable *FstReadSymbols(const string &, bool)
 
-
   cdef cppclass SymbolTableIterator:
 
     SymbolTableIterator(const SymbolTable &)
@@ -276,8 +252,6 @@ cdef extern from "<fst/fstlib.h>" namespace "fst" nogil:
 
 cdef extern from "<fst/script/fstscript.h>" namespace "fst::script" nogil:
 
-
-  # Weights.
   cdef cppclass WeightClass:
 
     WeightClass()
@@ -315,7 +289,6 @@ cdef extern from "<fst/script/fstscript.h>" namespace "fst::script" nogil:
 
   cdef WeightClass Power(const WeightClass &, size_t)
 
-  # Arcs.
   cdef cppclass ArcClass:
 
     ArcClass(const ArcClass &)
@@ -327,10 +300,6 @@ cdef extern from "<fst/script/fstscript.h>" namespace "fst::script" nogil:
     WeightClass weight
     int64 nextstate
 
-
-  # FSTs.
-
-
   cdef cppclass FstClass:
 
     FstClass(const FstClass &)
@@ -370,7 +339,6 @@ cdef extern from "<fst/script/fstscript.h>" namespace "fst::script" nogil:
 
     bool ValidStateId(int64)
 
-
   cdef cppclass MutableFstClass(FstClass):
 
     bool AddArc(int64, const ArcClass &)
@@ -413,8 +381,6 @@ cdef extern from "<fst/script/fstscript.h>" namespace "fst::script" nogil:
 
    VectorFstClass(const string &)
 
-
-  # EncodeMapper.
   cdef cppclass EncodeMapperClass:
 
     EncodeMapperClass(const string &, uint32, EncodeType)
@@ -424,11 +390,23 @@ cdef extern from "<fst/script/fstscript.h>" namespace "fst::script" nogil:
 
     const string &ArcType()
 
+    const string &WeightType()
+
     uint32 Flags()
 
     uint64 Properties(uint64)
 
-    EncodeType Type()
+    @staticmethod
+    EncodeMapperClass *Read(const string &)
+
+    # Aliased for overload.
+    @staticmethod
+    EncodeMapperClass *ReadStream "Read"(istream &, const string &)
+
+    bool Write(const string &)
+
+    # Aliased for overload.
+    bool WriteStream "Write"(ostream &, const string &)
 
     const SymbolTable *InputSymbols()
 
@@ -438,12 +416,6 @@ cdef extern from "<fst/script/fstscript.h>" namespace "fst::script" nogil:
 
     void SetOutputSymbols(const SymbolTable *)
 
-    const string &WeightType()
-
-
-  # Iterators.
-
-
   cdef cppclass ArcIteratorClass:
 
     ArcIteratorClass(const FstClass &, int64)
@@ -460,9 +432,9 @@ cdef extern from "<fst/script/fstscript.h>" namespace "fst::script" nogil:
 
     size_t Position()
 
-    uint32 Flags()
+    uint8 Flags()
 
-    void SetFlags(uint32, uint32)
+    void SetFlags(uint8, uint8)
 
   cdef cppclass MutableArcIteratorClass:
 
@@ -482,9 +454,9 @@ cdef extern from "<fst/script/fstscript.h>" namespace "fst::script" nogil:
 
     size_t Position()
 
-    uint32 Flags()
+    uint8 Flags()
 
-    void SetFlags(uint32, uint32)
+    void SetFlags(uint8, uint8)
 
   cdef cppclass StateIteratorClass:
 
@@ -522,10 +494,17 @@ cdef extern from "<fst/script/fstscript.h>" namespace "fst::script" nogil:
 
   cdef void Closure(MutableFstClass *, ClosureType)
 
-  cdef FstClass *CompileFstInternal(istream &, const string &,
-                                    const string &, const string &,
-                                    const SymbolTable *, const SymbolTable *,
-                                    const SymbolTable*, bool, bool, bool, bool,
+  cdef FstClass *CompileFstInternal(istream &,
+                                    const string &,
+                                    const string &,
+                                    const string &,
+                                    const SymbolTable *,
+                                    const SymbolTable *,
+                                    const SymbolTable*,
+                                    bool,
+                                    bool,
+                                    bool,
+                                    bool,
                                     bool)
 
   cdef void Compose(FstClass &, FstClass &, MutableFstClass *,
@@ -541,26 +520,48 @@ cdef extern from "<fst/script/fstscript.h>" namespace "fst::script" nogil:
 
   cdef cppclass DeterminizeOptions:
 
-    DeterminizeOptions(float, const WeightClass &, int64, int64,
-                       DeterminizeType, bool)
+    DeterminizeOptions(float,
+                       const WeightClass &,
+                       int64,
+                       int64,
+                       DeterminizeType,
+                       bool)
 
-  cdef void Determinize(const FstClass &, MutableFstClass *,
+  cdef void Determinize(const FstClass &,
+                        MutableFstClass *,
                         const DeterminizeOptions &)
 
   cdef cppclass DisambiguateOptions:
 
     DisambiguateOptions(float, const WeightClass &, int64, int64)
 
-  cdef void Disambiguate(const FstClass &, MutableFstClass *,
+  cdef void Disambiguate(const FstClass &,
+                         MutableFstClass *,
                          const DisambiguateOptions &)
 
-  cdef void Difference(const FstClass &, const FstClass &, MutableFstClass *,
+  cdef void Difference(const FstClass &,
+                       const FstClass &,
+                       MutableFstClass *,
                        const ComposeOptions &)
 
-  cdef void DrawFst(const FstClass &fst, const SymbolTable *,
-                    const SymbolTable *, const SymbolTable *, bool,
-                    const string &, float, float, bool, bool, float, float, int,
-                    int, const string &, bool, ostream *, const string &)
+  cdef void Draw(const FstClass &fst,
+                 const SymbolTable *,
+                 const SymbolTable *,
+                 const SymbolTable *,
+                 bool,
+                 const string &,
+                 float,
+                 float,
+                 bool,
+                 bool,
+                 float,
+                 float,
+                 int,
+                 int,
+                 const string &,
+                 bool,
+                 ostream &,
+                 const string &)
 
   cdef void Encode(MutableFstClass *, EncodeMapperClass *)
 
@@ -572,7 +573,9 @@ cdef extern from "<fst/script/fstscript.h>" namespace "fst::script" nogil:
 
   cdef bool Equivalent(const FstClass &, const FstClass &, float)
 
-  cdef void Intersect(const FstClass &, const FstClass &, MutableFstClass *,
+  cdef void Intersect(const FstClass &,
+                      const FstClass &,
+                      MutableFstClass *,
                       const ComposeOptions &)
 
   cdef void Invert(MutableFstClass *fst)
@@ -594,7 +597,10 @@ cdef extern from "<fst/script/fstscript.h>" namespace "fst::script" nogil:
     TO_LOG64_MAPPER
     TO_STD_MAPPER
 
-  cdef FstClass *Map(const FstClass &, MapType, float, double,
+  cdef FstClass *Map(const FstClass &,
+                     MapType,
+                     float,
+                     double,
                      const WeightClass &)
 
   cdef void Minimize(MutableFstClass *, MutableFstClass *, float, bool)
@@ -603,16 +609,26 @@ cdef extern from "<fst/script/fstscript.h>" namespace "fst::script" nogil:
 
   cdef void Project(MutableFstClass *, ProjectType)
 
-  cdef void PrintFst(const FstClass &, ostream &, const string &,
-                     const SymbolTable *, const SymbolTable *,
-                     const SymbolTable *, bool, bool, const string &)
-
-  cdef void Prune(const FstClass &, MutableFstClass *, const WeightClass &,
+  cdef void Print(const FstClass &,
+                  ostream &,
+                  const string &,
+                  const SymbolTable *,
+                  const SymbolTable *,
+                  const SymbolTable *,
+                  bool,
+                  bool,
+                  const string &)
+
+  cdef void Prune(const FstClass &,
+                  MutableFstClass *,
+                  const WeightClass &,
                   int64, float)
 
   cdef void Prune(MutableFstClass *, const WeightClass &, int64, float)
 
-  cdef void Push(const FstClass &, MutableFstClass *, uint32 flags,
+  cdef void Push(const FstClass &,
+                 MutableFstClass *,
+                 uint8 flags,
                  ReweightType, float)
 
   cdef void Push(MutableFstClass *, ReweightType, float, bool)
@@ -622,30 +638,43 @@ cdef extern from "<fst/script/fstscript.h>" namespace "fst::script" nogil:
     LOG_PROB_ARC_SELECTOR
     FAST_LOG_PROB_ARC_SELECTOR
 
-  cdef bool RandEquivalent(const FstClass &, const FstClass &, int32, float,
-                           time_t, const RandGenOptions[RandArcSelection] &)
+  cdef bool RandEquivalent(const FstClass &,
+                           const FstClass &,
+                           int32,
+                           float,
+                           time_t,
+                           const RandGenOptions[RandArcSelection] &)
 
-  cdef void RandGen(const FstClass &, MutableFstClass *, time_t,
+  cdef void RandGen(const FstClass &,
+                    MutableFstClass *,
+                    time_t,
                     const RandGenOptions[RandArcSelection] &)
 
-  cdef void Relabel(MutableFstClass *, const SymbolTable *,
-                    const SymbolTable *, const string &, bool,
-                    const SymbolTable *, const SymbolTable *, const string &,
+  cdef void Relabel(MutableFstClass *,
+                    const SymbolTable *,
+                    const SymbolTable *,
+                    const string &, bool,
+                    const SymbolTable *,
+                    const SymbolTable *,
+                    const string &,
                     bool)
 
-  cdef void Relabel(MutableFstClass *, const vector[LabelPair] &,
+  cdef void Relabel(MutableFstClass *,
+                    const vector[LabelPair] &,
                     const vector[LabelPair] &)
 
   cdef cppclass ReplaceOptions:
 
      ReplaceOptions(int64, ReplaceLabelType, ReplaceLabelType, int64)
 
-  cdef void Replace(const vector[LabelFstClassPair] &, MutableFstClass *,
+  cdef void Replace(const vector[LabelFstClassPair] &,
+                    MutableFstClass *,
                     const ReplaceOptions &)
 
   cdef void Reverse(const FstClass &, MutableFstClass *, bool)
 
-  cdef void Reweight(MutableFstClass *, const vector[WeightClass] &,
+  cdef void Reweight(MutableFstClass *,
+                     const vector[WeightClass] &,
                      ReweightType)
 
   cdef cppclass RmEpsilonOptions:
@@ -658,25 +687,32 @@ cdef extern from "<fst/script/fstscript.h>" namespace "fst::script" nogil:
 
     ShortestDistanceOptions(QueueType, ArcFilterType, int64, float)
 
-  cdef void ShortestDistance(const FstClass &, vector[WeightClass] *,
+  cdef void ShortestDistance(const FstClass &,
+                             vector[WeightClass] *,
                              const ShortestDistanceOptions &)
 
-  cdef void ShortestDistance(const FstClass &, vector[WeightClass] *, bool,
+  cdef void ShortestDistance(const FstClass &,
+                             vector[WeightClass] *, bool,
                              float)
 
   cdef cppclass ShortestPathOptions:
 
-    ShortestPathOptions(QueueType, int32, bool, float, const WeightClass &,
+    ShortestPathOptions(QueueType,
+                        int32,
+                        bool,
+                        float,
+                        const WeightClass &,
                         int64)
 
-  cdef void ShortestPath(const FstClass &, MutableFstClass *,
+  cdef void ShortestPath(const FstClass &,
+                         MutableFstClass *,
                          const ShortestPathOptions &)
 
   cdef void Synchronize(const FstClass &, MutableFstClass *)
 
   cdef bool TopSort(MutableFstClass *)
 
-  cdef void Union(MutableFstClass *, const FstClass &)
+  cdef void Union(MutableFstClass *, const vector[FstClass *] &)
 
   cdef bool Verify(const FstClass &)
 
@@ -689,11 +725,11 @@ cdef extern from "<fst/script/getters.h>" namespace "fst::script" nogil:
 
   cdef bool GetDeterminizeType(const string &, DeterminizeType *)
 
-  cdef uint32 GetEncodeFlags(bool, bool)
+  cdef uint8 GetEncodeFlags(bool, bool)
 
   cdef bool GetMapType(const string &, MapType *)
 
-  cdef uint32 GetPushFlags(bool, bool, bool, bool)
+  cdef uint8 GetPushFlags(bool, bool, bool, bool)
 
   cdef bool GetQueueType(const string &, QueueType *)
 
@@ -749,7 +785,6 @@ cdef extern from "<fst/extensions/far/far-class.h>" \
     FarType Type()
 
     # For simplicity, we always use the multiple-file one.
-
     @staticmethod
     FarReaderClass *Open(const vector[string] &)
 
diff --git a/src/extensions/python/memory.pxd b/src/extensions/python/memory.pxd
deleted file mode 100644 (file)
index 9b42edd..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-# See www.openfst.org for extensive documentation on this weighted
-# finite-state transducer library.
-
-
-from libcpp.memory cimport shared_ptr
-
-
-# This is mysteriously missing from libcpp.memory.
-
-cdef extern from "<memory>" namespace "std" nogil:
-
-  shared_ptr[T] static_pointer_cast[T, U](const shared_ptr[U] &)
index b76b855..c91b462 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by Cython 0.29.12 */
+/* Generated by Cython 0.29.13 */
 
 #define PY_SSIZE_T_CLEAN
 #include "Python.h"
@@ -7,8 +7,8 @@
 #elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000)
     #error Cython requires Python 2.6+ or Python 3.3+.
 #else
-#define CYTHON_ABI "0_29_12"
-#define CYTHON_HEX_VERSION 0x001D0CF0
+#define CYTHON_ABI "0_29_13"
+#define CYTHON_HEX_VERSION 0x001D0DF0
 #define CYTHON_FUTURE_DIVISION 1
 #include <stddef.h>
 #ifndef offsetof
@@ -614,10 +614,10 @@ static CYTHON_INLINE float __PYX_NAN() {
 #include "stdexcept"
 #include "typeinfo"
 #include <memory>
-#include <utility>
-#include <vector>
 #include <string.h>
 #include <string>
+#include <utility>
+#include <vector>
 #include <stdint.h>
 #include <iostream>
 #include <fstream>
@@ -933,7 +933,7 @@ struct __pyx_obj_9pywrapfst_FarReader;
 struct __pyx_obj_9pywrapfst_FarWriter;
 struct __pyx_obj_9pywrapfst___pyx_scope_struct____iter__;
 
-/* "fst.pxd":516
+/* "fst.pxd":488
  * 
  * 
  * ctypedef pair[int64, const FstClass *] LabelFstClassPair             # <<<<<<<<<<<<<<
@@ -942,7 +942,7 @@ struct __pyx_obj_9pywrapfst___pyx_scope_struct____iter__;
  */
 typedef std::pair<__pyx_t_10basictypes_int64,fst::script::FstClass const *>  __pyx_t_3fst_LabelFstClassPair;
 
-/* "fst.pxd":518
+/* "fst.pxd":490
  * ctypedef pair[int64, const FstClass *] LabelFstClassPair
  * 
  * ctypedef pair[int64, int64] LabelPair             # <<<<<<<<<<<<<<
@@ -988,7 +988,7 @@ struct __pyx_opt_args_9pywrapfst_reverse;
 struct __pyx_opt_args_9pywrapfst__shortestdistance;
 struct __pyx_opt_args_9pywrapfst_shortestpath;
 
-/* "pywrapfst.pxd":100
+/* "pywrapfst.pxd":103
  * # SymbolTable.
  * 
  * ctypedef fst.SymbolTable * SymbolTable_ptr             # <<<<<<<<<<<<<<
@@ -997,7 +997,7 @@ struct __pyx_opt_args_9pywrapfst_shortestpath;
  */
 typedef fst::SymbolTable *__pyx_t_9pywrapfst_SymbolTable_ptr;
 
-/* "pywrapfst.pxd":142
+/* "pywrapfst.pxd":145
  * cdef class _MutableSymbolTable(_SymbolTable):
  * 
  *   cpdef int64 add_symbol(self, symbol, int64 key=?)             # <<<<<<<<<<<<<<
@@ -1009,26 +1009,35 @@ struct __pyx_opt_args_9pywrapfst_19_MutableSymbolTable_add_symbol {
   __pyx_t_10basictypes_int64 key;
 };
 
-/* "pywrapfst.pxd":220
+/* "pywrapfst.pxd":233
  * 
  * 
  * ctypedef fst.FstClass * FstClass_ptr             # <<<<<<<<<<<<<<
+ * ctypedef const fst.FstClass * const_FstClass_ptr
  * ctypedef fst.MutableFstClass * MutableFstClass_ptr
- * ctypedef fst.VectorFstClass * VectorFstClass_ptr
  */
 typedef fst::script::FstClass *__pyx_t_9pywrapfst_FstClass_ptr;
 
-/* "pywrapfst.pxd":221
+/* "pywrapfst.pxd":234
  * 
  * ctypedef fst.FstClass * FstClass_ptr
+ * ctypedef const fst.FstClass * const_FstClass_ptr             # <<<<<<<<<<<<<<
+ * ctypedef fst.MutableFstClass * MutableFstClass_ptr
+ * ctypedef fst.VectorFstClass * VectorFstClass_ptr
+ */
+typedef fst::script::FstClass const *__pyx_t_9pywrapfst_const_FstClass_ptr;
+
+/* "pywrapfst.pxd":235
+ * ctypedef fst.FstClass * FstClass_ptr
+ * ctypedef const fst.FstClass * const_FstClass_ptr
  * ctypedef fst.MutableFstClass * MutableFstClass_ptr             # <<<<<<<<<<<<<<
  * ctypedef fst.VectorFstClass * VectorFstClass_ptr
  * 
  */
 typedef fst::script::MutableFstClass *__pyx_t_9pywrapfst_MutableFstClass_ptr;
 
-/* "pywrapfst.pxd":222
- * ctypedef fst.FstClass * FstClass_ptr
+/* "pywrapfst.pxd":236
+ * ctypedef const fst.FstClass * const_FstClass_ptr
  * ctypedef fst.MutableFstClass * MutableFstClass_ptr
  * ctypedef fst.VectorFstClass * VectorFstClass_ptr             # <<<<<<<<<<<<<<
  * 
@@ -1036,18 +1045,18 @@ typedef fst::script::MutableFstClass *__pyx_t_9pywrapfst_MutableFstClass_ptr;
  */
 typedef fst::script::VectorFstClass *__pyx_t_9pywrapfst_VectorFstClass_ptr;
 
-/* "pywrapfst.pxd":238
+/* "pywrapfst.pxd":252
  *   cpdef _Fst copy(self)
  * 
- *   cpdef void draw(self, filename, _SymbolTable isymbols=?,             # <<<<<<<<<<<<<<
- *                   _SymbolTable osymbols=?, SymbolTable ssymbols=?,
- *                   bool acceptor=?, title=?, double width=?,
+ *   cpdef void draw(self,             # <<<<<<<<<<<<<<
+ *                   source,
+ *                   _SymbolTable isymbols=?,
  */
 struct __pyx_opt_args_9pywrapfst_4_Fst_draw {
   int __pyx_n;
   struct __pyx_obj_9pywrapfst__SymbolTable *isymbols;
   struct __pyx_obj_9pywrapfst__SymbolTable *osymbols;
-  struct __pyx_obj_9pywrapfst_SymbolTable *ssymbols;
+  struct __pyx_obj_9pywrapfst__SymbolTable *ssymbols;
   bool acceptor;
   PyObject *title;
   double width;
@@ -1062,12 +1071,12 @@ struct __pyx_opt_args_9pywrapfst_4_Fst_draw {
   bool show_weight_one;
 };
 
-/* "pywrapfst.pxd":266
+/* "pywrapfst.pxd":290
  *   cpdef StateIterator states(self)
  * 
- *   cpdef string text(self, _SymbolTable isymbols=?, _SymbolTable osymbols=?,             # <<<<<<<<<<<<<<
- *                     _SymbolTable ssymbols=?, bool acceptor=?,
- *                     bool show_weight_one=?, missing_sym=?)
+ *   cpdef string text(self,             # <<<<<<<<<<<<<<
+ *                     _SymbolTable isymbols=?,
+ *                     _SymbolTable osymbols=?,
  */
 struct __pyx_opt_args_9pywrapfst_4_Fst_text {
   int __pyx_n;
@@ -1079,7 +1088,7 @@ struct __pyx_opt_args_9pywrapfst_4_Fst_text {
   PyObject *missing_sym;
 };
 
-/* "pywrapfst.pxd":291
+/* "pywrapfst.pxd":319
  *   cpdef void add_states(self, size_t) except *
  * 
  *   cdef void _arcsort(self, sort_type=?) except *             # <<<<<<<<<<<<<<
@@ -1091,19 +1100,19 @@ struct __pyx_opt_args_9pywrapfst_11_MutableFst__arcsort {
   PyObject *sort_type;
 };
 
-/* "pywrapfst.pxd":293
+/* "pywrapfst.pxd":321
  *   cdef void _arcsort(self, sort_type=?) except *
  * 
  *   cdef void _closure(self, bool closure_plus=?) except *             # <<<<<<<<<<<<<<
  * 
- *   cdef void _concat(self, _Fst ifst) except *
+ *   cdef void _concat(self, _Fst fst2) except *
  */
 struct __pyx_opt_args_9pywrapfst_11_MutableFst__closure {
   int __pyx_n;
   bool closure_plus;
 };
 
-/* "pywrapfst.pxd":301
+/* "pywrapfst.pxd":329
  *   cdef void _decode(self, EncodeMapper) except *
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=?) except *             # <<<<<<<<<<<<<<
@@ -1115,7 +1124,7 @@ struct __pyx_opt_args_9pywrapfst_11_MutableFst__delete_arcs {
   size_t n;
 };
 
-/* "pywrapfst.pxd":303
+/* "pywrapfst.pxd":331
  *   cdef void _delete_arcs(self, int64 state, size_t n=?) except *
  * 
  *   cdef void _delete_states(self, states=?) except *             # <<<<<<<<<<<<<<
@@ -1127,7 +1136,7 @@ struct __pyx_opt_args_9pywrapfst_11_MutableFst__delete_states {
   PyObject *states;
 };
 
-/* "pywrapfst.pxd":309
+/* "pywrapfst.pxd":337
  *   cdef void _invert(self) except *
  * 
  *   cdef void _minimize(self, float delta=?, bool allow_nondet=?) except *             # <<<<<<<<<<<<<<
@@ -1140,7 +1149,7 @@ struct __pyx_opt_args_9pywrapfst_11_MutableFst__minimize {
   bool allow_nondet;
 };
 
-/* "pywrapfst.pxd":315
+/* "pywrapfst.pxd":343
  *   cpdef int64 num_states(self)
  * 
  *   cdef void _project(self, bool project_output=?) except *             # <<<<<<<<<<<<<<
@@ -1152,12 +1161,12 @@ struct __pyx_opt_args_9pywrapfst_11_MutableFst__project {
   bool project_output;
 };
 
-/* "pywrapfst.pxd":317
+/* "pywrapfst.pxd":345
  *   cdef void _project(self, bool project_output=?) except *
  * 
  *   cdef void _prune(self, float delta=?, int64 nstate=?, weight=?) except *             # <<<<<<<<<<<<<<
  * 
- *   cdef void _push(self, float delta=?, bool remove_total_weight=?,
+ *   cdef void _push(self,
  */
 struct __pyx_opt_args_9pywrapfst_11_MutableFst__prune {
   int __pyx_n;
@@ -1166,12 +1175,12 @@ struct __pyx_opt_args_9pywrapfst_11_MutableFst__prune {
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":319
+/* "pywrapfst.pxd":347
  *   cdef void _prune(self, float delta=?, int64 nstate=?, weight=?) except *
  * 
- *   cdef void _push(self, float delta=?, bool remove_total_weight=?,             # <<<<<<<<<<<<<<
- *                   bool to_final=?) except *
- * 
+ *   cdef void _push(self,             # <<<<<<<<<<<<<<
+ *                   float delta=?,
+ *                   bool remove_total_weight=?,
  */
 struct __pyx_opt_args_9pywrapfst_11_MutableFst__push {
   int __pyx_n;
@@ -1180,12 +1189,12 @@ struct __pyx_opt_args_9pywrapfst_11_MutableFst__push {
   bool to_final;
 };
 
-/* "pywrapfst.pxd":322
+/* "pywrapfst.pxd":352
  *                   bool to_final=?) except *
  * 
  *   cdef void _relabel_pairs(self, ipairs=?, opairs=?) except *             # <<<<<<<<<<<<<<
  * 
- *   cdef void _relabel_tables(self, _SymbolTable old_isymbols=?,
+ *   cdef void _relabel_tables(self,
  */
 struct __pyx_opt_args_9pywrapfst_11_MutableFst__relabel_pairs {
   int __pyx_n;
@@ -1193,12 +1202,12 @@ struct __pyx_opt_args_9pywrapfst_11_MutableFst__relabel_pairs {
   PyObject *opairs;
 };
 
-/* "pywrapfst.pxd":324
+/* "pywrapfst.pxd":354
  *   cdef void _relabel_pairs(self, ipairs=?, opairs=?) except *
  * 
- *   cdef void _relabel_tables(self, _SymbolTable old_isymbols=?,             # <<<<<<<<<<<<<<
- *       _SymbolTable new_isymbols=?, unknown_isymbol=?,
- *       bool attach_new_isymbols=?,
+ *   cdef void _relabel_tables(self,             # <<<<<<<<<<<<<<
+ *                             _SymbolTable old_isymbols=?,
+ *                             _SymbolTable new_isymbols=?,
  */
 struct __pyx_opt_args_9pywrapfst_11_MutableFst__relabel_tables {
   int __pyx_n;
@@ -1212,24 +1221,24 @@ struct __pyx_opt_args_9pywrapfst_11_MutableFst__relabel_tables {
   bool attach_new_osymbols;
 };
 
-/* "pywrapfst.pxd":334
+/* "pywrapfst.pxd":368
  *   cdef void _reserve_states(self, int64 n) except *
  * 
  *   cdef void _reweight(self, potentials, bool to_final=?) except *             # <<<<<<<<<<<<<<
  * 
- *   cdef void _rmepsilon(self, queue_type=?, bool connect=?, weight=?,
+ *   cdef void _rmepsilon(self,
  */
 struct __pyx_opt_args_9pywrapfst_11_MutableFst__reweight {
   int __pyx_n;
   bool to_final;
 };
 
-/* "pywrapfst.pxd":336
+/* "pywrapfst.pxd":370
  *   cdef void _reweight(self, potentials, bool to_final=?) except *
  * 
- *   cdef void _rmepsilon(self, queue_type=?, bool connect=?, weight=?,             # <<<<<<<<<<<<<<
- *                        int64 nstate=?, float delta=?) except *
- * 
+ *   cdef void _rmepsilon(self,             # <<<<<<<<<<<<<<
+ *                        queue_type=?,
+ *                        bool connect=?,
  */
 struct __pyx_opt_args_9pywrapfst_11_MutableFst__rmepsilon {
   int __pyx_n;
@@ -1240,8 +1249,8 @@ struct __pyx_opt_args_9pywrapfst_11_MutableFst__rmepsilon {
   float delta;
 };
 
-/* "pywrapfst.pxd":339
- *                        int64 nstate=?, float delta=?) except *
+/* "pywrapfst.pxd":377
+ *                        float delta=?) except *
  * 
  *   cdef void _set_final(self, int64 state, weight=?) except *             # <<<<<<<<<<<<<<
  * 
@@ -1252,24 +1261,24 @@ struct __pyx_opt_args_9pywrapfst_11_MutableFst__set_final {
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":363
+/* "pywrapfst.pxd":399
  * cdef _Fst _init_XFst(FstClass_ptr tfst)
  * 
  * cdef _MutableFst _create_Fst(arc_type=?)             # <<<<<<<<<<<<<<
  * 
- * cpdef _Fst _read(filename)
+ * cpdef _Fst _read(source)
  */
 struct __pyx_opt_args_9pywrapfst__create_Fst {
   int __pyx_n;
   PyObject *arc_type;
 };
 
-/* "pywrapfst.pxd":446
+/* "pywrapfst.pxd":482
  * 
  * 
  * cdef _Fst _map(_Fst ifst, float delta=?, map_type=?, double power=?, weight=?)             # <<<<<<<<<<<<<<
  * 
- * cpdef _Fst arcmap(_Fst ifst, float delta=?, map_type=?, double power=?,
+ * cpdef _Fst arcmap(_Fst ifst,
  */
 struct __pyx_opt_args_9pywrapfst__map {
   int __pyx_n;
@@ -1279,12 +1288,12 @@ struct __pyx_opt_args_9pywrapfst__map {
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":448
+/* "pywrapfst.pxd":484
  * cdef _Fst _map(_Fst ifst, float delta=?, map_type=?, double power=?, weight=?)
  * 
- * cpdef _Fst arcmap(_Fst ifst, float delta=?, map_type=?, double power=?,             # <<<<<<<<<<<<<<
- *                   weight=?)
- * 
+ * cpdef _Fst arcmap(_Fst ifst,             # <<<<<<<<<<<<<<
+ *                   float delta=?,
+ *                   map_type=?,
  */
 struct __pyx_opt_args_9pywrapfst_arcmap {
   int __pyx_n;
@@ -1294,12 +1303,12 @@ struct __pyx_opt_args_9pywrapfst_arcmap {
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":451
+/* "pywrapfst.pxd":490
  *                   weight=?)
  * 
- * cpdef _MutableFst compose(_Fst ifst1, _Fst ifst2, compose_filter=?,             # <<<<<<<<<<<<<<
- *                           bool connect=?)
- * 
+ * cpdef _MutableFst compose(_Fst ifst1,             # <<<<<<<<<<<<<<
+ *                           _Fst ifst2,
+ *                           compose_filter=?,
  */
 struct __pyx_opt_args_9pywrapfst_compose {
   int __pyx_n;
@@ -1307,24 +1316,24 @@ struct __pyx_opt_args_9pywrapfst_compose {
   bool connect;
 };
 
-/* "pywrapfst.pxd":454
+/* "pywrapfst.pxd":495
  *                           bool connect=?)
  * 
  * cpdef _Fst convert(_Fst ifst, fst_type=?)             # <<<<<<<<<<<<<<
  * 
- * cpdef _MutableFst determinize(_Fst ifst, float delta=?, det_type=?,
+ * cpdef _MutableFst determinize(_Fst ifst,
  */
 struct __pyx_opt_args_9pywrapfst_convert {
   int __pyx_n;
   PyObject *fst_type;
 };
 
-/* "pywrapfst.pxd":456
+/* "pywrapfst.pxd":497
  * cpdef _Fst convert(_Fst ifst, fst_type=?)
  * 
- * cpdef _MutableFst determinize(_Fst ifst, float delta=?, det_type=?,             # <<<<<<<<<<<<<<
- *                               int64 nstate=?, int64 subsequential_label=?,
- *                               weight=?, bool increment_subsequential_label=?)
+ * cpdef _MutableFst determinize(_Fst ifst,             # <<<<<<<<<<<<<<
+ *                               float delta=?,
+ *                               det_type=?,
  */
 struct __pyx_opt_args_9pywrapfst_determinize {
   int __pyx_n;
@@ -1336,12 +1345,12 @@ struct __pyx_opt_args_9pywrapfst_determinize {
   bool increment_subsequential_label;
 };
 
-/* "pywrapfst.pxd":460
- *                               weight=?, bool increment_subsequential_label=?)
- * 
- * cpdef _MutableFst difference(_Fst ifst1, _Fst ifst2, compose_filter=?,             # <<<<<<<<<<<<<<
- *                              bool connect=?)
+/* "pywrapfst.pxd":505
+ *                               bool increment_subsequential_label=?)
  * 
+ * cpdef _MutableFst difference(_Fst ifst1,             # <<<<<<<<<<<<<<
+ *                              _Fst ifst2,
+ *                              compose_filter=?,
  */
 struct __pyx_opt_args_9pywrapfst_difference {
   int __pyx_n;
@@ -1349,12 +1358,12 @@ struct __pyx_opt_args_9pywrapfst_difference {
   bool connect;
 };
 
-/* "pywrapfst.pxd":463
+/* "pywrapfst.pxd":510
  *                              bool connect=?)
  * 
- * cpdef _MutableFst disambiguate(_Fst ifst, float delta=?, int64 nstate=?,             # <<<<<<<<<<<<<<
- *                                int64 subsequential_label=?, weight=?)
- * 
+ * cpdef _MutableFst disambiguate(_Fst ifst,             # <<<<<<<<<<<<<<
+ *                                float delta=?,
+ *                                int64 nstate=?,
  */
 struct __pyx_opt_args_9pywrapfst_disambiguate {
   int __pyx_n;
@@ -1364,8 +1373,8 @@ struct __pyx_opt_args_9pywrapfst_disambiguate {
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":466
- *                                int64 subsequential_label=?, weight=?)
+/* "pywrapfst.pxd":516
+ *                                weight=?)
  * 
  * cpdef _MutableFst epsnormalize(_Fst ifst, bool eps_norm_output=?)             # <<<<<<<<<<<<<<
  * 
@@ -1376,7 +1385,7 @@ struct __pyx_opt_args_9pywrapfst_epsnormalize {
   bool eps_norm_output;
 };
 
-/* "pywrapfst.pxd":468
+/* "pywrapfst.pxd":518
  * cpdef _MutableFst epsnormalize(_Fst ifst, bool eps_norm_output=?)
  * 
  * cpdef bool equal(_Fst ifst1, _Fst ifst2, float delta=?)             # <<<<<<<<<<<<<<
@@ -1388,24 +1397,24 @@ struct __pyx_opt_args_9pywrapfst_equal {
   float delta;
 };
 
-/* "pywrapfst.pxd":470
+/* "pywrapfst.pxd":520
  * cpdef bool equal(_Fst ifst1, _Fst ifst2, float delta=?)
  * 
  * cpdef bool equivalent(_Fst ifst1, _Fst ifst2, float delta=?) except *             # <<<<<<<<<<<<<<
  * 
- * cpdef _MutableFst intersect(_Fst ifst1, _Fst ifst2, compose_filter=?,
+ * cpdef _MutableFst intersect(_Fst ifst1,
  */
 struct __pyx_opt_args_9pywrapfst_equivalent {
   int __pyx_n;
   float delta;
 };
 
-/* "pywrapfst.pxd":472
+/* "pywrapfst.pxd":522
  * cpdef bool equivalent(_Fst ifst1, _Fst ifst2, float delta=?) except *
  * 
- * cpdef _MutableFst intersect(_Fst ifst1, _Fst ifst2, compose_filter=?,             # <<<<<<<<<<<<<<
- *                             bool connect=?)
- * 
+ * cpdef _MutableFst intersect(_Fst ifst1,             # <<<<<<<<<<<<<<
+ *                             _Fst ifst2,
+ *                             compose_filter=?,
  */
 struct __pyx_opt_args_9pywrapfst_intersect {
   int __pyx_n;
@@ -1413,24 +1422,24 @@ struct __pyx_opt_args_9pywrapfst_intersect {
   bool connect;
 };
 
-/* "pywrapfst.pxd":475
+/* "pywrapfst.pxd":527
  *                             bool connect=?)
  * 
  * cpdef bool isomorphic(_Fst ifst1, _Fst ifst2, float delta=?)             # <<<<<<<<<<<<<<
  * 
- * cpdef _MutableFst prune(_Fst ifst, float delta=?, int64 nstate=?,
+ * cpdef _MutableFst prune(_Fst ifst,
  */
 struct __pyx_opt_args_9pywrapfst_isomorphic {
   int __pyx_n;
   float delta;
 };
 
-/* "pywrapfst.pxd":477
+/* "pywrapfst.pxd":529
  * cpdef bool isomorphic(_Fst ifst1, _Fst ifst2, float delta=?)
  * 
- * cpdef _MutableFst prune(_Fst ifst, float delta=?, int64 nstate=?,             # <<<<<<<<<<<<<<
- *                         weight=?)
- * 
+ * cpdef _MutableFst prune(_Fst ifst,             # <<<<<<<<<<<<<<
+ *                         float delta=?,
+ *                         int64 nstate=?,
  */
 struct __pyx_opt_args_9pywrapfst_prune {
   int __pyx_n;
@@ -1439,12 +1448,12 @@ struct __pyx_opt_args_9pywrapfst_prune {
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":480
+/* "pywrapfst.pxd":534
  *                         weight=?)
  * 
- * cpdef _MutableFst push(_Fst ifst, float delta=?, bool push_weights=?,             # <<<<<<<<<<<<<<
- *                        bool push_labels=?, bool remove_common_affix=?,
- *                        bool remove_total_weight=?, bool to_final=?)
+ * cpdef _MutableFst push(_Fst ifst,             # <<<<<<<<<<<<<<
+ *                        float delta=?,
+ *                        bool push_weights=?,
  */
 struct __pyx_opt_args_9pywrapfst_push {
   int __pyx_n;
@@ -1456,12 +1465,12 @@ struct __pyx_opt_args_9pywrapfst_push {
   bool to_final;
 };
 
-/* "pywrapfst.pxd":484
- *                        bool remove_total_weight=?, bool to_final=?)
+/* "pywrapfst.pxd":542
+ *                        bool to_final=?)
  * 
- * cpdef bool randequivalent(_Fst ifst1, _Fst ifst2, int32 npath=?,             # <<<<<<<<<<<<<<
- *                           float delta=?, time_t seed=?, select=?,
- *                           int32 max_length=?) except *
+ * cpdef bool randequivalent(_Fst ifst1,             # <<<<<<<<<<<<<<
+ *                           _Fst ifst2,
+ *                           int32 npath=?,
  */
 struct __pyx_opt_args_9pywrapfst_randequivalent {
   int __pyx_n;
@@ -1472,12 +1481,12 @@ struct __pyx_opt_args_9pywrapfst_randequivalent {
   __pyx_t_10basictypes_int32 max_length;
 };
 
-/* "pywrapfst.pxd":488
+/* "pywrapfst.pxd":550
  *                           int32 max_length=?) except *
  * 
- * cpdef _MutableFst randgen(_Fst ifst, int32 npath=?, time_t seed=?,             # <<<<<<<<<<<<<<
- *                           select=?, int32 max_length=?,
- *                           bool remove_total_weight=?, bool weighted=?)
+ * cpdef _MutableFst randgen(_Fst ifst,             # <<<<<<<<<<<<<<
+ *                           int32 npath=?,
+ *                           time_t seed=?,
  */
 struct __pyx_opt_args_9pywrapfst_randgen {
   int __pyx_n;
@@ -1489,12 +1498,12 @@ struct __pyx_opt_args_9pywrapfst_randgen {
   bool weighted;
 };
 
-/* "pywrapfst.pxd":495
+/* "pywrapfst.pxd":562
  *     bool epsilon_on_replace) except *
  * 
- * cpdef _MutableFst replace(pairs, call_arc_labeling=?, return_arc_labeling=?,             # <<<<<<<<<<<<<<
- *                           bool epsilon_on_replace=?, int64 return_label=?)
- * 
+ * cpdef _MutableFst replace(pairs,             # <<<<<<<<<<<<<<
+ *                           call_arc_labeling=?,
+ *                           return_arc_labeling=?,
  */
 struct __pyx_opt_args_9pywrapfst_replace {
   int __pyx_n;
@@ -1504,24 +1513,24 @@ struct __pyx_opt_args_9pywrapfst_replace {
   __pyx_t_10basictypes_int64 return_label;
 };
 
-/* "pywrapfst.pxd":498
- *                           bool epsilon_on_replace=?, int64 return_label=?)
+/* "pywrapfst.pxd":568
+ *                           int64 return_label=?)
  * 
  * cpdef _MutableFst reverse(_Fst ifst, bool require_superinitial=?)             # <<<<<<<<<<<<<<
  * 
- * cdef vector[fst.WeightClass] *_shortestdistance(_Fst ifst, float delta=?,
+ * cdef vector[fst.WeightClass] *_shortestdistance(_Fst ifst,
  */
 struct __pyx_opt_args_9pywrapfst_reverse {
   int __pyx_n;
   bool require_superinitial;
 };
 
-/* "pywrapfst.pxd":500
+/* "pywrapfst.pxd":570
  * cpdef _MutableFst reverse(_Fst ifst, bool require_superinitial=?)
  * 
- * cdef vector[fst.WeightClass] *_shortestdistance(_Fst ifst, float delta=?,             # <<<<<<<<<<<<<<
- *                                                 int64 nstate=?, queue_type=?,
- *                                                 bool reverse=?) except *
+ * cdef vector[fst.WeightClass] *_shortestdistance(_Fst ifst,             # <<<<<<<<<<<<<<
+ *                                                 float delta=?,
+ *                                                 int64 nstate=?,
  */
 struct __pyx_opt_args_9pywrapfst__shortestdistance {
   int __pyx_n;
@@ -1531,12 +1540,12 @@ struct __pyx_opt_args_9pywrapfst__shortestdistance {
   bool reverse;
 };
 
-/* "pywrapfst.pxd":504
+/* "pywrapfst.pxd":576
  *                                                 bool reverse=?) except *
  * 
- * cpdef _MutableFst shortestpath(_Fst ifst, float delta=?, int32 nshortest=?,             # <<<<<<<<<<<<<<
- *                                int64 nstate=?, queue_type=?, bool unique=?,
- *                                weight=?)
+ * cpdef _MutableFst shortestpath(_Fst ifst,             # <<<<<<<<<<<<<<
+ *                                float delta=?,
+ *                                int32 nshortest=?,
  */
 struct __pyx_opt_args_9pywrapfst_shortestpath {
   int __pyx_n;
@@ -1548,7 +1557,7 @@ struct __pyx_opt_args_9pywrapfst_shortestpath {
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":68
+/* "pywrapfst.pxd":71
  * 
  * 
  * cdef class Weight(object):             # <<<<<<<<<<<<<<
@@ -1562,7 +1571,7 @@ struct __pyx_obj_9pywrapfst_Weight {
 };
 
 
-/* "pywrapfst.pxd":103
+/* "pywrapfst.pxd":106
  * 
  * 
  * cdef class _SymbolTable(object):             # <<<<<<<<<<<<<<
@@ -1576,20 +1585,20 @@ struct __pyx_obj_9pywrapfst__SymbolTable {
 };
 
 
-/* "pywrapfst.pxd":130
+/* "pywrapfst.pxd":133
  * 
  * 
  * cdef class _EncodeMapperSymbolTable(_SymbolTable):             # <<<<<<<<<<<<<<
  * 
- *   cdef shared_ptr[fst.EncodeMapperClass] _encoder
+ *   cdef shared_ptr[fst.EncodeMapperClass] _mapper
  */
 struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable {
   struct __pyx_obj_9pywrapfst__SymbolTable __pyx_base;
-  std::shared_ptr<fst::script::EncodeMapperClass>  _encoder;
+  std::shared_ptr<fst::script::EncodeMapperClass>  _mapper;
 };
 
 
-/* "pywrapfst.pxd":135
+/* "pywrapfst.pxd":138
  * 
  * 
  * cdef class _FstSymbolTable(_SymbolTable):             # <<<<<<<<<<<<<<
@@ -1602,7 +1611,7 @@ struct __pyx_obj_9pywrapfst__FstSymbolTable {
 };
 
 
-/* "pywrapfst.pxd":140
+/* "pywrapfst.pxd":143
  * 
  * 
  * cdef class _MutableSymbolTable(_SymbolTable):             # <<<<<<<<<<<<<<
@@ -1614,7 +1623,7 @@ struct __pyx_obj_9pywrapfst__MutableSymbolTable {
 };
 
 
-/* "pywrapfst.pxd":149
+/* "pywrapfst.pxd":152
  * 
  * 
  * cdef class _MutableFstSymbolTable(_MutableSymbolTable):             # <<<<<<<<<<<<<<
@@ -1627,7 +1636,7 @@ struct __pyx_obj_9pywrapfst__MutableFstSymbolTable {
 };
 
 
-/* "pywrapfst.pxd":154
+/* "pywrapfst.pxd":157
  * 
  * 
  * cdef class SymbolTable(_MutableSymbolTable):             # <<<<<<<<<<<<<<
@@ -1640,7 +1649,7 @@ struct __pyx_obj_9pywrapfst_SymbolTable {
 };
 
 
-/* "pywrapfst.pxd":177
+/* "pywrapfst.pxd":182
  * 
  * 
  * cdef class SymbolTableIterator(object):             # <<<<<<<<<<<<<<
@@ -1655,21 +1664,21 @@ struct __pyx_obj_9pywrapfst_SymbolTableIterator {
 };
 
 
-/* "pywrapfst.pxd":196
+/* "pywrapfst.pxd":201
  * 
  * 
  * cdef class EncodeMapper(object):             # <<<<<<<<<<<<<<
  * 
- *   cdef shared_ptr[fst.EncodeMapperClass] _encoder
+ *   cdef shared_ptr[fst.EncodeMapperClass] _mapper
  */
 struct __pyx_obj_9pywrapfst_EncodeMapper {
   PyObject_HEAD
   struct __pyx_vtabstruct_9pywrapfst_EncodeMapper *__pyx_vtab;
-  std::shared_ptr<fst::script::EncodeMapperClass>  _encoder;
+  std::shared_ptr<fst::script::EncodeMapperClass>  _mapper;
 };
 
 
-/* "pywrapfst.pxd":225
+/* "pywrapfst.pxd":239
  * 
  * 
  * cdef class _Fst(object):             # <<<<<<<<<<<<<<
@@ -1683,7 +1692,7 @@ struct __pyx_obj_9pywrapfst__Fst {
 };
 
 
-/* "pywrapfst.pxd":279
+/* "pywrapfst.pxd":307
  * 
  * 
  * cdef class _MutableFst(_Fst):             # <<<<<<<<<<<<<<
@@ -1696,7 +1705,7 @@ struct __pyx_obj_9pywrapfst__MutableFst {
 };
 
 
-/* "pywrapfst.pxd":373
+/* "pywrapfst.pxd":409
  * 
  * 
  * cdef class Arc(object):             # <<<<<<<<<<<<<<
@@ -1710,7 +1719,7 @@ struct __pyx_obj_9pywrapfst_Arc {
 };
 
 
-/* "pywrapfst.pxd":383
+/* "pywrapfst.pxd":419
  * 
  * 
  * cdef class ArcIterator(object):             # <<<<<<<<<<<<<<
@@ -1725,7 +1734,7 @@ struct __pyx_obj_9pywrapfst_ArcIterator {
 };
 
 
-/* "pywrapfst.pxd":405
+/* "pywrapfst.pxd":441
  * 
  * 
  * cdef class MutableArcIterator(object):             # <<<<<<<<<<<<<<
@@ -1740,7 +1749,7 @@ struct __pyx_obj_9pywrapfst_MutableArcIterator {
 };
 
 
-/* "pywrapfst.pxd":429
+/* "pywrapfst.pxd":465
  * 
  * 
  * cdef class StateIterator(object):             # <<<<<<<<<<<<<<
@@ -1755,7 +1764,7 @@ struct __pyx_obj_9pywrapfst_StateIterator {
 };
 
 
-/* "pywrapfst.pxd":516
+/* "pywrapfst.pxd":592
  * 
  * 
  * cdef class Compiler(object):             # <<<<<<<<<<<<<<
@@ -1779,7 +1788,7 @@ struct __pyx_obj_9pywrapfst_Compiler {
 };
 
 
-/* "pywrapfst.pxd":537
+/* "pywrapfst.pxd":613
  * # FarReader.
  * 
  * cdef class FarReader(object):             # <<<<<<<<<<<<<<
@@ -1793,7 +1802,7 @@ struct __pyx_obj_9pywrapfst_FarReader {
 };
 
 
-/* "pywrapfst.pxd":562
+/* "pywrapfst.pxd":638
  * # FarWriter.
  * 
  * cdef class FarWriter(object):             # <<<<<<<<<<<<<<
@@ -1807,7 +1816,7 @@ struct __pyx_obj_9pywrapfst_FarWriter {
 };
 
 
-/* "pywrapfst.pyx":3130
+/* "pywrapfst.pyx":3193
  * 
  *   # Magic method used to get a Pythonic Iterator API out of the C++ API
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -1863,7 +1872,7 @@ struct __pyx_vtabstruct_9pywrapfst__SymbolTable {
 static struct __pyx_vtabstruct_9pywrapfst__SymbolTable *__pyx_vtabptr_9pywrapfst__SymbolTable;
 
 
-/* "pywrapfst.pyx":852
+/* "pywrapfst.pyx":850
  * 
  * 
  * cdef class _EncodeMapperSymbolTable(_SymbolTable):             # <<<<<<<<<<<<<<
@@ -1877,7 +1886,7 @@ struct __pyx_vtabstruct_9pywrapfst__EncodeMapperSymbolTable {
 static struct __pyx_vtabstruct_9pywrapfst__EncodeMapperSymbolTable *__pyx_vtabptr_9pywrapfst__EncodeMapperSymbolTable;
 
 
-/* "pywrapfst.pyx":872
+/* "pywrapfst.pyx":870
  * 
  * 
  * cdef class _FstSymbolTable(_SymbolTable):             # <<<<<<<<<<<<<<
@@ -1891,7 +1900,7 @@ struct __pyx_vtabstruct_9pywrapfst__FstSymbolTable {
 static struct __pyx_vtabstruct_9pywrapfst__FstSymbolTable *__pyx_vtabptr_9pywrapfst__FstSymbolTable;
 
 
-/* "pywrapfst.pyx":891
+/* "pywrapfst.pyx":889
  * 
  * 
  * cdef class _MutableSymbolTable(_SymbolTable):             # <<<<<<<<<<<<<<
@@ -1908,7 +1917,7 @@ struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable {
 static struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable *__pyx_vtabptr_9pywrapfst__MutableSymbolTable;
 
 
-/* "pywrapfst.pyx":943
+/* "pywrapfst.pyx":941
  * 
  * 
  * cdef class _MutableFstSymbolTable(_MutableSymbolTable):             # <<<<<<<<<<<<<<
@@ -1922,7 +1931,7 @@ struct __pyx_vtabstruct_9pywrapfst__MutableFstSymbolTable {
 static struct __pyx_vtabstruct_9pywrapfst__MutableFstSymbolTable *__pyx_vtabptr_9pywrapfst__MutableFstSymbolTable;
 
 
-/* "pywrapfst.pyx":954
+/* "pywrapfst.pyx":952
  * 
  * 
  * cdef class SymbolTable(_MutableSymbolTable):             # <<<<<<<<<<<<<<
@@ -1936,7 +1945,7 @@ struct __pyx_vtabstruct_9pywrapfst_SymbolTable {
 static struct __pyx_vtabstruct_9pywrapfst_SymbolTable *__pyx_vtabptr_9pywrapfst_SymbolTable;
 
 
-/* "pywrapfst.pyx":1149
+/* "pywrapfst.pyx":1139
  * 
  * 
  * cdef class SymbolTableIterator(object):             # <<<<<<<<<<<<<<
@@ -1954,7 +1963,7 @@ struct __pyx_vtabstruct_9pywrapfst_SymbolTableIterator {
 static struct __pyx_vtabstruct_9pywrapfst_SymbolTableIterator *__pyx_vtabptr_9pywrapfst_SymbolTableIterator;
 
 
-/* "pywrapfst.pyx":1231
+/* "pywrapfst.pyx":1221
  * 
  * 
  * cdef class EncodeMapper(object):             # <<<<<<<<<<<<<<
@@ -1964,18 +1973,20 @@ static struct __pyx_vtabstruct_9pywrapfst_SymbolTableIterator *__pyx_vtabptr_9py
 
 struct __pyx_vtabstruct_9pywrapfst_EncodeMapper {
   std::string (*arc_type)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch);
-  __pyx_t_10basictypes_uint32 (*flags)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch);
+  std::string (*weight_type)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch);
+  __pyx_t_10basictypes_uint8 (*flags)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch);
+  __pyx_t_10basictypes_uint64 (*properties)(struct __pyx_obj_9pywrapfst_EncodeMapper *, __pyx_t_10basictypes_uint64, int __pyx_skip_dispatch);
+  void (*write)(struct __pyx_obj_9pywrapfst_EncodeMapper *, PyObject *, int __pyx_skip_dispatch);
+  PyObject *(*write_to_string)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch);
   struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *(*input_symbols)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch);
   struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *(*output_symbols)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch);
-  __pyx_t_10basictypes_uint64 (*properties)(struct __pyx_obj_9pywrapfst_EncodeMapper *, __pyx_t_10basictypes_uint64, int __pyx_skip_dispatch);
   void (*set_input_symbols)(struct __pyx_obj_9pywrapfst_EncodeMapper *, struct __pyx_obj_9pywrapfst__SymbolTable *, int __pyx_skip_dispatch);
   void (*set_output_symbols)(struct __pyx_obj_9pywrapfst_EncodeMapper *, struct __pyx_obj_9pywrapfst__SymbolTable *, int __pyx_skip_dispatch);
-  std::string (*weight_type)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch);
 };
 static struct __pyx_vtabstruct_9pywrapfst_EncodeMapper *__pyx_vtabptr_9pywrapfst_EncodeMapper;
 
 
-/* "pywrapfst.pyx":1387
+/* "pywrapfst.pyx":1467
  * 
  * 
  * cdef class _Fst(object):             # <<<<<<<<<<<<<<
@@ -2008,7 +2019,7 @@ struct __pyx_vtabstruct_9pywrapfst__Fst {
 static struct __pyx_vtabstruct_9pywrapfst__Fst *__pyx_vtabptr_9pywrapfst__Fst;
 
 
-/* "pywrapfst.pyx":1802
+/* "pywrapfst.pyx":1888
  * 
  * 
  * cdef class _MutableFst(_Fst):             # <<<<<<<<<<<<<<
@@ -2049,12 +2060,11 @@ struct __pyx_vtabstruct_9pywrapfst__MutableFst {
   void (*_set_input_symbols)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_obj_9pywrapfst__SymbolTable *);
   void (*_set_output_symbols)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_obj_9pywrapfst__SymbolTable *);
   void (*_topsort)(struct __pyx_obj_9pywrapfst__MutableFst *);
-  void (*_union)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_obj_9pywrapfst__Fst *);
 };
 static struct __pyx_vtabstruct_9pywrapfst__MutableFst *__pyx_vtabptr_9pywrapfst__MutableFst;
 
 
-/* "pywrapfst.pyx":2932
+/* "pywrapfst.pyx":2995
  * 
  * 
  * cdef class Arc(object):             # <<<<<<<<<<<<<<
@@ -2068,7 +2078,7 @@ struct __pyx_vtabstruct_9pywrapfst_Arc {
 static struct __pyx_vtabstruct_9pywrapfst_Arc *__pyx_vtabptr_9pywrapfst_Arc;
 
 
-/* "pywrapfst.pyx":2999
+/* "pywrapfst.pyx":3062
  * 
  * 
  * cdef class ArcIterator(object):             # <<<<<<<<<<<<<<
@@ -2078,18 +2088,18 @@ static struct __pyx_vtabstruct_9pywrapfst_Arc *__pyx_vtabptr_9pywrapfst_Arc;
 
 struct __pyx_vtabstruct_9pywrapfst_ArcIterator {
   bool (*done)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch);
-  __pyx_t_10basictypes_uint32 (*flags)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch);
+  __pyx_t_10basictypes_uint8 (*flags)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch);
   void (*next)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch);
   size_t (*position)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch);
   void (*reset)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch);
   void (*seek)(struct __pyx_obj_9pywrapfst_ArcIterator *, size_t, int __pyx_skip_dispatch);
-  void (*set_flags)(struct __pyx_obj_9pywrapfst_ArcIterator *, __pyx_t_10basictypes_uint32, __pyx_t_10basictypes_uint32, int __pyx_skip_dispatch);
+  void (*set_flags)(struct __pyx_obj_9pywrapfst_ArcIterator *, __pyx_t_10basictypes_uint8, __pyx_t_10basictypes_uint8, int __pyx_skip_dispatch);
   PyObject *(*value)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch);
 };
 static struct __pyx_vtabstruct_9pywrapfst_ArcIterator *__pyx_vtabptr_9pywrapfst_ArcIterator;
 
 
-/* "pywrapfst.pyx":3110
+/* "pywrapfst.pyx":3173
  * 
  * 
  * cdef class MutableArcIterator(object):             # <<<<<<<<<<<<<<
@@ -2099,19 +2109,19 @@ static struct __pyx_vtabstruct_9pywrapfst_ArcIterator *__pyx_vtabptr_9pywrapfst_
 
 struct __pyx_vtabstruct_9pywrapfst_MutableArcIterator {
   bool (*done)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch);
-  __pyx_t_10basictypes_uint32 (*flags)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch);
+  __pyx_t_10basictypes_uint8 (*flags)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch);
   void (*next)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch);
   size_t (*position)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch);
   void (*reset)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch);
   void (*seek)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, size_t, int __pyx_skip_dispatch);
-  void (*set_flags)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, __pyx_t_10basictypes_uint32, __pyx_t_10basictypes_uint32, int __pyx_skip_dispatch);
+  void (*set_flags)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, __pyx_t_10basictypes_uint8, __pyx_t_10basictypes_uint8, int __pyx_skip_dispatch);
   void (*set_value)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, struct __pyx_obj_9pywrapfst_Arc *, int __pyx_skip_dispatch);
   PyObject *(*value)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch);
 };
 static struct __pyx_vtabstruct_9pywrapfst_MutableArcIterator *__pyx_vtabptr_9pywrapfst_MutableArcIterator;
 
 
-/* "pywrapfst.pyx":3230
+/* "pywrapfst.pyx":3293
  * 
  * 
  * cdef class StateIterator(object):             # <<<<<<<<<<<<<<
@@ -2128,7 +2138,7 @@ struct __pyx_vtabstruct_9pywrapfst_StateIterator {
 static struct __pyx_vtabstruct_9pywrapfst_StateIterator *__pyx_vtabptr_9pywrapfst_StateIterator;
 
 
-/* "pywrapfst.pyx":4133
+/* "pywrapfst.pyx":4199
  * 
  * 
  * cdef class Compiler(object):             # <<<<<<<<<<<<<<
@@ -2143,7 +2153,7 @@ struct __pyx_vtabstruct_9pywrapfst_Compiler {
 static struct __pyx_vtabstruct_9pywrapfst_Compiler *__pyx_vtabptr_9pywrapfst_Compiler;
 
 
-/* "pywrapfst.pyx":4263
+/* "pywrapfst.pyx":4336
  * 
  * 
  * cdef class FarReader(object):             # <<<<<<<<<<<<<<
@@ -2165,7 +2175,7 @@ struct __pyx_vtabstruct_9pywrapfst_FarReader {
 static struct __pyx_vtabstruct_9pywrapfst_FarReader *__pyx_vtabptr_9pywrapfst_FarReader;
 
 
-/* "pywrapfst.pyx":4410
+/* "pywrapfst.pyx":4483
  * 
  * 
  * cdef class FarWriter(object):             # <<<<<<<<<<<<<<
@@ -2513,10 +2523,6 @@ static CYTHON_INLINE int __Pyx_IterFinish(void);
 /* UnpackItemEndCheck.proto */
 static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected);
 
-/* IterNext.proto */
-#define __Pyx_PyIter_Next(obj) __Pyx_PyIter_Next2(obj, NULL)
-static CYTHON_INLINE PyObject *__Pyx_PyIter_Next2(PyObject *, PyObject *);
-
 /* ListCompAppend.proto */
 #if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS
 static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) {
@@ -2684,7 +2690,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int64_t(int64_t value);
 static CYTHON_INLINE PyObject* __Pyx_PyInt_From_uint64_t(uint64_t value);
 
 /* CIntToPy.proto */
-static CYTHON_INLINE PyObject* __Pyx_PyInt_From_uint32_t(uint32_t value);
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_uint8_t(uint8_t value);
 
 /* CIntToPy.proto */
 static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value);
@@ -2747,7 +2753,7 @@ static CYTHON_INLINE uint64_t __Pyx_PyInt_As_uint64_t(PyObject *);
 static CYTHON_INLINE int32_t __Pyx_PyInt_As_int32_t(PyObject *);
 
 /* CIntFromPy.proto */
-static CYTHON_INLINE uint32_t __Pyx_PyInt_As_uint32_t(PyObject *);
+static CYTHON_INLINE uint8_t __Pyx_PyInt_As_uint8_t(PyObject *);
 
 /* CIntFromPy.proto */
 static CYTHON_INLINE time_t __Pyx_PyInt_As_time_t(PyObject *);
@@ -2861,8 +2867,8 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_labeled_checksum(struct __pyx
 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*/
-static void __pyx_f_9pywrapfst_12_SymbolTable_write_text(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_filename, int __pyx_skip_dispatch); /* proto*/
+static void __pyx_f_9pywrapfst_12_SymbolTable_write(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch); /* proto*/
+static void __pyx_f_9pywrapfst_12_SymbolTable_write_text(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch); /* proto*/
 static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_write_to_string(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_symbol(struct __pyx_obj_9pywrapfst__MutableSymbolTable *__pyx_v_self, PyObject *__pyx_v_symbol, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_19_MutableSymbolTable_add_symbol *__pyx_optional_args); /* proto*/
 static void __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(struct __pyx_obj_9pywrapfst__MutableSymbolTable *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms, int __pyx_skip_dispatch); /* proto*/
@@ -2873,18 +2879,20 @@ static void __pyx_f_9pywrapfst_19SymbolTableIterator_reset(struct __pyx_obj_9pyw
 static std::string __pyx_f_9pywrapfst_19SymbolTableIterator_symbol(struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19SymbolTableIterator_value(struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static std::string __pyx_f_9pywrapfst_12EncodeMapper_arc_type(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_12EncodeMapper_flags(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static std::string __pyx_f_9pywrapfst_12EncodeMapper_weight_type(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static __pyx_t_10basictypes_uint8 __pyx_f_9pywrapfst_12EncodeMapper_flags(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_12EncodeMapper_properties(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, __pyx_t_10basictypes_uint64 __pyx_v_mask, int __pyx_skip_dispatch); /* proto*/
+static void __pyx_f_9pywrapfst_12EncodeMapper_write(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch); /* proto*/
+static PyObject *__pyx_f_9pywrapfst_12EncodeMapper_write_to_string(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, int __pyx_skip_dispatch); /* 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); /* 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); /* proto*/
-static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_12EncodeMapper_properties(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, __pyx_t_10basictypes_uint64 __pyx_v_mask, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_12EncodeMapper_set_input_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_12EncodeMapper_set_output_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms, int __pyx_skip_dispatch); /* proto*/
-static std::string __pyx_f_9pywrapfst_12EncodeMapper_weight_type(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static std::string __pyx_f_9pywrapfst_4_Fst__local_render_svg(std::string const &__pyx_v_dot); /* proto*/
 static std::string __pyx_f_9pywrapfst_4_Fst_arc_type(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_4_Fst_arcs(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, int __pyx_skip_dispatch); /* proto*/
 static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_4_Fst_copy(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch); /* 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); /* proto*/
+static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_4_Fst_draw *__pyx_optional_args); /* proto*/
 static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_4_Fst_final(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, int __pyx_skip_dispatch); /* proto*/
 static std::string __pyx_f_9pywrapfst_4_Fst_fst_type(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch); /* 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); /* proto*/
@@ -2898,7 +2906,7 @@ static struct __pyx_obj_9pywrapfst_StateIterator *__pyx_f_9pywrapfst_4_Fst_state
 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); /* proto*/
 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 void __pyx_f_9pywrapfst_4_Fst_write(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch); /* proto*/
 static PyObject *__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*/
@@ -2906,12 +2914,12 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_add_state(str
 static void __pyx_f_9pywrapfst_11_MutableFst_add_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, size_t __pyx_v_n, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__arcsort *__pyx_optional_args); /* proto*/
 static void __pyx_f_9pywrapfst_11_MutableFst__closure(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__closure *__pyx_optional_args); /* proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst__concat(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst); /* proto*/
+static void __pyx_f_9pywrapfst_11_MutableFst__concat(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_fst2); /* proto*/
 static void __pyx_f_9pywrapfst_11_MutableFst__connect(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst__decode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_encoder); /* proto*/
+static void __pyx_f_9pywrapfst_11_MutableFst__decode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_mapper); /* proto*/
 static void __pyx_f_9pywrapfst_11_MutableFst__delete_arcs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, struct __pyx_opt_args_9pywrapfst_11_MutableFst__delete_arcs *__pyx_optional_args); /* proto*/
 static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__delete_states *__pyx_optional_args); /* proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst__encode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_encoder); /* proto*/
+static void __pyx_f_9pywrapfst_11_MutableFst__encode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_mapper); /* proto*/
 static void __pyx_f_9pywrapfst_11_MutableFst__invert(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto*/
 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); /* proto*/
 static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_11_MutableFst_mutable_arcs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, int __pyx_skip_dispatch); /* proto*/
@@ -2931,23 +2939,22 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_output_symbols(struct __pyx_ob
 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*/
 static bool __pyx_f_9pywrapfst_11ArcIterator_done(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_11ArcIterator_flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static __pyx_t_10basictypes_uint8 __pyx_f_9pywrapfst_11ArcIterator_flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_11ArcIterator_next(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static size_t __pyx_f_9pywrapfst_11ArcIterator_position(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_11ArcIterator_reset(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_11ArcIterator_seek(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, size_t __pyx_v_a, int __pyx_skip_dispatch); /* proto*/
-static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, __pyx_t_10basictypes_uint32 __pyx_v_flags, __pyx_t_10basictypes_uint32 __pyx_v_mask, int __pyx_skip_dispatch); /* proto*/
+static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, __pyx_t_10basictypes_uint8 __pyx_v_flags, __pyx_t_10basictypes_uint8 __pyx_v_mask, int __pyx_skip_dispatch); /* proto*/
 static PyObject *__pyx_f_9pywrapfst_11ArcIterator_value(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static bool __pyx_f_9pywrapfst_18MutableArcIterator_done(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_18MutableArcIterator_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static __pyx_t_10basictypes_uint8 __pyx_f_9pywrapfst_18MutableArcIterator_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_18MutableArcIterator_next(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static size_t __pyx_f_9pywrapfst_18MutableArcIterator_position(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_18MutableArcIterator_reset(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_18MutableArcIterator_seek(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, size_t __pyx_v_a, int __pyx_skip_dispatch); /* proto*/
-static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, __pyx_t_10basictypes_uint32 __pyx_v_flags, __pyx_t_10basictypes_uint32 __pyx_v_mask, int __pyx_skip_dispatch); /* proto*/
+static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, __pyx_t_10basictypes_uint8 __pyx_v_flags, __pyx_t_10basictypes_uint8 __pyx_v_mask, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_18MutableArcIterator_set_value(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc, int __pyx_skip_dispatch); /* proto*/
 static PyObject *__pyx_f_9pywrapfst_18MutableArcIterator_value(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static bool __pyx_f_9pywrapfst_13StateIterator_done(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
@@ -2979,14 +2986,14 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_far_type(struct __pyx_obj_9pywr
 
 /* Module declarations from 'libcpp.memory' */
 
-/* Module declarations from 'libcpp.utility' */
-
-/* Module declarations from 'libcpp.vector' */
-
 /* Module declarations from 'libc.string' */
 
 /* Module declarations from 'libcpp.string' */
 
+/* Module declarations from 'libcpp.utility' */
+
+/* Module declarations from 'libcpp.vector' */
+
 /* Module declarations from 'libc.stdint' */
 
 /* Module declarations from 'basictypes' */
@@ -3001,8 +3008,6 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_far_type(struct __pyx_obj_9pywr
 
 /* Module declarations from 'libcpp.cast' */
 
-/* Module declarations from 'memory' */
-
 /* Module declarations from 'pywrapfst' */
 static PyTypeObject *__pyx_ptype_9pywrapfst_Weight = 0;
 static PyTypeObject *__pyx_ptype_9pywrapfst__SymbolTable = 0;
@@ -3043,6 +3048,8 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst__init_Fst
 static struct __pyx_obj_9pywrapfst__MutableFstSymbolTable *__pyx_f_9pywrapfst__init_MutableFstSymbolTable(fst::SymbolTable *, std::shared_ptr<fst::script::MutableFstClass> ); /*proto*/
 static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__init_SymbolTable(fst::SymbolTable *); /*proto*/
 static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__read_SymbolTable_from_string(PyObject *, int __pyx_skip_dispatch); /*proto*/
+static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__init_EncodeMapper(fst::script::EncodeMapperClass *); /*proto*/
+static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__read_EncodeMapper_from_string(PyObject *, int __pyx_skip_dispatch); /*proto*/
 static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9pywrapfst_FstClass_ptr); /*proto*/
 static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__init_MutableFst(__pyx_t_9pywrapfst_MutableFstClass_ptr); /*proto*/
 static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_XFst(__pyx_t_9pywrapfst_FstClass_ptr); /*proto*/
@@ -3090,8 +3097,8 @@ static PyObject *__pyx_builtin_ValueError;
 static PyObject *__pyx_builtin_RuntimeError;
 static PyObject *__pyx_builtin_IndexError;
 static PyObject *__pyx_builtin_IOError;
-static PyObject *__pyx_builtin_object;
 static PyObject *__pyx_builtin_staticmethod;
+static PyObject *__pyx_builtin_object;
 static PyObject *__pyx_builtin_id;
 static PyObject *__pyx_builtin_TypeError;
 static PyObject *__pyx_builtin_StopIteration;
@@ -3099,11 +3106,11 @@ static PyObject *__pyx_builtin_KeyError;
 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__8[] = "";
 static const char __pyx_k_id[] = "id";
 static const char __pyx_k_Arc[] = "Arc";
 static const char __pyx_k_Fst[] = "_Fst";
 static const char __pyx_k_One[] = "One";
-static const char __pyx_k__10[] = "";
 static const char __pyx_k_add[] = "add";
 static const char __pyx_k_arc[] = "arc";
 static const char __pyx_k_cls[] = "cls";
@@ -3188,6 +3195,7 @@ static const char __pyx_k_opairs[] = "opairs";
 static const char __pyx_k_reduce[] = "__reduce__";
 static const char __pyx_k_result[] = "result";
 static const char __pyx_k_select[] = "select";
+static const char __pyx_k_source[] = "source";
 static const char __pyx_k_states[] = "states";
 static const char __pyx_k_stdout[] = "stdout";
 static const char __pyx_k_symbol[] = "symbol";
@@ -3229,7 +3237,6 @@ static const char __pyx_k_checksum[] = "checksum";
 static const char __pyx_k_det_type[] = "det_type";
 static const char __pyx_k_distance[] = "distance";
 static const char __pyx_k_far_type[] = "far_type";
-static const char __pyx_k_filename[] = "filename";
 static const char __pyx_k_fontsize[] = "fontsize";
 static const char __pyx_k_fst_type[] = "fst_type";
 static const char __pyx_k_getstate[] = "__getstate__";
@@ -3455,9 +3462,10 @@ static const char __pyx_k_O_LABEL_INVARIANT_PROPERTIES[] = "O_LABEL_INVARIANT_PR
 static const char __pyx_k_Unknown_replace_label_type_r[] = "Unknown replace label type: {!r}";
 static const char __pyx_k_read_SymbolTable_from_string[] = "_read_SymbolTable_from_string";
 static const char __pyx_k_No_new_SymbolTables_specified[] = "No new SymbolTables specified";
-static const char __pyx_k_No_relabeling_pairs_specified[] = "No relabeling pairs specified.";
+static const char __pyx_k_No_relabeling_pairs_specified[] = "No relabeling pairs specified";
 static const char __pyx_k_Unknown_compose_filter_type_r[] = "Unknown compose filter type: {!r}";
 static const char __pyx_k_increment_subsequential_label[] = "increment_subsequential_label";
+static const char __pyx_k_read_EncodeMapper_from_string[] = "_read_EncodeMapper_from_string";
 static const char __pyx_k_Incompatible_or_invalid_weight[] = "Incompatible or invalid weight";
 static const char __pyx_k_Unknown_determinization_type_r[] = "Unknown determinization type: {!r}";
 static const char __pyx_k_const_EncodeMapper_SymbolTable[] = "<const EncodeMapper SymbolTable {!r} at 0x{:x}>";
@@ -3472,7 +3480,6 @@ static const char __pyx_k_Unknown_random_arc_selection_typ[] = "Unknown random a
 static const char __pyx_k_no_default___reduce___due_to_non[] = "no default __reduce__ due to non-trivial __cinit__";
 static const char __pyx_k_self__aiter_self__mfst_cannot_be[] = "self._aiter,self._mfst cannot be converted to a Python object for pickling";
 static const char __pyx_k_self__arc_cannot_be_converted_to[] = "self._arc cannot be converted to a Python object for pickling";
-static const char __pyx_k_self__encoder_cannot_be_converte[] = "self._encoder cannot be converted to a Python object for pickling";
 static const char __pyx_k_self__reader_cannot_be_converted[] = "self._reader cannot be converted to a Python object for pickling";
 static const char __pyx_k_self__siter_self__table_cannot_b[] = "self._siter,self._table cannot be converted to a Python object for pickling";
 static const char __pyx_k_self__weight_cannot_be_converted[] = "self._weight cannot be converted to a Python object for pickling";
@@ -3634,7 +3641,7 @@ static PyObject *__pyx_kp_u_Weight_type_not_found;
 static PyObject *__pyx_kp_u_Write_failed_r;
 static PyObject *__pyx_kp_u_Write_to_string_failed;
 static PyObject *__pyx_n_s_Zero;
-static PyObject *__pyx_kp_b__10;
+static PyObject *__pyx_kp_b__8;
 static PyObject *__pyx_n_s_acceptor;
 static PyObject *__pyx_n_s_add;
 static PyObject *__pyx_n_s_add_state;
@@ -3682,7 +3689,6 @@ static PyObject *__pyx_n_s_eps_norm_output;
 static PyObject *__pyx_n_s_epsilon_on_replace;
 static PyObject *__pyx_n_s_error;
 static PyObject *__pyx_n_s_far_type;
-static PyObject *__pyx_n_s_filename;
 static PyObject *__pyx_n_s_final;
 static PyObject *__pyx_n_s_find;
 static PyObject *__pyx_n_s_flags;
@@ -3776,6 +3782,7 @@ static PyObject *__pyx_n_s_qualname;
 static PyObject *__pyx_n_s_queue_type;
 static PyObject *__pyx_n_s_ranksep;
 static PyObject *__pyx_n_s_read;
+static PyObject *__pyx_n_s_read_EncodeMapper_from_string;
 static PyObject *__pyx_n_s_read_Fst_from_string;
 static PyObject *__pyx_n_s_read_SymbolTable_from_string;
 static PyObject *__pyx_n_s_read_from_string;
@@ -3799,7 +3806,6 @@ static PyObject *__pyx_n_s_select;
 static PyObject *__pyx_kp_s_self__aiter_self__fst_cannot_be;
 static PyObject *__pyx_kp_s_self__aiter_self__mfst_cannot_be;
 static PyObject *__pyx_kp_s_self__arc_cannot_be_converted_to;
-static PyObject *__pyx_kp_s_self__encoder_cannot_be_converte;
 static PyObject *__pyx_kp_s_self__fst_self__siter_cannot_be;
 static PyObject *__pyx_kp_s_self__reader_cannot_be_converted;
 static PyObject *__pyx_kp_s_self__siter_self__table_cannot_b;
@@ -3816,6 +3822,7 @@ static PyObject *__pyx_n_s_setstate_cython;
 static PyObject *__pyx_n_s_shortestdistance;
 static PyObject *__pyx_n_s_show_weight_one;
 static PyObject *__pyx_n_s_sort_type;
+static PyObject *__pyx_n_s_source;
 static PyObject *__pyx_n_s_ssymbols;
 static PyObject *__pyx_n_b_standard;
 static PyObject *__pyx_n_s_start;
@@ -3888,8 +3895,8 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_18member(struct __pyx_obj_9p
 static int __pyx_pf_9pywrapfst_12_SymbolTable_20__contains__(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_key); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_22name(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_24num_symbols(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_26write(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_filename); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_28write_text(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_filename); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_26write(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_source); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_28write_text(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_source); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_30write_to_string(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_24_EncodeMapperSymbolTable___repr__(struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_15_FstSymbolTable___repr__(struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_v_self); /* proto */
@@ -3899,9 +3906,9 @@ static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_4set_name(struct __py
 static PyObject *__pyx_pf_9pywrapfst_22_MutableFstSymbolTable___repr__(struct __pyx_obj_9pywrapfst__MutableFstSymbolTable *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11SymbolTable___repr__(struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v_self); /* proto */
 static int __pyx_pf_9pywrapfst_11SymbolTable_2__init__(struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v_self, PyObject *__pyx_v_name); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_filename); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_filename, bool __pyx_v_allow_negative_labels); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_filename, bool __pyx_v_input_table); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_source); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_source, bool __pyx_v_allow_negative_labels); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_source, bool __pyx_v_input_table); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_8_read_SymbolTable_from_string(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_state); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_10compact_symbol_table(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_12merge_symbol_table(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_lhs, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_rhs); /* proto */
@@ -3918,17 +3925,21 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_18__reduce_cython__(C
 static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_20__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper___repr__(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self); /* proto */
 static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, PyObject *__pyx_v_arc_type, bool __pyx_v_encode_labels, bool __pyx_v_encode_weights); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_4arc_type(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_6__call__(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_8flags(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_10input_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_12output_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_4__call__(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_6__reduce__(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_8arc_type(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_10weight_type(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_12flags(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_14properties(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, __pyx_t_10basictypes_uint64 __pyx_v_mask); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_16set_input_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_18set_output_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_20weight_type(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_22__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_24__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_16read(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_source); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_18read_from_string(PyObject *__pyx_v_state); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_20write(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, PyObject *__pyx_v_source); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_22write_to_string(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_24input_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_26output_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_28set_input_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_30set_output_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_14_read_EncodeMapper_from_string(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_state); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self); /* proto */
 static int __pyx_pf_9pywrapfst_4_Fst_2__init__(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_4_Fst_4__reduce__(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self); /* proto */
@@ -3937,7 +3948,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_8__str__(struct __pyx_obj_9pywrapfst_
 static PyObject *__pyx_pf_9pywrapfst_4_Fst_10arc_type(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_4_Fst_12arcs(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_4_Fst_14copy(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_16draw(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, PyObject *__pyx_v_filename, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_isymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_osymbols, struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v_ssymbols, bool __pyx_v_acceptor, PyObject *__pyx_v_title, double __pyx_v_width, double __pyx_v_height, bool __pyx_v_portrait, bool __pyx_v_vertical, double __pyx_v_ranksep, double __pyx_v_nodesep, __pyx_t_10basictypes_int32 __pyx_v_fontsize, __pyx_t_10basictypes_int32 __pyx_v_precision, PyObject *__pyx_v_float_format, bool __pyx_v_show_weight_one); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_4_Fst_16draw(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, PyObject *__pyx_v_source, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_isymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_osymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_ssymbols, bool __pyx_v_acceptor, PyObject *__pyx_v_title, double __pyx_v_width, double __pyx_v_height, bool __pyx_v_portrait, bool __pyx_v_vertical, double __pyx_v_ranksep, double __pyx_v_nodesep, __pyx_t_10basictypes_int32 __pyx_v_fontsize, __pyx_t_10basictypes_int32 __pyx_v_precision, PyObject *__pyx_v_float_format, bool __pyx_v_show_weight_one); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_4_Fst_18final(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_4_Fst_20fst_type(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_4_Fst_22input_symbols(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self); /* proto */
@@ -3951,19 +3962,19 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_36states(struct __pyx_obj_9pywrapfst_
 static PyObject *__pyx_pf_9pywrapfst_4_Fst_38text(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_isymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_osymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_ssymbols, bool __pyx_v_acceptor, bool __pyx_v_show_weight_one, PyObject *__pyx_v_missing_sym); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_4_Fst_40verify(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_4_Fst_42weight_type(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_44write(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, PyObject *__pyx_v_filename); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_4_Fst_44write(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, PyObject *__pyx_v_source); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_4_Fst_46write_to_string(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_add_arc(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_2add_state(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_4add_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, size_t __pyx_v_n); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_6arcsort(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_sort_type); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_8closure(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, bool __pyx_v_closure_plus); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_10concat(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_10concat(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_fst2); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_12connect(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_14decode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_encoder); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_14decode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_mapper); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_16delete_arcs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, size_t __pyx_v_n); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_18delete_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_states); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_20encode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_encoder); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_20encode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_mapper); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_22invert(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_24minimize(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, float __pyx_v_delta, bool __pyx_v_allow_nondet); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_26mutable_arcs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state); /* proto */
@@ -3985,11 +3996,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_56set_output_symbols(struct _
 static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_58set_properties(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_uint64 __pyx_v_props, __pyx_t_10basictypes_uint64 __pyx_v_mask); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_60set_start(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_62topsort(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_64union(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_14_read(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_filename); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_16_read_Fst_from_string(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_state); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_64union(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_fsts2); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_16_read(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_source); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_18_read_Fst_from_string(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_state); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_3Fst___new__(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_cls, PyObject *__pyx_v_arc_type); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_3Fst_2read(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_filename); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_3Fst_2read(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_source); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_3Fst_4read_from_string(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_state); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_3Arc___repr__(struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self); /* proto */
 static int __pyx_pf_9pywrapfst_3Arc_2__init__(struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_ilabel, __pyx_t_10basictypes_int64 __pyx_v_olabel, PyObject *__pyx_v_weight, __pyx_t_10basictypes_int64 __pyx_v_nextstate); /* proto */
@@ -4014,7 +4025,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_12next(struct __pyx_obj_9pywr
 static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_14position(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_16reset(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_18seek(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, size_t __pyx_v_a); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_20set_flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, __pyx_t_10basictypes_uint32 __pyx_v_flags, __pyx_t_10basictypes_uint32 __pyx_v_mask); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_20set_flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, __pyx_t_10basictypes_uint8 __pyx_v_flags, __pyx_t_10basictypes_uint8 __pyx_v_mask); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_22value(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_24__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_26__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */
@@ -4027,7 +4038,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_11next(struct __pyx_ob
 static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_13position(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_15reset(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_17seek(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, size_t __pyx_v_a); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_19set_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, __pyx_t_10basictypes_uint32 __pyx_v_flags, __pyx_t_10basictypes_uint32 __pyx_v_mask); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_19set_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, __pyx_t_10basictypes_uint8 __pyx_v_flags, __pyx_t_10basictypes_uint8 __pyx_v_mask); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_21set_value(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_23value(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_25__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
@@ -4042,27 +4053,27 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_12reset(struct __pyx_obj_9p
 static PyObject *__pyx_pf_9pywrapfst_13StateIterator_14value(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_13StateIterator_16__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_13StateIterator_18__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_18arcmap(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, PyObject *__pyx_v_map_type, double __pyx_v_power, PyObject *__pyx_v_weight); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_20compose(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, PyObject *__pyx_v_compose_filter, bool __pyx_v_connect); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_22convert(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, PyObject *__pyx_v_fst_type); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_24determinize(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, PyObject *__pyx_v_det_type, __pyx_t_10basictypes_int64 __pyx_v_nstate, __pyx_t_10basictypes_int64 __pyx_v_subsequential_label, PyObject *__pyx_v_weight, bool __pyx_v_increment_subsequential_label); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_26difference(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, PyObject *__pyx_v_compose_filter, bool __pyx_v_connect); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_28disambiguate(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, __pyx_t_10basictypes_int64 __pyx_v_nstate, __pyx_t_10basictypes_int64 __pyx_v_subsequential_label, PyObject *__pyx_v_weight); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_30epsnormalize(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, bool __pyx_v_eps_norm_output); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_32equal(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, float __pyx_v_delta); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_34equivalent(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, float __pyx_v_delta); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_36intersect(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, PyObject *__pyx_v_compose_filter, bool __pyx_v_connect); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_38isomorphic(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, float __pyx_v_delta); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_40prune(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, __pyx_t_10basictypes_int64 __pyx_v_nstate, PyObject *__pyx_v_weight); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_42push(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, bool __pyx_v_push_weights, bool __pyx_v_push_labels, bool __pyx_v_remove_common_affix, bool __pyx_v_remove_total_weight, bool __pyx_v_to_final); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_44randequivalent(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, __pyx_t_10basictypes_int32 __pyx_v_npath, float __pyx_v_delta, time_t __pyx_v_seed, PyObject *__pyx_v_select, __pyx_t_10basictypes_int32 __pyx_v_max_length); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_46randgen(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, __pyx_t_10basictypes_int32 __pyx_v_npath, time_t __pyx_v_seed, PyObject *__pyx_v_select, __pyx_t_10basictypes_int32 __pyx_v_max_length, bool __pyx_v_weighted, bool __pyx_v_remove_total_weight); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_48replace(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pairs, PyObject *__pyx_v_call_arc_labeling, PyObject *__pyx_v_return_arc_labeling, bool __pyx_v_epsilon_on_replace, __pyx_t_10basictypes_int64 __pyx_v_return_label); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_50reverse(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, bool __pyx_v_require_superinitial); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_52shortestdistance(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, __pyx_t_10basictypes_int64 __pyx_v_nstate, PyObject *__pyx_v_queue_type, bool __pyx_v_reverse); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_54shortestpath(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, __pyx_t_10basictypes_int32 __pyx_v_nshortest, __pyx_t_10basictypes_int64 __pyx_v_nstate, PyObject *__pyx_v_queue_type, bool __pyx_v_unique, PyObject *__pyx_v_weight); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_56statemap(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, PyObject *__pyx_v_map_type); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_58synchronize(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_20arcmap(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, PyObject *__pyx_v_map_type, double __pyx_v_power, PyObject *__pyx_v_weight); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_22compose(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, PyObject *__pyx_v_compose_filter, bool __pyx_v_connect); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_24convert(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, PyObject *__pyx_v_fst_type); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_26determinize(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, PyObject *__pyx_v_det_type, __pyx_t_10basictypes_int64 __pyx_v_nstate, __pyx_t_10basictypes_int64 __pyx_v_subsequential_label, PyObject *__pyx_v_weight, bool __pyx_v_increment_subsequential_label); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_28difference(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, PyObject *__pyx_v_compose_filter, bool __pyx_v_connect); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_30disambiguate(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, __pyx_t_10basictypes_int64 __pyx_v_nstate, __pyx_t_10basictypes_int64 __pyx_v_subsequential_label, PyObject *__pyx_v_weight); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_32epsnormalize(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, bool __pyx_v_eps_norm_output); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_34equal(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, float __pyx_v_delta); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_36equivalent(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, float __pyx_v_delta); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_38intersect(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, PyObject *__pyx_v_compose_filter, bool __pyx_v_connect); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_40isomorphic(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, float __pyx_v_delta); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_42prune(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, __pyx_t_10basictypes_int64 __pyx_v_nstate, PyObject *__pyx_v_weight); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_44push(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, bool __pyx_v_push_weights, bool __pyx_v_push_labels, bool __pyx_v_remove_common_affix, bool __pyx_v_remove_total_weight, bool __pyx_v_to_final); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_46randequivalent(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, __pyx_t_10basictypes_int32 __pyx_v_npath, float __pyx_v_delta, time_t __pyx_v_seed, PyObject *__pyx_v_select, __pyx_t_10basictypes_int32 __pyx_v_max_length); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_48randgen(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, __pyx_t_10basictypes_int32 __pyx_v_npath, time_t __pyx_v_seed, PyObject *__pyx_v_select, __pyx_t_10basictypes_int32 __pyx_v_max_length, bool __pyx_v_weighted, bool __pyx_v_remove_total_weight); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_50replace(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pairs, PyObject *__pyx_v_call_arc_labeling, PyObject *__pyx_v_return_arc_labeling, bool __pyx_v_epsilon_on_replace, __pyx_t_10basictypes_int64 __pyx_v_return_label); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_52reverse(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, bool __pyx_v_require_superinitial); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_54shortestdistance(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, __pyx_t_10basictypes_int64 __pyx_v_nstate, PyObject *__pyx_v_queue_type, bool __pyx_v_reverse); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_56shortestpath(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, __pyx_t_10basictypes_int32 __pyx_v_nshortest, __pyx_t_10basictypes_int64 __pyx_v_nstate, PyObject *__pyx_v_queue_type, bool __pyx_v_unique, PyObject *__pyx_v_weight); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_58statemap(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, PyObject *__pyx_v_map_type); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_60synchronize(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst); /* proto */
 static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_Compiler *__pyx_v_self, std::string __pyx_v_fst_type, std::string __pyx_v_arc_type, struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v_isymbols, struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v_osymbols, struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v_ssymbols, bool __pyx_v_acceptor, bool __pyx_v_keep_isymbols, bool __pyx_v_keep_osymbols, bool __pyx_v_keep_state_numbering, bool __pyx_v_allow_negative_labels); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_8Compiler_2compile(struct __pyx_obj_9pywrapfst_Compiler *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_8Compiler_4write(struct __pyx_obj_9pywrapfst_Compiler *__pyx_v_self, PyObject *__pyx_v_expression); /* proto */
@@ -4070,7 +4081,7 @@ static PyObject *__pyx_pf_9pywrapfst_8Compiler_6__reduce_cython__(CYTHON_UNUSED
 static PyObject *__pyx_pf_9pywrapfst_8Compiler_8__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_Compiler *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */
 static int __pyx_pf_9pywrapfst_9FarReader___init__(struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_filenames); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_sources); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_9FarReader_6arc_type(struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_9FarReader_8done(struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_9FarReader_10error(struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self); /* proto */
@@ -4085,7 +4096,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_26__reduce_cython__(CYTHON_UNUSE
 static PyObject *__pyx_pf_9pywrapfst_9FarReader_28__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */
 static int __pyx_pf_9pywrapfst_9FarWriter___init__(struct __pyx_obj_9pywrapfst_FarWriter *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywrapfst_FarWriter *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_filename, PyObject *__pyx_v_arc_type, PyObject *__pyx_v_far_type); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_source, PyObject *__pyx_v_arc_type, PyObject *__pyx_v_far_type); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_9FarWriter_6add(struct __pyx_obj_9pywrapfst_FarWriter *__pyx_v_self, PyObject *__pyx_v_key, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_9FarWriter_8arc_type(struct __pyx_obj_9pywrapfst_FarWriter *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_9FarWriter_10error(struct __pyx_obj_9pywrapfst_FarWriter *__pyx_v_self); /* proto */
@@ -4113,63 +4124,62 @@ 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_tp_new_9pywrapfst___pyx_scope_struct____iter__(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
 static __pyx_t_10basictypes_int64 __pyx_k__3;
+static float __pyx_k__9;
+static float __pyx_k__10;
 static float __pyx_k__11;
-static float __pyx_k__12;
+static __pyx_t_10basictypes_int64 __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__17;
+static float __pyx_k__16;
+static __pyx_t_10basictypes_int64 __pyx_k__17;
 static float __pyx_k__18;
 static __pyx_t_10basictypes_int64 __pyx_k__19;
 static float __pyx_k__20;
-static __pyx_t_10basictypes_int64 __pyx_k__21;
-static float __pyx_k__22;
+static float __pyx_k__29;
+static float __pyx_k__30;
 static float __pyx_k__31;
-static float __pyx_k__32;
+static __pyx_t_10basictypes_int64 __pyx_k__32;
 static float __pyx_k__33;
 static __pyx_t_10basictypes_int64 __pyx_k__34;
 static float __pyx_k__35;
-static __pyx_t_10basictypes_int64 __pyx_k__36;
+static float __pyx_k__36;
 static float __pyx_k__37;
 static float __pyx_k__38;
-static float __pyx_k__39;
+static __pyx_t_10basictypes_int64 __pyx_k__39;
 static float __pyx_k__40;
-static __pyx_t_10basictypes_int64 __pyx_k__41;
-static float __pyx_k__42;
-static float __pyx_k__43;
-static __pyx_t_10basictypes_int32 __pyx_k__44;
-static __pyx_t_10basictypes_int32 __pyx_k__45;
+static float __pyx_k__41;
+static __pyx_t_10basictypes_int32 __pyx_k__42;
+static __pyx_t_10basictypes_int32 __pyx_k__43;
+static float __pyx_k__44;
+static __pyx_t_10basictypes_int64 __pyx_k__45;
 static float __pyx_k__46;
 static __pyx_t_10basictypes_int64 __pyx_k__47;
 static float __pyx_k__48;
 static __pyx_t_10basictypes_int64 __pyx_k__49;
-static float __pyx_k__50;
-static __pyx_t_10basictypes_int64 __pyx_k__51;
-static std::string __pyx_k__52;
-static std::string __pyx_k__53;
+static std::string __pyx_k__50;
+static std::string __pyx_k__51;
 static PyObject *__pyx_tuple_;
 static PyObject *__pyx_tuple__2;
 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__21;
+static PyObject *__pyx_tuple__22;
 static PyObject *__pyx_tuple__23;
 static PyObject *__pyx_tuple__24;
 static PyObject *__pyx_tuple__25;
 static PyObject *__pyx_tuple__26;
 static PyObject *__pyx_tuple__27;
 static PyObject *__pyx_tuple__28;
-static PyObject *__pyx_tuple__29;
-static PyObject *__pyx_tuple__30;
+static PyObject *__pyx_tuple__52;
+static PyObject *__pyx_tuple__53;
 static PyObject *__pyx_tuple__54;
 static PyObject *__pyx_tuple__55;
 static PyObject *__pyx_tuple__56;
 static PyObject *__pyx_tuple__57;
 static PyObject *__pyx_tuple__58;
-static PyObject *__pyx_tuple__59;
 static PyObject *__pyx_tuple__60;
 static PyObject *__pyx_tuple__62;
 static PyObject *__pyx_tuple__64;
@@ -4180,6 +4190,7 @@ static PyObject *__pyx_tuple__71;
 static PyObject *__pyx_tuple__72;
 static PyObject *__pyx_tuple__74;
 static PyObject *__pyx_tuple__76;
+static PyObject *__pyx_codeobj__59;
 static PyObject *__pyx_codeobj__61;
 static PyObject *__pyx_codeobj__63;
 static PyObject *__pyx_codeobj__65;
@@ -10092,7 +10103,7 @@ static size_t __pyx_f_9pywrapfst_12_SymbolTable_num_symbols(struct __pyx_obj_9py
  *     """
  *     return self._table.NumSymbols()             # <<<<<<<<<<<<<<
  * 
- *   cpdef void write(self, filename) except *:
+ *   cpdef void write(self, source) except *:
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
@@ -10162,13 +10173,13 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_24num_symbols(struct __pyx_o
 /* "pywrapfst.pyx":798
  *     return self._table.NumSymbols()
  * 
- *   cpdef void write(self, filename) except *:             # <<<<<<<<<<<<<<
+ *   cpdef void write(self, source) except *:             # <<<<<<<<<<<<<<
  *     """
- *     write(self, filename)
+ *     write(self, source)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_27write(PyObject *__pyx_v_self, PyObject *__pyx_v_filename); /*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) {
+static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_27write(PyObject *__pyx_v_self, PyObject *__pyx_v_source); /*proto*/
+static void __pyx_f_9pywrapfst_12_SymbolTable_write(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -10201,7 +10212,7 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write(struct __pyx_obj_9pywrapfst_
             __Pyx_DECREF_SET(__pyx_t_3, function);
           }
         }
-        __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_filename) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_filename);
+        __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_source);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
         if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 798, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
@@ -10226,24 +10237,24 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write(struct __pyx_obj_9pywrapfst_
   /* "pywrapfst.pyx":812
  *       FstIOError: Write failed.
  *     """
- *     if not self._table.Write(tostring(filename)):             # <<<<<<<<<<<<<<
- *       raise FstIOError("Write failed: {!r}".format(filename))
+ *     if not self._table.Write(tostring(source)):             # <<<<<<<<<<<<<<
+ *       raise FstIOError("Write failed: {!r}".format(source))
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
     __PYX_ERR(0, 812, __pyx_L1_error)
   }
-  __pyx_t_5 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 812, __pyx_L1_error)
+  __pyx_t_5 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 812, __pyx_L1_error)
   __pyx_t_6 = ((!(__pyx_v_self->_table->Write(__pyx_t_5) != 0)) != 0);
   if (unlikely(__pyx_t_6)) {
 
     /* "pywrapfst.pyx":813
  *     """
- *     if not self._table.Write(tostring(filename)):
- *       raise FstIOError("Write failed: {!r}".format(filename))             # <<<<<<<<<<<<<<
+ *     if not self._table.Write(tostring(source)):
+ *       raise FstIOError("Write failed: {!r}".format(source))             # <<<<<<<<<<<<<<
  * 
- *   cpdef void write_text(self, filename) except *:
+ *   cpdef void write_text(self, source) except *:
  */
     __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 813, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
@@ -10259,7 +10270,7 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write(struct __pyx_obj_9pywrapfst_
         __Pyx_DECREF_SET(__pyx_t_4, function);
       }
     }
-    __pyx_t_3 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_7, __pyx_v_filename) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_filename);
+    __pyx_t_3 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_7, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_source);
     __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
     if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 813, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
@@ -10287,8 +10298,8 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write(struct __pyx_obj_9pywrapfst_
     /* "pywrapfst.pyx":812
  *       FstIOError: Write failed.
  *     """
- *     if not self._table.Write(tostring(filename)):             # <<<<<<<<<<<<<<
- *       raise FstIOError("Write failed: {!r}".format(filename))
+ *     if not self._table.Write(tostring(source)):             # <<<<<<<<<<<<<<
+ *       raise FstIOError("Write failed: {!r}".format(source))
  * 
  */
   }
@@ -10296,9 +10307,9 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write(struct __pyx_obj_9pywrapfst_
   /* "pywrapfst.pyx":798
  *     return self._table.NumSymbols()
  * 
- *   cpdef void write(self, filename) except *:             # <<<<<<<<<<<<<<
+ *   cpdef void write(self, source) except *:             # <<<<<<<<<<<<<<
  *     """
- *     write(self, filename)
+ *     write(self, source)
  */
 
   /* function exit code */
@@ -10315,26 +10326,26 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write(struct __pyx_obj_9pywrapfst_
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_27write(PyObject *__pyx_v_self, PyObject *__pyx_v_filename); /*proto*/
-static char __pyx_doc_9pywrapfst_12_SymbolTable_26write[] = "\n    write(self, filename)\n\n    Serializes symbol table to a file.\n\n    This methods writes the SymbolTable to a file in binary format.\n\n    Args:\n      filename: The string location of the output file.\n\n    Raises:\n      FstIOError: Write failed.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_27write(PyObject *__pyx_v_self, PyObject *__pyx_v_filename) {
+static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_27write(PyObject *__pyx_v_self, PyObject *__pyx_v_source); /*proto*/
+static char __pyx_doc_9pywrapfst_12_SymbolTable_26write[] = "\n    write(self, source)\n\n    Serializes symbol table to a file.\n\n    This methods writes the SymbolTable to a file in binary format.\n\n    Args:\n      source: The string location of the output file.\n\n    Raises:\n      FstIOError: Write failed.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_27write(PyObject *__pyx_v_self, PyObject *__pyx_v_source) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("write (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_12_SymbolTable_26write(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self), ((PyObject *)__pyx_v_filename));
+  __pyx_r = __pyx_pf_9pywrapfst_12_SymbolTable_26write(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self), ((PyObject *)__pyx_v_source));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_26write(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_filename) {
+static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_26write(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_source) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   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, 798, __pyx_L1_error)
+  __pyx_f_9pywrapfst_12_SymbolTable_write(__pyx_v_self, __pyx_v_source, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 798, __pyx_L1_error)
   __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 798, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
@@ -10353,15 +10364,15 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_26write(struct __pyx_obj_9py
 }
 
 /* "pywrapfst.pyx":815
- *       raise FstIOError("Write failed: {!r}".format(filename))
+ *       raise FstIOError("Write failed: {!r}".format(source))
  * 
- *   cpdef void write_text(self, filename) except *:             # <<<<<<<<<<<<<<
+ *   cpdef void write_text(self, source) except *:             # <<<<<<<<<<<<<<
  *     """
- *     write_text(self, filename)
+ *     write_text(self, source)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_29write_text(PyObject *__pyx_v_self, PyObject *__pyx_v_filename); /*proto*/
-static void __pyx_f_9pywrapfst_12_SymbolTable_write_text(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_filename, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_29write_text(PyObject *__pyx_v_self, PyObject *__pyx_v_source); /*proto*/
+static void __pyx_f_9pywrapfst_12_SymbolTable_write_text(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -10394,7 +10405,7 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write_text(struct __pyx_obj_9pywra
             __Pyx_DECREF_SET(__pyx_t_3, function);
           }
         }
-        __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_filename) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_filename);
+        __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_source);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
         if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 815, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
@@ -10419,22 +10430,22 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write_text(struct __pyx_obj_9pywra
   /* "pywrapfst.pyx":829
  *       FstIOError: Write failed.
  *     """
- *     if not self._table.WriteText(tostring(filename)):             # <<<<<<<<<<<<<<
- *       raise FstIOError("Write failed: {!r}".format(filename))
+ *     if not self._table.WriteText(tostring(source)):             # <<<<<<<<<<<<<<
+ *       raise FstIOError("Write failed: {!r}".format(source))
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
     __PYX_ERR(0, 829, __pyx_L1_error)
   }
-  __pyx_t_5 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 829, __pyx_L1_error)
+  __pyx_t_5 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 829, __pyx_L1_error)
   __pyx_t_6 = ((!(__pyx_v_self->_table->WriteText(__pyx_t_5) != 0)) != 0);
   if (unlikely(__pyx_t_6)) {
 
     /* "pywrapfst.pyx":830
  *     """
- *     if not self._table.WriteText(tostring(filename)):
- *       raise FstIOError("Write failed: {!r}".format(filename))             # <<<<<<<<<<<<<<
+ *     if not self._table.WriteText(tostring(source)):
+ *       raise FstIOError("Write failed: {!r}".format(source))             # <<<<<<<<<<<<<<
  * 
  *   cpdef bytes write_to_string(self):
  */
@@ -10452,7 +10463,7 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write_text(struct __pyx_obj_9pywra
         __Pyx_DECREF_SET(__pyx_t_4, function);
       }
     }
-    __pyx_t_3 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_7, __pyx_v_filename) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_filename);
+    __pyx_t_3 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_7, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_source);
     __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
     if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 830, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
@@ -10480,18 +10491,18 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write_text(struct __pyx_obj_9pywra
     /* "pywrapfst.pyx":829
  *       FstIOError: Write failed.
  *     """
- *     if not self._table.WriteText(tostring(filename)):             # <<<<<<<<<<<<<<
- *       raise FstIOError("Write failed: {!r}".format(filename))
+ *     if not self._table.WriteText(tostring(source)):             # <<<<<<<<<<<<<<
+ *       raise FstIOError("Write failed: {!r}".format(source))
  * 
  */
   }
 
   /* "pywrapfst.pyx":815
- *       raise FstIOError("Write failed: {!r}".format(filename))
+ *       raise FstIOError("Write failed: {!r}".format(source))
  * 
- *   cpdef void write_text(self, filename) except *:             # <<<<<<<<<<<<<<
+ *   cpdef void write_text(self, source) except *:             # <<<<<<<<<<<<<<
  *     """
- *     write_text(self, filename)
+ *     write_text(self, source)
  */
 
   /* function exit code */
@@ -10508,26 +10519,26 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write_text(struct __pyx_obj_9pywra
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_29write_text(PyObject *__pyx_v_self, PyObject *__pyx_v_filename); /*proto*/
-static char __pyx_doc_9pywrapfst_12_SymbolTable_28write_text[] = "\n    write_text(self, filename)\n\n    Writes symbol table to text file.\n\n    This method writes the SymbolTable to a file in human-readable format.\n\n    Args:\n      filename: The string location of the output file.\n\n    Raises:\n      FstIOError: Write failed.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_29write_text(PyObject *__pyx_v_self, PyObject *__pyx_v_filename) {
+static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_29write_text(PyObject *__pyx_v_self, PyObject *__pyx_v_source); /*proto*/
+static char __pyx_doc_9pywrapfst_12_SymbolTable_28write_text[] = "\n    write_text(self, source)\n\n    Writes symbol table to text file.\n\n    This method writes the SymbolTable to a file in human-readable format.\n\n    Args:\n      source: The string location of the output file.\n\n    Raises:\n      FstIOError: Write failed.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_29write_text(PyObject *__pyx_v_self, PyObject *__pyx_v_source) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("write_text (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_12_SymbolTable_28write_text(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self), ((PyObject *)__pyx_v_filename));
+  __pyx_r = __pyx_pf_9pywrapfst_12_SymbolTable_28write_text(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self), ((PyObject *)__pyx_v_source));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_28write_text(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_filename) {
+static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_28write_text(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_source) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   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, 815, __pyx_L1_error)
+  __pyx_f_9pywrapfst_12_SymbolTable_write_text(__pyx_v_self, __pyx_v_source, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 815, __pyx_L1_error)
   __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 815, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
@@ -10546,7 +10557,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_28write_text(struct __pyx_ob
 }
 
 /* "pywrapfst.pyx":832
- *       raise FstIOError("Write failed: {!r}".format(filename))
+ *       raise FstIOError("Write failed: {!r}".format(source))
  * 
  *   cpdef bytes write_to_string(self):             # <<<<<<<<<<<<<<
  *     """
@@ -10612,7 +10623,7 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_write_to_string(struct __pyx_
     #endif
   }
 
-  /* "pywrapfst.pyx":847
+  /* "pywrapfst.pyx":845
  *     """
  *     cdef stringstream sstrm
  *     if not self._table.Write(sstrm):             # <<<<<<<<<<<<<<
@@ -10621,19 +10632,19 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_write_to_string(struct __pyx_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 847, __pyx_L1_error)
+    __PYX_ERR(0, 845, __pyx_L1_error)
   }
   __pyx_t_5 = ((!(__pyx_v_self->_table->Write(__pyx_v_sstrm) != 0)) != 0);
   if (unlikely(__pyx_t_5)) {
 
-    /* "pywrapfst.pyx":848
+    /* "pywrapfst.pyx":846
  *     cdef stringstream sstrm
  *     if not self._table.Write(sstrm):
  *       raise FstIOError("Write to string failed")             # <<<<<<<<<<<<<<
  *     return sstrm.str()
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 848, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 846, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_3 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -10647,14 +10658,14 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_write_to_string(struct __pyx_
     }
     __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_kp_u_Write_to_string_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_Write_to_string_failed);
     __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 848, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 846, __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, 848, __pyx_L1_error)
+    __PYX_ERR(0, 846, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":847
+    /* "pywrapfst.pyx":845
  *     """
  *     cdef stringstream sstrm
  *     if not self._table.Write(sstrm):             # <<<<<<<<<<<<<<
@@ -10663,7 +10674,7 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_write_to_string(struct __pyx_
  */
   }
 
-  /* "pywrapfst.pyx":849
+  /* "pywrapfst.pyx":847
  *     if not self._table.Write(sstrm):
  *       raise FstIOError("Write to string failed")
  *     return sstrm.str()             # <<<<<<<<<<<<<<
@@ -10671,14 +10682,14 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_write_to_string(struct __pyx_
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_sstrm.str()); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 849, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_sstrm.str()); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 847, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((PyObject*)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
   /* "pywrapfst.pyx":832
- *       raise FstIOError("Write failed: {!r}".format(filename))
+ *       raise FstIOError("Write failed: {!r}".format(source))
  * 
  *   cpdef bytes write_to_string(self):             # <<<<<<<<<<<<<<
  *     """
@@ -10701,7 +10712,7 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_write_to_string(struct __pyx_
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_31write_to_string(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_12_SymbolTable_30write_to_string[] = "\n    write_to_string(self)\n\n    Serializes SymbolTable to a string.\n\n    Returns:\n      A bytestring.\n\n    Raises:\n      FstIOError: Write to string failed.\n\n    See also: `read_from_string`.\n    ";
+static char __pyx_doc_9pywrapfst_12_SymbolTable_30write_to_string[] = "\n    write_to_string(self)\n\n    Serializes SymbolTable to a string.\n\n    Returns:\n      A bytestring.\n\n    Raises:\n      FstIOError: Write to string failed.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_31write_to_string(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -10736,7 +10747,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_30write_to_string(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":867
+/* "pywrapfst.pyx":865
  *   # Doing so will allow undefined behavior.
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -10769,7 +10780,7 @@ static PyObject *__pyx_pf_9pywrapfst_24_EncodeMapperSymbolTable___repr__(struct
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":868
+  /* "pywrapfst.pyx":866
  * 
  *   def __repr__(self):
  *     return "<const EncodeMapper SymbolTable {!r} at 0x{:x}>".format(self.name(),             # <<<<<<<<<<<<<<
@@ -10777,23 +10788,23 @@ static PyObject *__pyx_pf_9pywrapfst_24_EncodeMapperSymbolTable___repr__(struct
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_const_EncodeMapper_SymbolTable, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 868, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_const_EncodeMapper_SymbolTable, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 866, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "name");
-    __PYX_ERR(0, 868, __pyx_L1_error)
+    __PYX_ERR(0, 866, __pyx_L1_error)
   }
-  __pyx_t_3 = __pyx_convert_PyUnicode_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, 868, __pyx_L1_error)
+  __pyx_t_3 = __pyx_convert_PyUnicode_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, 866, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
 
-  /* "pywrapfst.pyx":869
+  /* "pywrapfst.pyx":867
  *   def __repr__(self):
  *     return "<const EncodeMapper SymbolTable {!r} at 0x{:x}>".format(self.name(),
  *                                                                     id(self))             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 869, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 867, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __pyx_t_5 = NULL;
   __pyx_t_6 = 0;
@@ -10810,7 +10821,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_5, __pyx_t_3, __pyx_t_4};
-    __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 868, __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, 866, __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;
@@ -10820,7 +10831,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_5, __pyx_t_3, __pyx_t_4};
-    __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 868, __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, 866, __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;
@@ -10828,7 +10839,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, 868, __pyx_L1_error)
+    __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 866, __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;
@@ -10839,7 +10850,7 @@ static PyObject *__pyx_pf_9pywrapfst_24_EncodeMapperSymbolTable___repr__(struct
     PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_4);
     __pyx_t_3 = 0;
     __pyx_t_4 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 868, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 866, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
   }
@@ -10848,7 +10859,7 @@ static PyObject *__pyx_pf_9pywrapfst_24_EncodeMapperSymbolTable___repr__(struct
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":867
+  /* "pywrapfst.pyx":865
  *   # Doing so will allow undefined behavior.
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -10872,7 +10883,7 @@ static PyObject *__pyx_pf_9pywrapfst_24_EncodeMapperSymbolTable___repr__(struct
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":886
+/* "pywrapfst.pyx":884
  *   # Doing so will allow undefined behavior.
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -10905,7 +10916,7 @@ static PyObject *__pyx_pf_9pywrapfst_15_FstSymbolTable___repr__(struct __pyx_obj
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":887
+  /* "pywrapfst.pyx":885
  * 
  *   def __repr__(self):
  *     return "<const Fst SymbolTable {!r} at 0x{:x}>".format(self.name(),             # <<<<<<<<<<<<<<
@@ -10913,23 +10924,23 @@ static PyObject *__pyx_pf_9pywrapfst_15_FstSymbolTable___repr__(struct __pyx_obj
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_const_Fst_SymbolTable_r_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 887, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_const_Fst_SymbolTable_r_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 885, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "name");
-    __PYX_ERR(0, 887, __pyx_L1_error)
+    __PYX_ERR(0, 885, __pyx_L1_error)
   }
-  __pyx_t_3 = __pyx_convert_PyUnicode_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, 887, __pyx_L1_error)
+  __pyx_t_3 = __pyx_convert_PyUnicode_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, 885, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
 
-  /* "pywrapfst.pyx":888
+  /* "pywrapfst.pyx":886
  *   def __repr__(self):
  *     return "<const Fst SymbolTable {!r} at 0x{:x}>".format(self.name(),
  *                                                            id(self))             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 888, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 886, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __pyx_t_5 = NULL;
   __pyx_t_6 = 0;
@@ -10946,7 +10957,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_5, __pyx_t_3, __pyx_t_4};
-    __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 887, __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, 885, __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;
@@ -10956,7 +10967,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_5, __pyx_t_3, __pyx_t_4};
-    __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 887, __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, 885, __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;
@@ -10964,7 +10975,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, 887, __pyx_L1_error)
+    __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 885, __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;
@@ -10975,7 +10986,7 @@ static PyObject *__pyx_pf_9pywrapfst_15_FstSymbolTable___repr__(struct __pyx_obj
     PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_4);
     __pyx_t_3 = 0;
     __pyx_t_4 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 887, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 885, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
   }
@@ -10984,7 +10995,7 @@ static PyObject *__pyx_pf_9pywrapfst_15_FstSymbolTable___repr__(struct __pyx_obj
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":886
+  /* "pywrapfst.pyx":884
  *   # Doing so will allow undefined behavior.
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -11008,7 +11019,7 @@ static PyObject *__pyx_pf_9pywrapfst_15_FstSymbolTable___repr__(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":902
+/* "pywrapfst.pyx":900
  *   """
  * 
  *   cpdef int64 add_symbol(self, symbol, int64 key=fst.kNoSymbol):             # <<<<<<<<<<<<<<
@@ -11047,10 +11058,10 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_s
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add_symbol); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 902, __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, 900, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_19_MutableSymbolTable_1add_symbol)) {
-        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_key); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 902, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_key); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 900, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -11068,7 +11079,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, 902, __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, 900, __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;
@@ -11077,14 +11088,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, 902, __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, 900, __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, 902, __pyx_L1_error)
+          __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 900, __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;
@@ -11095,12 +11106,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, 902, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 900, __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, 902, __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, 900, __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;
@@ -11119,17 +11130,17 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_s
     #endif
   }
 
-  /* "pywrapfst.pyx":919
+  /* "pywrapfst.pyx":917
  *       The integer key of the new symbol.
  *     """
  *     cdef string symbol_string = tostring(symbol)             # <<<<<<<<<<<<<<
  *     if key != fst.kNoSymbol:
  *       return self._table.AddSymbol(symbol_string, key)
  */
-  __pyx_t_9 = __pyx_f_9pywrapfst_tostring(__pyx_v_symbol); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 919, __pyx_L1_error)
+  __pyx_t_9 = __pyx_f_9pywrapfst_tostring(__pyx_v_symbol); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 917, __pyx_L1_error)
   __pyx_v_symbol_string = __pyx_t_9;
 
-  /* "pywrapfst.pyx":920
+  /* "pywrapfst.pyx":918
  *     """
  *     cdef string symbol_string = tostring(symbol)
  *     if key != fst.kNoSymbol:             # <<<<<<<<<<<<<<
@@ -11139,7 +11150,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_s
   __pyx_t_10 = ((__pyx_v_key != fst::kNoSymbol) != 0);
   if (__pyx_t_10) {
 
-    /* "pywrapfst.pyx":921
+    /* "pywrapfst.pyx":919
  *     cdef string symbol_string = tostring(symbol)
  *     if key != fst.kNoSymbol:
  *       return self._table.AddSymbol(symbol_string, key)             # <<<<<<<<<<<<<<
@@ -11148,12 +11159,12 @@ 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 '%.30s'", "_table");
-      __PYX_ERR(0, 921, __pyx_L1_error)
+      __PYX_ERR(0, 919, __pyx_L1_error)
     }
     __pyx_r = __pyx_v_self->__pyx_base._table->AddSymbol(__pyx_v_symbol_string, __pyx_v_key);
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":920
+    /* "pywrapfst.pyx":918
  *     """
  *     cdef string symbol_string = tostring(symbol)
  *     if key != fst.kNoSymbol:             # <<<<<<<<<<<<<<
@@ -11162,7 +11173,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_s
  */
   }
 
-  /* "pywrapfst.pyx":923
+  /* "pywrapfst.pyx":921
  *       return self._table.AddSymbol(symbol_string, key)
  *     else:
  *       return self._table.AddSymbol(symbol_string)             # <<<<<<<<<<<<<<
@@ -11172,13 +11183,13 @@ 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 '%.30s'", "_table");
-      __PYX_ERR(0, 923, __pyx_L1_error)
+      __PYX_ERR(0, 921, __pyx_L1_error)
     }
     __pyx_r = __pyx_v_self->__pyx_base._table->AddSymbol(__pyx_v_symbol_string);
     goto __pyx_L0;
   }
 
-  /* "pywrapfst.pyx":902
+  /* "pywrapfst.pyx":900
  *   """
  * 
  *   cpdef int64 add_symbol(self, symbol, int64 key=fst.kNoSymbol):             # <<<<<<<<<<<<<<
@@ -11237,7 +11248,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, 902, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add_symbol") < 0)) __PYX_ERR(0, 900, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -11250,14 +11261,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, 902, __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, 900, __pyx_L3_error)
     } else {
       __pyx_v_key = __pyx_k__3;
     }
   }
   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, 902, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("add_symbol", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 900, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableSymbolTable.add_symbol", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -11281,7 +11292,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, 902, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 900, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -11298,7 +11309,7 @@ static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_add_symbol(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":925
+/* "pywrapfst.pyx":923
  *       return self._table.AddSymbol(symbol_string)
  * 
  *   cpdef void add_table(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
@@ -11323,7 +11334,7 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(struct __pyx_obj_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add_table); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 925, __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)(void*)__pyx_pw_9pywrapfst_19_MutableSymbolTable_3add_table)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -11339,7 +11350,7 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(struct __pyx_obj_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, ((PyObject *)__pyx_v_syms)) : __Pyx_PyObject_CallOneArg(__pyx_t_3, ((PyObject *)__pyx_v_syms));
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 925, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 923, __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;
@@ -11359,7 +11370,7 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(struct __pyx_obj_
     #endif
   }
 
-  /* "pywrapfst.pyx":937
+  /* "pywrapfst.pyx":935
  *       syms: A SymbolTable to be merged with the current table.
  *     """
  *     self._table.AddTable(deref(syms._table))             # <<<<<<<<<<<<<<
@@ -11368,15 +11379,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 '%.30s'", "_table");
-    __PYX_ERR(0, 937, __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 '%.30s'", "_table");
-    __PYX_ERR(0, 937, __pyx_L1_error)
+    __PYX_ERR(0, 935, __pyx_L1_error)
   }
   __pyx_v_self->__pyx_base._table->AddTable((*__pyx_v_syms->_table));
 
-  /* "pywrapfst.pyx":925
+  /* "pywrapfst.pyx":923
  *       return self._table.AddSymbol(symbol_string)
  * 
  *   cpdef void add_table(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
@@ -11403,7 +11414,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, 925, __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 */
@@ -11421,7 +11432,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, 925, __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;
@@ -11438,7 +11449,7 @@ static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_2add_table(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":939
+/* "pywrapfst.pyx":937
  *     self._table.AddTable(deref(syms._table))
  * 
  *   cpdef void set_name(self, new_name) except *:             # <<<<<<<<<<<<<<
@@ -11464,7 +11475,7 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_set_name(struct __pyx_obj_9
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_name); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 939, __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)(void*)__pyx_pw_9pywrapfst_19_MutableSymbolTable_5set_name)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -11480,7 +11491,7 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_set_name(struct __pyx_obj_9
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_new_name) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_new_name);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 939, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 937, __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;
@@ -11500,7 +11511,7 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_set_name(struct __pyx_obj_9
     #endif
   }
 
-  /* "pywrapfst.pyx":940
+  /* "pywrapfst.pyx":938
  * 
  *   cpdef void set_name(self, new_name) except *:
  *     self._table.SetName(tostring(new_name))             # <<<<<<<<<<<<<<
@@ -11509,12 +11520,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 '%.30s'", "_table");
-    __PYX_ERR(0, 940, __pyx_L1_error)
+    __PYX_ERR(0, 938, __pyx_L1_error)
   }
-  __pyx_t_5 = __pyx_f_9pywrapfst_tostring(__pyx_v_new_name); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 940, __pyx_L1_error)
+  __pyx_t_5 = __pyx_f_9pywrapfst_tostring(__pyx_v_new_name); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 938, __pyx_L1_error)
   __pyx_v_self->__pyx_base._table->SetName(__pyx_t_5);
 
-  /* "pywrapfst.pyx":939
+  /* "pywrapfst.pyx":937
  *     self._table.AddTable(deref(syms._table))
  * 
  *   cpdef void set_name(self, new_name) except *:             # <<<<<<<<<<<<<<
@@ -11553,8 +11564,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, 939, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 939, __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;
@@ -11571,7 +11582,7 @@ static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_4set_name(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":950
+/* "pywrapfst.pyx":948
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -11604,7 +11615,7 @@ static PyObject *__pyx_pf_9pywrapfst_22_MutableFstSymbolTable___repr__(struct __
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":951
+  /* "pywrapfst.pyx":949
  * 
  *   def __repr__(self):
  *     return "<Fst SymbolTable {!r} at 0x{:x}>".format(self.name(), id(self))             # <<<<<<<<<<<<<<
@@ -11612,15 +11623,15 @@ static PyObject *__pyx_pf_9pywrapfst_22_MutableFstSymbolTable___repr__(struct __
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Fst_SymbolTable_r_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 951, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_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 '%.30s'", "name");
-    __PYX_ERR(0, 951, __pyx_L1_error)
+    __PYX_ERR(0, 949, __pyx_L1_error)
   }
-  __pyx_t_3 = __pyx_convert_PyUnicode_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, 951, __pyx_L1_error)
+  __pyx_t_3 = __pyx_convert_PyUnicode_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 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 951, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 949, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __pyx_t_5 = NULL;
   __pyx_t_6 = 0;
@@ -11637,7 +11648,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_5, __pyx_t_3, __pyx_t_4};
-    __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 951, __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_5); __pyx_t_5 = 0;
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -11647,7 +11658,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_5, __pyx_t_3, __pyx_t_4};
-    __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 951, __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_5); __pyx_t_5 = 0;
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -11655,7 +11666,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, 951, __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_5) {
       __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __pyx_t_5 = NULL;
@@ -11666,7 +11677,7 @@ static PyObject *__pyx_pf_9pywrapfst_22_MutableFstSymbolTable___repr__(struct __
     PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_4);
     __pyx_t_3 = 0;
     __pyx_t_4 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 951, __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;
   }
@@ -11675,7 +11686,7 @@ static PyObject *__pyx_pf_9pywrapfst_22_MutableFstSymbolTable___repr__(struct __
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":950
+  /* "pywrapfst.pyx":948
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -11699,7 +11710,7 @@ static PyObject *__pyx_pf_9pywrapfst_22_MutableFstSymbolTable___repr__(struct __
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":971
+/* "pywrapfst.pyx":969
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -11732,7 +11743,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable___repr__(struct __pyx_obj_9py
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":972
+  /* "pywrapfst.pyx":970
  * 
  *   def __repr__(self):
  *     return "<SymbolTable {!r} at 0x{:x}>".format(self.name(), id(self))             # <<<<<<<<<<<<<<
@@ -11740,15 +11751,15 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable___repr__(struct __pyx_obj_9py
  *   def __init__(self, name="<unspecified>"):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_SymbolTable_r_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 972, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_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 '%.30s'", "name");
-    __PYX_ERR(0, 972, __pyx_L1_error)
+    __PYX_ERR(0, 970, __pyx_L1_error)
   }
-  __pyx_t_3 = __pyx_convert_PyUnicode_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, 972, __pyx_L1_error)
+  __pyx_t_3 = __pyx_convert_PyUnicode_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 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 972, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 970, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __pyx_t_5 = NULL;
   __pyx_t_6 = 0;
@@ -11765,7 +11776,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_5, __pyx_t_3, __pyx_t_4};
-    __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 972, __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_5); __pyx_t_5 = 0;
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -11775,7 +11786,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_5, __pyx_t_3, __pyx_t_4};
-    __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 972, __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_5); __pyx_t_5 = 0;
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -11783,7 +11794,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, 972, __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_5) {
       __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __pyx_t_5 = NULL;
@@ -11794,7 +11805,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable___repr__(struct __pyx_obj_9py
     PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_4);
     __pyx_t_3 = 0;
     __pyx_t_4 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 972, __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;
   }
@@ -11803,7 +11814,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable___repr__(struct __pyx_obj_9py
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":971
+  /* "pywrapfst.pyx":969
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -11827,7 +11838,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable___repr__(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":974
+/* "pywrapfst.pyx":972
  *     return "<SymbolTable {!r} at 0x{:x}>".format(self.name(), id(self))
  * 
  *   def __init__(self, name="<unspecified>"):             # <<<<<<<<<<<<<<
@@ -11864,7 +11875,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, 974, __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)) {
@@ -11878,7 +11889,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, 974, __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();
@@ -11897,21 +11908,21 @@ static int __pyx_pf_9pywrapfst_11SymbolTable_2__init__(struct __pyx_obj_9pywrapf
   std::string __pyx_t_1;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":975
+  /* "pywrapfst.pyx":973
  * 
  *   def __init__(self, name="<unspecified>"):
  *     self._table = new fst.SymbolTable(tostring(name))             # <<<<<<<<<<<<<<
  *     self._smart_table.reset(self._table)
  * 
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_name); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 975, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_name); 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 '%.30s'", "_table");
-    __PYX_ERR(0, 975, __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":976
+  /* "pywrapfst.pyx":974
  *   def __init__(self, name="<unspecified>"):
  *     self._table = new fst.SymbolTable(tostring(name))
  *     self._smart_table.reset(self._table)             # <<<<<<<<<<<<<<
@@ -11920,15 +11931,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 '%.30s'", "_smart_table");
-    __PYX_ERR(0, 976, __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 '%.30s'", "_table");
-    __PYX_ERR(0, 976, __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":974
+  /* "pywrapfst.pyx":972
  *     return "<SymbolTable {!r} at 0x{:x}>".format(self.name(), id(self))
  * 
  *   def __init__(self, name="<unspecified>"):             # <<<<<<<<<<<<<<
@@ -11947,29 +11958,29 @@ static int __pyx_pf_9pywrapfst_11SymbolTable_2__init__(struct __pyx_obj_9pywrapf
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":979
+/* "pywrapfst.pyx":977
  * 
  *   @classmethod
- *   def read(cls, filename):             # <<<<<<<<<<<<<<
+ *   def read(cls, source):             # <<<<<<<<<<<<<<
  *     """
- *     SymbolTable.read(filename)
+ *     SymbolTable.read(source)
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11SymbolTable_5read(PyObject *__pyx_v_cls, PyObject *__pyx_v_filename); /*proto*/
-static char __pyx_doc_9pywrapfst_11SymbolTable_4read[] = "\n    SymbolTable.read(filename)\n\n    Reads symbol table from binary file.\n\n    This class method creates a new SymbolTable from a symbol table binary file.\n\n    Args:\n      filename: The string location of the input binary file.\n\n    Returns:\n      A new SymbolTable instance.\n\n    See also: `SymbolTable.read_fst`, `SymbolTable.read_text`.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11SymbolTable_5read(PyObject *__pyx_v_cls, PyObject *__pyx_v_filename) {
+static PyObject *__pyx_pw_9pywrapfst_11SymbolTable_5read(PyObject *__pyx_v_cls, PyObject *__pyx_v_source); /*proto*/
+static char __pyx_doc_9pywrapfst_11SymbolTable_4read[] = "\n    SymbolTable.read(source)\n\n    Reads symbol table from binary file.\n\n    This class method creates a new SymbolTable from a symbol table binary file.\n\n    Args:\n      source: The string location of the input binary file.\n\n    Returns:\n      A new SymbolTable instance.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11SymbolTable_5read(PyObject *__pyx_v_cls, PyObject *__pyx_v_source) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("read (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_11SymbolTable_4read(((PyTypeObject*)__pyx_v_cls), ((PyObject *)__pyx_v_filename));
+  __pyx_r = __pyx_pf_9pywrapfst_11SymbolTable_4read(((PyTypeObject*)__pyx_v_cls), ((PyObject *)__pyx_v_source));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_filename) {
+static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_source) {
   std::unique_ptr<fst::SymbolTable>  __pyx_v_syms;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
@@ -11982,36 +11993,36 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObj
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("read", 0);
 
-  /* "pywrapfst.pyx":996
+  /* "pywrapfst.pyx":992
  *     """
  *     cdef unique_ptr[fst.SymbolTable] syms
- *     syms.reset(fst.SymbolTable.Read(tostring(filename)))             # <<<<<<<<<<<<<<
+ *     syms.reset(fst.SymbolTable.Read(tostring(source)))             # <<<<<<<<<<<<<<
  *     if syms.get() == NULL:
- *       raise FstIOError("Read failed: {!r}".format(filename))
+ *       raise FstIOError("Read failed: {!r}".format(source))
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 996, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 992, __pyx_L1_error)
   __pyx_v_syms.reset(fst::SymbolTable::Read(__pyx_t_1));
 
-  /* "pywrapfst.pyx":997
+  /* "pywrapfst.pyx":993
  *     cdef unique_ptr[fst.SymbolTable] syms
- *     syms.reset(fst.SymbolTable.Read(tostring(filename)))
+ *     syms.reset(fst.SymbolTable.Read(tostring(source)))
  *     if syms.get() == NULL:             # <<<<<<<<<<<<<<
- *       raise FstIOError("Read failed: {!r}".format(filename))
+ *       raise FstIOError("Read failed: {!r}".format(source))
  *     return _init_SymbolTable(syms.release())
  */
   __pyx_t_2 = ((__pyx_v_syms.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":998
- *     syms.reset(fst.SymbolTable.Read(tostring(filename)))
+    /* "pywrapfst.pyx":994
+ *     syms.reset(fst.SymbolTable.Read(tostring(source)))
  *     if syms.get() == NULL:
- *       raise FstIOError("Read failed: {!r}".format(filename))             # <<<<<<<<<<<<<<
+ *       raise FstIOError("Read failed: {!r}".format(source))             # <<<<<<<<<<<<<<
  *     return _init_SymbolTable(syms.release())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 998, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 994, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 998, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 994, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __pyx_t_7 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
@@ -12023,9 +12034,9 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObj
         __Pyx_DECREF_SET(__pyx_t_6, function);
       }
     }
-    __pyx_t_5 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_v_filename) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_filename);
+    __pyx_t_5 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_source);
     __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 998, __pyx_L1_error)
+    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 994, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __pyx_t_6 = NULL;
@@ -12041,42 +12052,42 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObj
     __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5);
     __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 998, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 994, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 998, __pyx_L1_error)
+    __PYX_ERR(0, 994, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":997
+    /* "pywrapfst.pyx":993
  *     cdef unique_ptr[fst.SymbolTable] syms
- *     syms.reset(fst.SymbolTable.Read(tostring(filename)))
+ *     syms.reset(fst.SymbolTable.Read(tostring(source)))
  *     if syms.get() == NULL:             # <<<<<<<<<<<<<<
- *       raise FstIOError("Read failed: {!r}".format(filename))
+ *       raise FstIOError("Read failed: {!r}".format(source))
  *     return _init_SymbolTable(syms.release())
  */
   }
 
-  /* "pywrapfst.pyx":999
+  /* "pywrapfst.pyx":995
  *     if syms.get() == NULL:
- *       raise FstIOError("Read failed: {!r}".format(filename))
+ *       raise FstIOError("Read failed: {!r}".format(source))
  *     return _init_SymbolTable(syms.release())             # <<<<<<<<<<<<<<
  * 
  *   @classmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(__pyx_v_syms.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 999, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(__pyx_v_syms.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 995, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":979
+  /* "pywrapfst.pyx":977
  * 
  *   @classmethod
- *   def read(cls, filename):             # <<<<<<<<<<<<<<
+ *   def read(cls, source):             # <<<<<<<<<<<<<<
  *     """
- *     SymbolTable.read(filename)
+ *     SymbolTable.read(source)
  */
 
   /* function exit code */
@@ -12094,25 +12105,25 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1002
+/* "pywrapfst.pyx":998
  * 
  *   @classmethod
- *   def read_text(cls, filename, bool allow_negative_labels=False):             # <<<<<<<<<<<<<<
+ *   def read_text(cls, source, bool allow_negative_labels=False):             # <<<<<<<<<<<<<<
  *     """
- *     SymbolTable.read_text(filename)
+ *     SymbolTable.read_text(source)
  */
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_11SymbolTable_7read_text(PyObject *__pyx_v_cls, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11SymbolTable_6read_text[] = "\n    SymbolTable.read_text(filename)\n\n    Reads symbol table from text file.\n\n    This class method creates a new SymbolTable from a symbol table text file.\n\n    Args:\n      filename: The string location of the input text file.\n      allow_negative_labels: Should negative labels be allowed? (Not\n          recommended; may cause conflicts).\n\n    Returns:\n      A new SymbolTable instance.\n\n    See also: `SymbolTable.read`, `SymbolTable.read_fst`.\n    ";
+static char __pyx_doc_9pywrapfst_11SymbolTable_6read_text[] = "\n    SymbolTable.read_text(source)\n\n    Reads symbol table from text file.\n\n    This class method creates a new SymbolTable from a symbol table text file.\n\n    Args:\n      source: The string location of the input text file.\n      allow_negative_labels: Should negative labels be allowed? (Not\n          recommended; may cause conflicts).\n\n    Returns:\n      A new SymbolTable instance.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_11SymbolTable_7read_text(PyObject *__pyx_v_cls, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyObject *__pyx_v_filename = 0;
+  PyObject *__pyx_v_source = 0;
   bool __pyx_v_allow_negative_labels;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("read_text (wrapper)", 0);
   {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_filename,&__pyx_n_s_allow_negative_labels,0};
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_source,&__pyx_n_s_allow_negative_labels,0};
     PyObject* values[2] = {0,0};
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
@@ -12128,7 +12139,7 @@ static PyObject *__pyx_pw_9pywrapfst_11SymbolTable_7read_text(PyObject *__pyx_v_
       kw_args = PyDict_Size(__pyx_kwds);
       switch (pos_args) {
         case  0:
-        if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_filename)) != 0)) kw_args--;
+        if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_source)) != 0)) kw_args--;
         else goto __pyx_L5_argtuple_error;
         CYTHON_FALLTHROUGH;
         case  1:
@@ -12138,7 +12149,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, 1002, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "read_text") < 0)) __PYX_ERR(0, 998, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -12149,29 +12160,29 @@ static PyObject *__pyx_pw_9pywrapfst_11SymbolTable_7read_text(PyObject *__pyx_v_
         default: goto __pyx_L5_argtuple_error;
       }
     }
-    __pyx_v_filename = values[0];
+    __pyx_v_source = values[0];
     if (values[1]) {
-      __pyx_v_allow_negative_labels = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_allow_negative_labels == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1002, __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, 998, __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, 1002, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("read_text", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 998, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.SymbolTable.read_text", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11SymbolTable_6read_text(((PyTypeObject*)__pyx_v_cls), __pyx_v_filename, __pyx_v_allow_negative_labels);
+  __pyx_r = __pyx_pf_9pywrapfst_11SymbolTable_6read_text(((PyTypeObject*)__pyx_v_cls), __pyx_v_source, __pyx_v_allow_negative_labels);
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_filename, bool __pyx_v_allow_negative_labels) {
+static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_source, bool __pyx_v_allow_negative_labels) {
   std::unique_ptr<fst::SymbolTableTextOptions>  __pyx_v_opts;
   std::unique_ptr<fst::SymbolTable>  __pyx_v_syms;
   PyObject *__pyx_r = NULL;
@@ -12185,45 +12196,45 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("read_text", 0);
 
-  /* "pywrapfst.pyx":1021
+  /* "pywrapfst.pyx":1015
  *     """
  *     cdef unique_ptr[fst.SymbolTableTextOptions] opts
  *     opts.reset(new fst.SymbolTableTextOptions(allow_negative_labels))             # <<<<<<<<<<<<<<
  *     cdef unique_ptr[fst.SymbolTable] syms
- *     syms.reset(fst.SymbolTable.ReadText(tostring(filename), deref(opts)))
+ *     syms.reset(fst.SymbolTable.ReadText(tostring(source), deref(opts)))
  */
   __pyx_v_opts.reset(new fst::SymbolTableTextOptions(__pyx_v_allow_negative_labels));
 
-  /* "pywrapfst.pyx":1023
+  /* "pywrapfst.pyx":1017
  *     opts.reset(new fst.SymbolTableTextOptions(allow_negative_labels))
  *     cdef unique_ptr[fst.SymbolTable] syms
- *     syms.reset(fst.SymbolTable.ReadText(tostring(filename), deref(opts)))             # <<<<<<<<<<<<<<
+ *     syms.reset(fst.SymbolTable.ReadText(tostring(source), deref(opts)))             # <<<<<<<<<<<<<<
  *     if syms.get() == NULL:
- *       raise FstIOError("Read failed: {!r}".format(filename))
+ *       raise FstIOError("Read failed: {!r}".format(source))
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1023, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1017, __pyx_L1_error)
   __pyx_v_syms.reset(fst::SymbolTable::ReadText(__pyx_t_1, (*__pyx_v_opts)));
 
-  /* "pywrapfst.pyx":1024
+  /* "pywrapfst.pyx":1018
  *     cdef unique_ptr[fst.SymbolTable] syms
- *     syms.reset(fst.SymbolTable.ReadText(tostring(filename), deref(opts)))
+ *     syms.reset(fst.SymbolTable.ReadText(tostring(source), deref(opts)))
  *     if syms.get() == NULL:             # <<<<<<<<<<<<<<
- *       raise FstIOError("Read failed: {!r}".format(filename))
+ *       raise FstIOError("Read failed: {!r}".format(source))
  *     return _init_SymbolTable(syms.release())
  */
   __pyx_t_2 = ((__pyx_v_syms.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":1025
- *     syms.reset(fst.SymbolTable.ReadText(tostring(filename), deref(opts)))
+    /* "pywrapfst.pyx":1019
+ *     syms.reset(fst.SymbolTable.ReadText(tostring(source), deref(opts)))
  *     if syms.get() == NULL:
- *       raise FstIOError("Read failed: {!r}".format(filename))             # <<<<<<<<<<<<<<
+ *       raise FstIOError("Read failed: {!r}".format(source))             # <<<<<<<<<<<<<<
  *     return _init_SymbolTable(syms.release())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1025, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1019, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1025, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1019, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __pyx_t_7 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
@@ -12235,9 +12246,9 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
         __Pyx_DECREF_SET(__pyx_t_6, function);
       }
     }
-    __pyx_t_5 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_v_filename) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_filename);
+    __pyx_t_5 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_source);
     __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1025, __pyx_L1_error)
+    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1019, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __pyx_t_6 = NULL;
@@ -12253,42 +12264,42 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
     __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5);
     __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1025, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1019, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 1025, __pyx_L1_error)
+    __PYX_ERR(0, 1019, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1024
+    /* "pywrapfst.pyx":1018
  *     cdef unique_ptr[fst.SymbolTable] syms
- *     syms.reset(fst.SymbolTable.ReadText(tostring(filename), deref(opts)))
+ *     syms.reset(fst.SymbolTable.ReadText(tostring(source), deref(opts)))
  *     if syms.get() == NULL:             # <<<<<<<<<<<<<<
- *       raise FstIOError("Read failed: {!r}".format(filename))
+ *       raise FstIOError("Read failed: {!r}".format(source))
  *     return _init_SymbolTable(syms.release())
  */
   }
 
-  /* "pywrapfst.pyx":1026
+  /* "pywrapfst.pyx":1020
  *     if syms.get() == NULL:
- *       raise FstIOError("Read failed: {!r}".format(filename))
+ *       raise FstIOError("Read failed: {!r}".format(source))
  *     return _init_SymbolTable(syms.release())             # <<<<<<<<<<<<<<
  * 
  *   @classmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(__pyx_v_syms.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1026, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(__pyx_v_syms.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1020, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1002
+  /* "pywrapfst.pyx":998
  * 
  *   @classmethod
- *   def read_text(cls, filename, bool allow_negative_labels=False):             # <<<<<<<<<<<<<<
+ *   def read_text(cls, source, bool allow_negative_labels=False):             # <<<<<<<<<<<<<<
  *     """
- *     SymbolTable.read_text(filename)
+ *     SymbolTable.read_text(source)
  */
 
   /* function exit code */
@@ -12306,25 +12317,25 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1029
+/* "pywrapfst.pyx":1023
  * 
  *   @classmethod
- *   def read_fst(cls, filename, bool input_table):             # <<<<<<<<<<<<<<
+ *   def read_fst(cls, source, bool input_table):             # <<<<<<<<<<<<<<
  *     """
- *     SymbolTable.read_fst(filename, input_table)
+ *     SymbolTable.read_fst(source, input_table)
  */
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_11SymbolTable_9read_fst(PyObject *__pyx_v_cls, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11SymbolTable_8read_fst[] = "\n    SymbolTable.read_fst(filename, input_table)\n\n    Reads symbol table from an FST file without loading the corresponding FST.\n\n    This class method creates a new SymbolTable by reading either the input or\n    output symbol table from an FST file, without loading the corresponding FST.\n\n    Args:\n      filename: The string location of the input FST file.\n      input_table: Should the input table be read (True) or the output table\n          (False)?\n\n    Returns:\n      A new SymbolTable instance, or None if none can be read.\n\n    Raises:\n      FstIOError: Read failed.\n\n    See also: `SymbolTable.read`, `SymbolTable.read_text`.\n    ";
+static char __pyx_doc_9pywrapfst_11SymbolTable_8read_fst[] = "\n    SymbolTable.read_fst(source, input_table)\n\n    Reads symbol table from an FST file without loading the corresponding FST.\n\n    This class method creates a new SymbolTable by reading either the input or\n    output symbol table from an FST file, without loading the corresponding FST.\n\n    Args:\n      source: The string location of the input FST file.\n      input_table: Should the input table be read (True) or the output table\n          (False)?\n\n    Returns:\n      A new SymbolTable instance, or None if none can be read.\n\n    Raises:\n      FstIOError: Read failed.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_11SymbolTable_9read_fst(PyObject *__pyx_v_cls, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyObject *__pyx_v_filename = 0;
+  PyObject *__pyx_v_source = 0;
   bool __pyx_v_input_table;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("read_fst (wrapper)", 0);
   {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_filename,&__pyx_n_s_input_table,0};
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_source,&__pyx_n_s_input_table,0};
     PyObject* values[2] = {0,0};
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
@@ -12340,17 +12351,17 @@ static PyObject *__pyx_pw_9pywrapfst_11SymbolTable_9read_fst(PyObject *__pyx_v_c
       kw_args = PyDict_Size(__pyx_kwds);
       switch (pos_args) {
         case  0:
-        if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_filename)) != 0)) kw_args--;
+        if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_source)) != 0)) kw_args--;
         else goto __pyx_L5_argtuple_error;
         CYTHON_FALLTHROUGH;
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_input_table)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("read_fst", 1, 2, 2, 1); __PYX_ERR(0, 1029, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("read_fst", 1, 2, 2, 1); __PYX_ERR(0, 1023, __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, 1029, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "read_fst") < 0)) __PYX_ERR(0, 1023, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -12358,25 +12369,25 @@ static PyObject *__pyx_pw_9pywrapfst_11SymbolTable_9read_fst(PyObject *__pyx_v_c
       values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
       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, 1029, __pyx_L3_error)
+    __pyx_v_source = values[0];
+    __pyx_v_input_table = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_input_table == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1023, __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, 1029, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("read_fst", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1023, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.SymbolTable.read_fst", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11SymbolTable_8read_fst(((PyTypeObject*)__pyx_v_cls), __pyx_v_filename, __pyx_v_input_table);
+  __pyx_r = __pyx_pf_9pywrapfst_11SymbolTable_8read_fst(((PyTypeObject*)__pyx_v_cls), __pyx_v_source, __pyx_v_input_table);
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_filename, bool __pyx_v_input_table) {
+static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_source, bool __pyx_v_input_table) {
   std::unique_ptr<fst::SymbolTable>  __pyx_v_syms;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
@@ -12389,36 +12400,36 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTyp
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("read_fst", 0);
 
-  /* "pywrapfst.pyx":1052
+  /* "pywrapfst.pyx":1044
  *     """
  *     cdef unique_ptr[fst.SymbolTable] syms
- *     syms.reset(fst.FstReadSymbols(tostring(filename), input_table))             # <<<<<<<<<<<<<<
+ *     syms.reset(fst.FstReadSymbols(tostring(source), input_table))             # <<<<<<<<<<<<<<
  *     if syms.get() == NULL:
- *       raise FstIOError("Read failed: {!r}".format(filename))
+ *       raise FstIOError("Read failed: {!r}".format(source))
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1052, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1044, __pyx_L1_error)
   __pyx_v_syms.reset(fst::FstReadSymbols(__pyx_t_1, __pyx_v_input_table));
 
-  /* "pywrapfst.pyx":1053
+  /* "pywrapfst.pyx":1045
  *     cdef unique_ptr[fst.SymbolTable] syms
- *     syms.reset(fst.FstReadSymbols(tostring(filename), input_table))
+ *     syms.reset(fst.FstReadSymbols(tostring(source), input_table))
  *     if syms.get() == NULL:             # <<<<<<<<<<<<<<
- *       raise FstIOError("Read failed: {!r}".format(filename))
+ *       raise FstIOError("Read failed: {!r}".format(source))
  *     return _init_SymbolTable(syms.release())
  */
   __pyx_t_2 = ((__pyx_v_syms.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":1054
- *     syms.reset(fst.FstReadSymbols(tostring(filename), input_table))
+    /* "pywrapfst.pyx":1046
+ *     syms.reset(fst.FstReadSymbols(tostring(source), input_table))
  *     if syms.get() == NULL:
- *       raise FstIOError("Read failed: {!r}".format(filename))             # <<<<<<<<<<<<<<
+ *       raise FstIOError("Read failed: {!r}".format(source))             # <<<<<<<<<<<<<<
  *     return _init_SymbolTable(syms.release())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1054, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1046, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1054, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1046, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __pyx_t_7 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
@@ -12430,9 +12441,9 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTyp
         __Pyx_DECREF_SET(__pyx_t_6, function);
       }
     }
-    __pyx_t_5 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_v_filename) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_filename);
+    __pyx_t_5 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_source);
     __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1054, __pyx_L1_error)
+    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1046, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __pyx_t_6 = NULL;
@@ -12448,42 +12459,42 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTyp
     __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5);
     __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1054, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1046, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 1054, __pyx_L1_error)
+    __PYX_ERR(0, 1046, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1053
+    /* "pywrapfst.pyx":1045
  *     cdef unique_ptr[fst.SymbolTable] syms
- *     syms.reset(fst.FstReadSymbols(tostring(filename), input_table))
+ *     syms.reset(fst.FstReadSymbols(tostring(source), input_table))
  *     if syms.get() == NULL:             # <<<<<<<<<<<<<<
- *       raise FstIOError("Read failed: {!r}".format(filename))
+ *       raise FstIOError("Read failed: {!r}".format(source))
  *     return _init_SymbolTable(syms.release())
  */
   }
 
-  /* "pywrapfst.pyx":1055
+  /* "pywrapfst.pyx":1047
  *     if syms.get() == NULL:
- *       raise FstIOError("Read failed: {!r}".format(filename))
+ *       raise FstIOError("Read failed: {!r}".format(source))
  *     return _init_SymbolTable(syms.release())             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(__pyx_v_syms.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1055, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(__pyx_v_syms.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1047, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1029
+  /* "pywrapfst.pyx":1023
  * 
  *   @classmethod
- *   def read_fst(cls, filename, bool input_table):             # <<<<<<<<<<<<<<
+ *   def read_fst(cls, source, bool input_table):             # <<<<<<<<<<<<<<
  *     """
- *     SymbolTable.read_fst(filename, input_table)
+ *     SymbolTable.read_fst(source, input_table)
  */
 
   /* function exit code */
@@ -12501,62 +12512,62 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTyp
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1058
+/* "pywrapfst.pyx":1050
  * 
  * 
  * cdef _EncodeMapperSymbolTable _init_EncodeMapperSymbolTable(             # <<<<<<<<<<<<<<
- *     fst.SymbolTable *table, shared_ptr[fst.EncodeMapperClass] encoder):
+ *     fst.SymbolTable *table, shared_ptr[fst.EncodeMapperClass] mapper):
  *   cdef _EncodeMapperSymbolTable result = (
  */
 
-static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst__init_EncodeMapperSymbolTable(fst::SymbolTable *__pyx_v_table, std::shared_ptr<fst::script::EncodeMapperClass>  __pyx_v_encoder) {
+static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst__init_EncodeMapperSymbolTable(fst::SymbolTable *__pyx_v_table, std::shared_ptr<fst::script::EncodeMapperClass>  __pyx_v_mapper) {
   struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_v_result = 0;
   struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("_init_EncodeMapperSymbolTable", 0);
 
-  /* "pywrapfst.pyx":1061
- *     fst.SymbolTable *table, shared_ptr[fst.EncodeMapperClass] encoder):
+  /* "pywrapfst.pyx":1053
+ *     fst.SymbolTable *table, shared_ptr[fst.EncodeMapperClass] mapper):
  *   cdef _EncodeMapperSymbolTable result = (
  *       _EncodeMapperSymbolTable.__new__(_EncodeMapperSymbolTable))             # <<<<<<<<<<<<<<
  *   result._table = table
- *   result._encoder = encoder
+ *   result._mapper = mapper
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst__EncodeMapperSymbolTable(((PyTypeObject *)__pyx_ptype_9pywrapfst__EncodeMapperSymbolTable), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1061, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst__EncodeMapperSymbolTable(((PyTypeObject *)__pyx_ptype_9pywrapfst__EncodeMapperSymbolTable), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1053, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1062
+  /* "pywrapfst.pyx":1054
  *   cdef _EncodeMapperSymbolTable result = (
  *       _EncodeMapperSymbolTable.__new__(_EncodeMapperSymbolTable))
  *   result._table = table             # <<<<<<<<<<<<<<
- *   result._encoder = encoder
+ *   result._mapper = mapper
  *   return result
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 1062, __pyx_L1_error)
+    __PYX_ERR(0, 1054, __pyx_L1_error)
   }
   __pyx_v_result->__pyx_base._table = __pyx_v_table;
 
-  /* "pywrapfst.pyx":1063
+  /* "pywrapfst.pyx":1055
  *       _EncodeMapperSymbolTable.__new__(_EncodeMapperSymbolTable))
  *   result._table = table
- *   result._encoder = encoder             # <<<<<<<<<<<<<<
+ *   result._mapper = mapper             # <<<<<<<<<<<<<<
  *   return result
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_encoder");
-    __PYX_ERR(0, 1063, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
+    __PYX_ERR(0, 1055, __pyx_L1_error)
   }
-  __pyx_v_result->_encoder = __pyx_v_encoder;
+  __pyx_v_result->_mapper = __pyx_v_mapper;
 
-  /* "pywrapfst.pyx":1064
+  /* "pywrapfst.pyx":1056
  *   result._table = table
- *   result._encoder = encoder
+ *   result._mapper = mapper
  *   return result             # <<<<<<<<<<<<<<
  * 
  * 
@@ -12566,11 +12577,11 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1058
+  /* "pywrapfst.pyx":1050
  * 
  * 
  * cdef _EncodeMapperSymbolTable _init_EncodeMapperSymbolTable(             # <<<<<<<<<<<<<<
- *     fst.SymbolTable *table, shared_ptr[fst.EncodeMapperClass] encoder):
+ *     fst.SymbolTable *table, shared_ptr[fst.EncodeMapperClass] mapper):
  *   cdef _EncodeMapperSymbolTable result = (
  */
 
@@ -12586,7 +12597,7 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1067
+/* "pywrapfst.pyx":1059
  * 
  * 
  * cdef _FstSymbolTable _init_FstSymbolTable(fst.SymbolTable *table,             # <<<<<<<<<<<<<<
@@ -12601,19 +12612,19 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst__init_Fst
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("_init_FstSymbolTable", 0);
 
-  /* "pywrapfst.pyx":1069
+  /* "pywrapfst.pyx":1061
  * 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 = ((PyObject *)__pyx_tp_new_9pywrapfst__FstSymbolTable(((PyTypeObject *)__pyx_ptype_9pywrapfst__FstSymbolTable), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1069, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst__FstSymbolTable(((PyTypeObject *)__pyx_ptype_9pywrapfst__FstSymbolTable), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1061, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst__FstSymbolTable *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1070
+  /* "pywrapfst.pyx":1062
  *                                           shared_ptr[fst.FstClass] ifst):
  *   cdef _FstSymbolTable result = _FstSymbolTable.__new__(_FstSymbolTable)
  *   result._table = table             # <<<<<<<<<<<<<<
@@ -12622,11 +12633,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 '%.30s'", "_table");
-    __PYX_ERR(0, 1070, __pyx_L1_error)
+    __PYX_ERR(0, 1062, __pyx_L1_error)
   }
   __pyx_v_result->__pyx_base._table = __pyx_v_table;
 
-  /* "pywrapfst.pyx":1071
+  /* "pywrapfst.pyx":1063
  *   cdef _FstSymbolTable result = _FstSymbolTable.__new__(_FstSymbolTable)
  *   result._table = table
  *   result._fst = ifst             # <<<<<<<<<<<<<<
@@ -12635,11 +12646,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 '%.30s'", "_fst");
-    __PYX_ERR(0, 1071, __pyx_L1_error)
+    __PYX_ERR(0, 1063, __pyx_L1_error)
   }
   __pyx_v_result->_fst = __pyx_v_ifst;
 
-  /* "pywrapfst.pyx":1072
+  /* "pywrapfst.pyx":1064
  *   result._table = table
  *   result._fst = ifst
  *   return result             # <<<<<<<<<<<<<<
@@ -12651,7 +12662,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst__init_Fst
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1067
+  /* "pywrapfst.pyx":1059
  * 
  * 
  * cdef _FstSymbolTable _init_FstSymbolTable(fst.SymbolTable *table,             # <<<<<<<<<<<<<<
@@ -12671,7 +12682,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst__init_Fst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1075
+/* "pywrapfst.pyx":1067
  * 
  * 
  * cdef _MutableFstSymbolTable _init_MutableFstSymbolTable(fst.SymbolTable *table,             # <<<<<<<<<<<<<<
@@ -12686,19 +12697,19 @@ static struct __pyx_obj_9pywrapfst__MutableFstSymbolTable *__pyx_f_9pywrapfst__i
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("_init_MutableFstSymbolTable", 0);
 
-  /* "pywrapfst.pyx":1078
+  /* "pywrapfst.pyx":1070
  *     shared_ptr[fst.MutableFstClass] ifst):
  *   cdef _MutableFstSymbolTable result = (
  *       _MutableFstSymbolTable.__new__(_MutableFstSymbolTable))             # <<<<<<<<<<<<<<
  *   result._table = table
  *   result._mfst = ifst
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst__MutableFstSymbolTable(((PyTypeObject *)__pyx_ptype_9pywrapfst__MutableFstSymbolTable), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1078, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst__MutableFstSymbolTable(((PyTypeObject *)__pyx_ptype_9pywrapfst__MutableFstSymbolTable), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1070, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst__MutableFstSymbolTable *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1079
+  /* "pywrapfst.pyx":1071
  *   cdef _MutableFstSymbolTable result = (
  *       _MutableFstSymbolTable.__new__(_MutableFstSymbolTable))
  *   result._table = table             # <<<<<<<<<<<<<<
@@ -12707,11 +12718,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 '%.30s'", "_table");
-    __PYX_ERR(0, 1079, __pyx_L1_error)
+    __PYX_ERR(0, 1071, __pyx_L1_error)
   }
   __pyx_v_result->__pyx_base.__pyx_base._table = __pyx_v_table;
 
-  /* "pywrapfst.pyx":1080
+  /* "pywrapfst.pyx":1072
  *       _MutableFstSymbolTable.__new__(_MutableFstSymbolTable))
  *   result._table = table
  *   result._mfst = ifst             # <<<<<<<<<<<<<<
@@ -12720,11 +12731,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 '%.30s'", "_mfst");
-    __PYX_ERR(0, 1080, __pyx_L1_error)
+    __PYX_ERR(0, 1072, __pyx_L1_error)
   }
   __pyx_v_result->_mfst = __pyx_v_ifst;
 
-  /* "pywrapfst.pyx":1081
+  /* "pywrapfst.pyx":1073
  *   result._table = table
  *   result._mfst = ifst
  *   return result             # <<<<<<<<<<<<<<
@@ -12736,7 +12747,7 @@ static struct __pyx_obj_9pywrapfst__MutableFstSymbolTable *__pyx_f_9pywrapfst__i
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1075
+  /* "pywrapfst.pyx":1067
  * 
  * 
  * cdef _MutableFstSymbolTable _init_MutableFstSymbolTable(fst.SymbolTable *table,             # <<<<<<<<<<<<<<
@@ -12756,7 +12767,7 @@ static struct __pyx_obj_9pywrapfst__MutableFstSymbolTable *__pyx_f_9pywrapfst__i
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1084
+/* "pywrapfst.pyx":1076
  * 
  * 
  * cdef SymbolTable _init_SymbolTable(fst.SymbolTable *table):             # <<<<<<<<<<<<<<
@@ -12771,19 +12782,19 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__init_SymbolT
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("_init_SymbolTable", 0);
 
-  /* "pywrapfst.pyx":1085
+  /* "pywrapfst.pyx":1077
  * 
  * cdef SymbolTable _init_SymbolTable(fst.SymbolTable *table):
  *   cdef SymbolTable result = SymbolTable.__new__(SymbolTable)             # <<<<<<<<<<<<<<
  *   result._table = table
  *   return result
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_SymbolTable(((PyTypeObject *)__pyx_ptype_9pywrapfst_SymbolTable), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1085, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_SymbolTable(((PyTypeObject *)__pyx_ptype_9pywrapfst_SymbolTable), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1077, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_SymbolTable *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1086
+  /* "pywrapfst.pyx":1078
  * cdef SymbolTable _init_SymbolTable(fst.SymbolTable *table):
  *   cdef SymbolTable result = SymbolTable.__new__(SymbolTable)
  *   result._table = table             # <<<<<<<<<<<<<<
@@ -12792,11 +12803,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 '%.30s'", "_table");
-    __PYX_ERR(0, 1086, __pyx_L1_error)
+    __PYX_ERR(0, 1078, __pyx_L1_error)
   }
   __pyx_v_result->__pyx_base.__pyx_base._table = __pyx_v_table;
 
-  /* "pywrapfst.pyx":1087
+  /* "pywrapfst.pyx":1079
  *   cdef SymbolTable result = SymbolTable.__new__(SymbolTable)
  *   result._table = table
  *   return result             # <<<<<<<<<<<<<<
@@ -12808,7 +12819,7 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__init_SymbolT
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1084
+  /* "pywrapfst.pyx":1076
  * 
  * 
  * cdef SymbolTable _init_SymbolTable(fst.SymbolTable *table):             # <<<<<<<<<<<<<<
@@ -12828,7 +12839,7 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__init_SymbolT
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1090
+/* "pywrapfst.pyx":1082
  * 
  * 
  * cpdef SymbolTable _read_SymbolTable_from_string(state):             # <<<<<<<<<<<<<<
@@ -12849,17 +12860,17 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__read_SymbolT
   PyObject *__pyx_t_5 = NULL;
   __Pyx_RefNannySetupContext("_read_SymbolTable_from_string", 0);
 
-  /* "pywrapfst.pyx":1092
+  /* "pywrapfst.pyx":1084
  * cpdef SymbolTable _read_SymbolTable_from_string(state):
  *   cdef stringstream sstrm
  *   sstrm << tostring(state)             # <<<<<<<<<<<<<<
  *   cdef unique_ptr[fst.SymbolTable] syms
  *   syms.reset(fst.SymbolTable.ReadStream(sstrm, b"<pywrapfst>"))
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1092, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1084, __pyx_L1_error)
   (void)((__pyx_v_sstrm << __pyx_t_1));
 
-  /* "pywrapfst.pyx":1094
+  /* "pywrapfst.pyx":1086
  *   sstrm << tostring(state)
  *   cdef unique_ptr[fst.SymbolTable] syms
  *   syms.reset(fst.SymbolTable.ReadStream(sstrm, b"<pywrapfst>"))             # <<<<<<<<<<<<<<
@@ -12868,7 +12879,7 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__read_SymbolT
  */
   __pyx_v_syms.reset(fst::SymbolTable::Read(__pyx_v_sstrm, __pyx_k_pywrapfst));
 
-  /* "pywrapfst.pyx":1095
+  /* "pywrapfst.pyx":1087
  *   cdef unique_ptr[fst.SymbolTable] syms
  *   syms.reset(fst.SymbolTable.ReadStream(sstrm, b"<pywrapfst>"))
  *   if syms.get() == NULL:             # <<<<<<<<<<<<<<
@@ -12878,14 +12889,14 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__read_SymbolT
   __pyx_t_2 = ((__pyx_v_syms.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":1096
+    /* "pywrapfst.pyx":1088
  *   syms.reset(fst.SymbolTable.ReadStream(sstrm, b"<pywrapfst>"))
  *   if syms.get() == NULL:
  *     raise FstIOError("Read failed")             # <<<<<<<<<<<<<<
  *   return _init_SymbolTable(syms.release())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1096, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1088, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __pyx_t_5 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
@@ -12899,14 +12910,14 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__read_SymbolT
     }
     __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_kp_u_Read_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_kp_u_Read_failed);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1096, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1088, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 1096, __pyx_L1_error)
+    __PYX_ERR(0, 1088, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1095
+    /* "pywrapfst.pyx":1087
  *   cdef unique_ptr[fst.SymbolTable] syms
  *   syms.reset(fst.SymbolTable.ReadStream(sstrm, b"<pywrapfst>"))
  *   if syms.get() == NULL:             # <<<<<<<<<<<<<<
@@ -12915,7 +12926,7 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__read_SymbolT
  */
   }
 
-  /* "pywrapfst.pyx":1097
+  /* "pywrapfst.pyx":1089
  *   if syms.get() == NULL:
  *     raise FstIOError("Read failed")
  *   return _init_SymbolTable(syms.release())             # <<<<<<<<<<<<<<
@@ -12923,13 +12934,13 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__read_SymbolT
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(__pyx_v_syms.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1097, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(__pyx_v_syms.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1089, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_SymbolTable *)__pyx_t_3);
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1090
+  /* "pywrapfst.pyx":1082
  * 
  * 
  * cpdef SymbolTable _read_SymbolTable_from_string(state):             # <<<<<<<<<<<<<<
@@ -12969,7 +12980,7 @@ static PyObject *__pyx_pf_9pywrapfst_8_read_SymbolTable_from_string(CYTHON_UNUSE
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("_read_SymbolTable_from_string", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_SymbolTable_from_string(__pyx_v_state, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1090, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_SymbolTable_from_string(__pyx_v_state, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1082, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -12986,7 +12997,7 @@ static PyObject *__pyx_pf_9pywrapfst_8_read_SymbolTable_from_string(CYTHON_UNUSE
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1103
+/* "pywrapfst.pyx":1095
  * 
  * 
  * cpdef SymbolTable compact_symbol_table(_SymbolTable syms):             # <<<<<<<<<<<<<<
@@ -13001,7 +13012,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":1115
+  /* "pywrapfst.pyx":1107
  *     A new compacted SymbolTable.
  *   """
  *   return _init_SymbolTable(fst.CompactSymbolTable(deref(syms._table)))             # <<<<<<<<<<<<<<
@@ -13011,15 +13022,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 '%.30s'", "_table");
-    __PYX_ERR(0, 1115, __pyx_L1_error)
+    __PYX_ERR(0, 1107, __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, 1115, __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, 1107, __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":1103
+  /* "pywrapfst.pyx":1095
  * 
  * 
  * cpdef SymbolTable compact_symbol_table(_SymbolTable syms):             # <<<<<<<<<<<<<<
@@ -13045,7 +13056,7 @@ static PyObject *__pyx_pw_9pywrapfst_11compact_symbol_table(PyObject *__pyx_self
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("compact_symbol_table (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_syms), __pyx_ptype_9pywrapfst__SymbolTable, 1, "syms", 0))) __PYX_ERR(0, 1103, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_syms), __pyx_ptype_9pywrapfst__SymbolTable, 1, "syms", 0))) __PYX_ERR(0, 1095, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_10compact_symbol_table(__pyx_self, ((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_syms));
 
   /* function exit code */
@@ -13063,7 +13074,7 @@ static PyObject *__pyx_pf_9pywrapfst_10compact_symbol_table(CYTHON_UNUSED PyObje
   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, 1103, __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, 1095, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -13080,7 +13091,7 @@ static PyObject *__pyx_pf_9pywrapfst_10compact_symbol_table(CYTHON_UNUSED PyObje
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1118
+/* "pywrapfst.pyx":1110
  * 
  * 
  * cpdef SymbolTable merge_symbol_table(_SymbolTable lhs, _SymbolTable rhs):             # <<<<<<<<<<<<<<
@@ -13095,8 +13106,8 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_merge_symbol_
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("merge_symbol_table", 0);
 
-  /* "pywrapfst.pyx":1142
- *   See also: `relabel_symbols`.
+  /* "pywrapfst.pyx":1132
+ *     A new merged SymbolTable.
  *   """
  *   return _init_SymbolTable(fst.MergeSymbolTable(deref(lhs._table),             # <<<<<<<<<<<<<<
  *                                                 deref(rhs._table), NULL))
@@ -13105,10 +13116,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 '%.30s'", "_table");
-    __PYX_ERR(0, 1142, __pyx_L1_error)
+    __PYX_ERR(0, 1132, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1143
+  /* "pywrapfst.pyx":1133
  *   """
  *   return _init_SymbolTable(fst.MergeSymbolTable(deref(lhs._table),
  *                                                 deref(rhs._table), NULL))             # <<<<<<<<<<<<<<
@@ -13117,23 +13128,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 '%.30s'", "_table");
-    __PYX_ERR(0, 1143, __pyx_L1_error)
+    __PYX_ERR(0, 1133, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1142
- *   See also: `relabel_symbols`.
+  /* "pywrapfst.pyx":1132
+ *     A new merged SymbolTable.
  *   """
  *   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, 1142, __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, 1132, __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":1118
+  /* "pywrapfst.pyx":1110
  * 
  * 
  * cpdef SymbolTable merge_symbol_table(_SymbolTable lhs, _SymbolTable rhs):             # <<<<<<<<<<<<<<
@@ -13154,7 +13165,7 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_merge_symbol_
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_13merge_symbol_table(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_12merge_symbol_table[] = "\n  merge_symbol_table(lhs, rhs)\n\n  Merges all symbols from the left table into the right.\n\n  This function creates a new SymbolTable which is the merger of the two input\n  symbol Tables. Symbols in the right-hand table that conflict with those in the\n  left-hand table will be assigned values from the left-hand table. Thus the\n  returned table will never modify symbol assignments from the left-hand side,\n  but may do so on the right.\n\n  If the left-hand table is associated with an FST, it may be necessary to\n  relabel it using the output table.\n\n  Args:\n    lhs: Left-hand side SymbolTable.\n    rhs: Left-hand side SymbolTable.\n\n  Returns:\n    A new merged SymbolTable.\n\n  See also: `relabel_symbols`.\n  ";
+static char __pyx_doc_9pywrapfst_12merge_symbol_table[] = "\n  merge_symbol_table(lhs, rhs)\n\n  Merges all symbols from the left table into the right.\n\n  This function creates a new SymbolTable which is the merger of the two input\n  symbol Tables. Symbols in the right-hand table that conflict with those in the\n  left-hand table will be assigned values from the left-hand table. Thus the\n  returned table will never modify symbol assignments from the left-hand side,\n  but may do so on the right.\n\n  If the left-hand table is associated with an FST, it may be necessary to\n  relabel it using the output table.\n\n  Args:\n    lhs: Left-hand side SymbolTable.\n    rhs: Left-hand side SymbolTable.\n\n  Returns:\n    A new merged SymbolTable.\n  ";
 static PyObject *__pyx_pw_9pywrapfst_13merge_symbol_table(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_lhs = 0;
   struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_rhs = 0;
@@ -13184,11 +13195,11 @@ static PyObject *__pyx_pw_9pywrapfst_13merge_symbol_table(PyObject *__pyx_self,
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_rhs)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("merge_symbol_table", 1, 2, 2, 1); __PYX_ERR(0, 1118, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("merge_symbol_table", 1, 2, 2, 1); __PYX_ERR(0, 1110, __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, 1118, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "merge_symbol_table") < 0)) __PYX_ERR(0, 1110, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -13201,14 +13212,14 @@ static PyObject *__pyx_pw_9pywrapfst_13merge_symbol_table(PyObject *__pyx_self,
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("merge_symbol_table", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1118, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("merge_symbol_table", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1110, __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, 1118, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rhs), __pyx_ptype_9pywrapfst__SymbolTable, 1, "rhs", 0))) __PYX_ERR(0, 1118, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lhs), __pyx_ptype_9pywrapfst__SymbolTable, 1, "lhs", 0))) __PYX_ERR(0, 1110, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rhs), __pyx_ptype_9pywrapfst__SymbolTable, 1, "rhs", 0))) __PYX_ERR(0, 1110, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_12merge_symbol_table(__pyx_self, __pyx_v_lhs, __pyx_v_rhs);
 
   /* function exit code */
@@ -13226,7 +13237,7 @@ static PyObject *__pyx_pf_9pywrapfst_12merge_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, 1118, __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, 1110, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -13243,7 +13254,7 @@ static PyObject *__pyx_pf_9pywrapfst_12merge_symbol_table(CYTHON_UNUSED PyObject
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1157
+/* "pywrapfst.pyx":1147
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -13273,7 +13284,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator___repr__(struct __pyx
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":1158
+  /* "pywrapfst.pyx":1148
  * 
  *   def __repr__(self):
  *     return "<SymbolTableIterator at 0x{:x}>".format(id(self))             # <<<<<<<<<<<<<<
@@ -13281,9 +13292,9 @@ 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_u_SymbolTableIterator_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1158, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_SymbolTableIterator_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1148, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1158, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1148, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_t_4 = NULL;
   if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
@@ -13298,14 +13309,14 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator___repr__(struct __pyx
   __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1158, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1148, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1157
+  /* "pywrapfst.pyx":1147
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -13327,7 +13338,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator___repr__(struct __pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1160
+/* "pywrapfst.pyx":1150
  *     return "<SymbolTableIterator at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
@@ -13361,7 +13372,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, 1160, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 1150, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
       goto __pyx_L5_argtuple_error;
@@ -13372,13 +13383,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, 1160, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1150, __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, 1160, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_syms), __pyx_ptype_9pywrapfst__SymbolTable, 1, "syms", 0))) __PYX_ERR(0, 1150, __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 */
@@ -13395,7 +13406,7 @@ static int __pyx_pf_9pywrapfst_19SymbolTableIterator_2__init__(struct __pyx_obj_
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":1161
+  /* "pywrapfst.pyx":1151
  * 
  *   def __init__(self, _SymbolTable syms):
  *     self._siter.reset(new fst.SymbolTableIterator(deref(syms._table)))             # <<<<<<<<<<<<<<
@@ -13404,15 +13415,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 '%.30s'", "_siter");
-    __PYX_ERR(0, 1161, __pyx_L1_error)
+    __PYX_ERR(0, 1151, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_syms) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 1161, __pyx_L1_error)
+    __PYX_ERR(0, 1151, __pyx_L1_error)
   }
   __pyx_v_self->_siter.reset(new fst::SymbolTableIterator((*__pyx_v_syms->_table)));
 
-  /* "pywrapfst.pyx":1160
+  /* "pywrapfst.pyx":1150
  *     return "<SymbolTableIterator at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
@@ -13431,7 +13442,7 @@ static int __pyx_pf_9pywrapfst_19SymbolTableIterator_2__init__(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1164
+/* "pywrapfst.pyx":1154
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -13457,7 +13468,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_4__iter__(struct __py
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__iter__", 0);
 
-  /* "pywrapfst.pyx":1165
+  /* "pywrapfst.pyx":1155
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):
  *     return self             # <<<<<<<<<<<<<<
@@ -13469,7 +13480,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_4__iter__(struct __py
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1164
+  /* "pywrapfst.pyx":1154
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -13484,7 +13495,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_4__iter__(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1168
+/* "pywrapfst.pyx":1158
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -13516,7 +13527,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_6__next__(struct __py
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("__next__", 0);
 
-  /* "pywrapfst.pyx":1169
+  /* "pywrapfst.pyx":1159
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -13525,12 +13536,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 '%.30s'", "done");
-    __PYX_ERR(0, 1169, __pyx_L1_error)
+    __PYX_ERR(0, 1159, __pyx_L1_error)
   }
   __pyx_t_1 = (((struct __pyx_vtabstruct_9pywrapfst_SymbolTableIterator *)__pyx_v_self->__pyx_vtab)->done(__pyx_v_self, 0) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":1170
+    /* "pywrapfst.pyx":1160
  *   def __next__(self):
  *     if self.done():
  *       raise StopIteration             # <<<<<<<<<<<<<<
@@ -13538,9 +13549,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, 1170, __pyx_L1_error)
+    __PYX_ERR(0, 1160, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1169
+    /* "pywrapfst.pyx":1159
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -13549,7 +13560,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_6__next__(struct __py
  */
   }
 
-  /* "pywrapfst.pyx":1171
+  /* "pywrapfst.pyx":1161
  *     if self.done():
  *       raise StopIteration
  *     cdef int64 value = self.value()             # <<<<<<<<<<<<<<
@@ -13558,11 +13569,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 '%.30s'", "value");
-    __PYX_ERR(0, 1171, __pyx_L1_error)
+    __PYX_ERR(0, 1161, __pyx_L1_error)
   }
   __pyx_v_value = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableIterator *)__pyx_v_self->__pyx_vtab)->value(__pyx_v_self, 0);
 
-  /* "pywrapfst.pyx":1172
+  /* "pywrapfst.pyx":1162
  *       raise StopIteration
  *     cdef int64 value = self.value()
  *     cdef string symbol = self.symbol()             # <<<<<<<<<<<<<<
@@ -13571,11 +13582,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 '%.30s'", "symbol");
-    __PYX_ERR(0, 1172, __pyx_L1_error)
+    __PYX_ERR(0, 1162, __pyx_L1_error)
   }
   __pyx_v_symbol = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableIterator *)__pyx_v_self->__pyx_vtab)->symbol(__pyx_v_self, 0);
 
-  /* "pywrapfst.pyx":1173
+  /* "pywrapfst.pyx":1163
  *     cdef int64 value = self.value()
  *     cdef string symbol = self.symbol()
  *     self.next()             # <<<<<<<<<<<<<<
@@ -13584,11 +13595,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 '%.30s'", "next");
-    __PYX_ERR(0, 1173, __pyx_L1_error)
+    __PYX_ERR(0, 1163, __pyx_L1_error)
   }
   ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableIterator *)__pyx_v_self->__pyx_vtab)->next(__pyx_v_self, 0);
 
-  /* "pywrapfst.pyx":1174
+  /* "pywrapfst.pyx":1164
  *     cdef string symbol = self.symbol()
  *     self.next()
  *     return (value, symbol)             # <<<<<<<<<<<<<<
@@ -13596,11 +13607,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, 1174, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_v_value); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1164, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_symbol); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1174, __pyx_L1_error)
+  __pyx_t_3 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_symbol); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1164, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1174, __pyx_L1_error)
+  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1164, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_GIVEREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
@@ -13612,7 +13623,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_6__next__(struct __py
   __pyx_t_4 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1168
+  /* "pywrapfst.pyx":1158
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -13633,7 +13644,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_6__next__(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1176
+/* "pywrapfst.pyx":1166
  *     return (value, symbol)
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -13660,7 +13671,7 @@ static bool __pyx_f_9pywrapfst_19SymbolTableIterator_done(struct __pyx_obj_9pywr
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_done); 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_done); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1166, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_19SymbolTableIterator_9done)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -13676,10 +13687,10 @@ static bool __pyx_f_9pywrapfst_19SymbolTableIterator_done(struct __pyx_obj_9pywr
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1176, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1166, __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, 1176, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1166, __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;
@@ -13698,7 +13709,7 @@ static bool __pyx_f_9pywrapfst_19SymbolTableIterator_done(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":1185
+  /* "pywrapfst.pyx":1175
  *       True if the iterator is exhausted, False otherwise.
  *     """
  *     return self._siter.get().Done()             # <<<<<<<<<<<<<<
@@ -13707,12 +13718,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 '%.30s'", "_siter");
-    __PYX_ERR(0, 1185, __pyx_L1_error)
+    __PYX_ERR(0, 1175, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_siter.get()->Done();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1176
+  /* "pywrapfst.pyx":1166
  *     return (value, symbol)
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -13753,7 +13764,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, 1176, __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, 1166, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -13770,7 +13781,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_8done(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1187
+/* "pywrapfst.pyx":1177
  *     return self._siter.get().Done()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -13795,7 +13806,7 @@ static void __pyx_f_9pywrapfst_19SymbolTableIterator_next(struct __pyx_obj_9pywr
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_next); 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_next); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1177, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_19SymbolTableIterator_11next)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -13811,7 +13822,7 @@ static void __pyx_f_9pywrapfst_19SymbolTableIterator_next(struct __pyx_obj_9pywr
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1187, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1177, __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;
@@ -13831,7 +13842,7 @@ static void __pyx_f_9pywrapfst_19SymbolTableIterator_next(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":1193
+  /* "pywrapfst.pyx":1183
  *     Advances the iterator.
  *     """
  *     self._siter.get().Next()             # <<<<<<<<<<<<<<
@@ -13840,11 +13851,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 '%.30s'", "_siter");
-    __PYX_ERR(0, 1193, __pyx_L1_error)
+    __PYX_ERR(0, 1183, __pyx_L1_error)
   }
   __pyx_v_self->_siter.get()->Next();
 
-  /* "pywrapfst.pyx":1187
+  /* "pywrapfst.pyx":1177
  *     return self._siter.get().Done()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -13884,7 +13895,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, 1187, __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, 1177, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -13901,7 +13912,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_10next(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1195
+/* "pywrapfst.pyx":1185
  *     self._siter.get().Next()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -13926,7 +13937,7 @@ static void __pyx_f_9pywrapfst_19SymbolTableIterator_reset(struct __pyx_obj_9pyw
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_reset); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1195, __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, 1185, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_19SymbolTableIterator_13reset)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -13942,7 +13953,7 @@ static void __pyx_f_9pywrapfst_19SymbolTableIterator_reset(struct __pyx_obj_9pyw
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1195, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1185, __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;
@@ -13962,7 +13973,7 @@ static void __pyx_f_9pywrapfst_19SymbolTableIterator_reset(struct __pyx_obj_9pyw
     #endif
   }
 
-  /* "pywrapfst.pyx":1201
+  /* "pywrapfst.pyx":1191
  *     Resets the iterator to the initial position.
  *     """
  *     self._siter.get().Reset()             # <<<<<<<<<<<<<<
@@ -13971,11 +13982,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 '%.30s'", "_siter");
-    __PYX_ERR(0, 1201, __pyx_L1_error)
+    __PYX_ERR(0, 1191, __pyx_L1_error)
   }
   __pyx_v_self->_siter.get()->Reset();
 
-  /* "pywrapfst.pyx":1195
+  /* "pywrapfst.pyx":1185
  *     self._siter.get().Next()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -14015,7 +14026,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, 1195, __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, 1185, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -14032,7 +14043,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_12reset(struct __pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1203
+/* "pywrapfst.pyx":1193
  *     self._siter.get().Reset()
  * 
  *   cpdef string symbol(self):             # <<<<<<<<<<<<<<
@@ -14059,7 +14070,7 @@ static std::string __pyx_f_9pywrapfst_19SymbolTableIterator_symbol(struct __pyx_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_symbol); 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_symbol); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1193, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_19SymbolTableIterator_15symbol)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -14075,10 +14086,10 @@ static std::string __pyx_f_9pywrapfst_19SymbolTableIterator_symbol(struct __pyx_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1203, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1193, __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, 1203, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1193, __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;
@@ -14097,7 +14108,7 @@ static std::string __pyx_f_9pywrapfst_19SymbolTableIterator_symbol(struct __pyx_
     #endif
   }
 
-  /* "pywrapfst.pyx":1214
+  /* "pywrapfst.pyx":1204
  *       A symbol string.
  *     """
  *     return self._siter.get().Symbol()             # <<<<<<<<<<<<<<
@@ -14106,12 +14117,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 '%.30s'", "_siter");
-    __PYX_ERR(0, 1214, __pyx_L1_error)
+    __PYX_ERR(0, 1204, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_siter.get()->Symbol();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1203
+  /* "pywrapfst.pyx":1193
  *     self._siter.get().Reset()
  * 
  *   cpdef string symbol(self):             # <<<<<<<<<<<<<<
@@ -14152,7 +14163,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_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_19SymbolTableIterator_symbol(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1203, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_19SymbolTableIterator_symbol(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1193, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -14169,7 +14180,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_14symbol(struct __pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1216
+/* "pywrapfst.pyx":1206
  *     return self._siter.get().Symbol()
  * 
  *   cpdef int64 value(self):             # <<<<<<<<<<<<<<
@@ -14196,7 +14207,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19SymbolTableIterator_value
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1216, __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, 1206, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_19SymbolTableIterator_17value)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -14212,10 +14223,10 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19SymbolTableIterator_value
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1216, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1206, __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, 1216, __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, 1206, __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;
@@ -14234,7 +14245,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19SymbolTableIterator_value
     #endif
   }
 
-  /* "pywrapfst.pyx":1225
+  /* "pywrapfst.pyx":1215
  *       An integer index.
  *     """
  *     return self._siter.get().Value()             # <<<<<<<<<<<<<<
@@ -14243,12 +14254,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 '%.30s'", "_siter");
-    __PYX_ERR(0, 1225, __pyx_L1_error)
+    __PYX_ERR(0, 1215, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_siter.get()->Value();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1216
+  /* "pywrapfst.pyx":1206
  *     return self._siter.get().Symbol()
  * 
  *   cpdef int64 value(self):             # <<<<<<<<<<<<<<
@@ -14289,7 +14300,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, 1216, __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, 1206, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -14413,7 +14424,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_20__setstate_cython__
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1254
+/* "pywrapfst.pyx":1244
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -14443,7 +14454,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper___repr__(struct __pyx_obj_9p
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":1255
+  /* "pywrapfst.pyx":1245
  * 
  *   def __repr__(self):
  *     return "<EncodeMapper at 0x{:x}>".format(id(self))             # <<<<<<<<<<<<<<
@@ -14451,9 +14462,9 @@ 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_u_EncodeMapper_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1255, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_EncodeMapper_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1245, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1255, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1245, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_t_4 = NULL;
   if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
@@ -14468,14 +14479,14 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper___repr__(struct __pyx_obj_9p
   __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1255, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1245, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1254
+  /* "pywrapfst.pyx":1244
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -14497,7 +14508,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper___repr__(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1257
+/* "pywrapfst.pyx":1247
  *     return "<EncodeMapper at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self,             # <<<<<<<<<<<<<<
@@ -14552,7 +14563,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, 1257, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 1247, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -14568,35 +14579,35 @@ 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, 1259, __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, 1249, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1259
+      /* "pywrapfst.pyx":1249
  *   def __init__(self,
  *                arc_type=b"standard",
  *                bool encode_labels=False,             # <<<<<<<<<<<<<<
  *                bool encode_weights=False):
- *     cdef uint32 flags = fst.GetEncodeFlags(encode_labels, encode_weights)
+ *     cdef uint8 flags = fst.GetEncodeFlags(encode_labels, encode_weights)
  */
       __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, 1260, __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, 1250, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1260
+      /* "pywrapfst.pyx":1250
  *                arc_type=b"standard",
  *                bool encode_labels=False,
  *                bool encode_weights=False):             # <<<<<<<<<<<<<<
- *     cdef uint32 flags = fst.GetEncodeFlags(encode_labels, encode_weights)
- *     self._encoder.reset(new fst.EncodeMapperClass(tostring(arc_type), flags,
+ *     cdef uint8 flags = fst.GetEncodeFlags(encode_labels, encode_weights)
+ *     self._mapper.reset(new fst.EncodeMapperClass(tostring(arc_type), flags,
  */
       __pyx_v_encode_weights = ((bool)0);
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1257, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1247, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.EncodeMapper.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -14604,7 +14615,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":1257
+  /* "pywrapfst.pyx":1247
  *     return "<EncodeMapper at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self,             # <<<<<<<<<<<<<<
@@ -14618,7 +14629,7 @@ static int __pyx_pw_9pywrapfst_12EncodeMapper_3__init__(PyObject *__pyx_v_self,
 }
 
 static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, PyObject *__pyx_v_arc_type, bool __pyx_v_encode_labels, bool __pyx_v_encode_weights) {
-  __pyx_t_10basictypes_uint32 __pyx_v_flags;
+  __pyx_t_10basictypes_uint8 __pyx_v_flags;
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
@@ -14630,61 +14641,61 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":1261
+  /* "pywrapfst.pyx":1251
  *                bool encode_labels=False,
  *                bool encode_weights=False):
- *     cdef uint32 flags = fst.GetEncodeFlags(encode_labels, encode_weights)             # <<<<<<<<<<<<<<
- *     self._encoder.reset(new fst.EncodeMapperClass(tostring(arc_type), flags,
+ *     cdef uint8 flags = fst.GetEncodeFlags(encode_labels, encode_weights)             # <<<<<<<<<<<<<<
+ *     self._mapper.reset(new fst.EncodeMapperClass(tostring(arc_type), flags,
  *                                                   fst.ENCODE))
  */
   __pyx_v_flags = fst::script::GetEncodeFlags(__pyx_v_encode_labels, __pyx_v_encode_weights);
 
-  /* "pywrapfst.pyx":1262
+  /* "pywrapfst.pyx":1252
  *                bool encode_weights=False):
- *     cdef uint32 flags = fst.GetEncodeFlags(encode_labels, encode_weights)
- *     self._encoder.reset(new fst.EncodeMapperClass(tostring(arc_type), flags,             # <<<<<<<<<<<<<<
+ *     cdef uint8 flags = fst.GetEncodeFlags(encode_labels, encode_weights)
+ *     self._mapper.reset(new fst.EncodeMapperClass(tostring(arc_type), flags,             # <<<<<<<<<<<<<<
  *                                                   fst.ENCODE))
- *     if not self._encoder:
+ *     if not self._mapper:
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_encoder");
-    __PYX_ERR(0, 1262, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
+    __PYX_ERR(0, 1252, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1262, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1252, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1263
- *     cdef uint32 flags = fst.GetEncodeFlags(encode_labels, encode_weights)
- *     self._encoder.reset(new fst.EncodeMapperClass(tostring(arc_type), flags,
+  /* "pywrapfst.pyx":1253
+ *     cdef uint8 flags = fst.GetEncodeFlags(encode_labels, encode_weights)
+ *     self._mapper.reset(new fst.EncodeMapperClass(tostring(arc_type), flags,
  *                                                   fst.ENCODE))             # <<<<<<<<<<<<<<
- *     if not self._encoder:
+ *     if not self._mapper:
  *       raise FstOpError("Unknown arc type: {!r}".format(arc_type))
  */
-  __pyx_v_self->_encoder.reset(new fst::script::EncodeMapperClass(__pyx_t_1, __pyx_v_flags, fst::ENCODE));
+  __pyx_v_self->_mapper.reset(new fst::script::EncodeMapperClass(__pyx_t_1, __pyx_v_flags, fst::ENCODE));
 
-  /* "pywrapfst.pyx":1264
- *     self._encoder.reset(new fst.EncodeMapperClass(tostring(arc_type), flags,
+  /* "pywrapfst.pyx":1254
+ *     self._mapper.reset(new fst.EncodeMapperClass(tostring(arc_type), flags,
  *                                                   fst.ENCODE))
- *     if not self._encoder:             # <<<<<<<<<<<<<<
+ *     if not self._mapper:             # <<<<<<<<<<<<<<
  *       raise FstOpError("Unknown arc type: {!r}".format(arc_type))
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_encoder");
-    __PYX_ERR(0, 1264, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
+    __PYX_ERR(0, 1254, __pyx_L1_error)
   }
-  __pyx_t_2 = ((!__pyx_v_self->_encoder) != 0);
+  __pyx_t_2 = ((!__pyx_v_self->_mapper) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":1265
+    /* "pywrapfst.pyx":1255
  *                                                   fst.ENCODE))
- *     if not self._encoder:
+ *     if not self._mapper:
  *       raise FstOpError("Unknown arc type: {!r}".format(arc_type))             # <<<<<<<<<<<<<<
  * 
- *   cpdef string arc_type(self):
+ *   # Python's equivalent to operator().
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1265, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1255, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Unknown_arc_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1265, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Unknown_arc_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1255, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __pyx_t_7 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
@@ -14698,7 +14709,7 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
     }
     __pyx_t_5 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_v_arc_type) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_arc_type);
     __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1265, __pyx_L1_error)
+    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1255, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __pyx_t_6 = NULL;
@@ -14714,23 +14725,23 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
     __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5);
     __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1265, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1255, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 1265, __pyx_L1_error)
+    __PYX_ERR(0, 1255, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1264
- *     self._encoder.reset(new fst.EncodeMapperClass(tostring(arc_type), flags,
+    /* "pywrapfst.pyx":1254
+ *     self._mapper.reset(new fst.EncodeMapperClass(tostring(arc_type), flags,
  *                                                   fst.ENCODE))
- *     if not self._encoder:             # <<<<<<<<<<<<<<
+ *     if not self._mapper:             # <<<<<<<<<<<<<<
  *       raise FstOpError("Unknown arc type: {!r}".format(arc_type))
  * 
  */
   }
 
-  /* "pywrapfst.pyx":1257
+  /* "pywrapfst.pyx":1247
  *     return "<EncodeMapper at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self,             # <<<<<<<<<<<<<<
@@ -14754,144 +14765,7 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1267
- *       raise FstOpError("Unknown arc type: {!r}".format(arc_type))
- * 
- *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
- *     """
- *     arc_type(self)
- */
-
-static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_5arc_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static std::string __pyx_f_9pywrapfst_12EncodeMapper_arc_type(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, int __pyx_skip_dispatch) {
-  std::string __pyx_r;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  std::string __pyx_t_5;
-  __Pyx_RefNannySetupContext("arc_type", 0);
-  /* Check if called by wrapper */
-  if (unlikely(__pyx_skip_dispatch)) ;
-  /* Check if overridden in Python */
-  else if (unlikely((Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0) || (Py_TYPE(((PyObject *)__pyx_v_self))->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)))) {
-    #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
-    static PY_UINT64_T __pyx_tp_dict_version = __PYX_DICT_VERSION_INIT, __pyx_obj_dict_version = __PYX_DICT_VERSION_INIT;
-    if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
-      PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
-      #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1267, __pyx_L1_error)
-      __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_5arc_type)) {
-        __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);
-          }
-        }
-        __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
-        __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1267, __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, 1267, __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;
-        goto __pyx_L0;
-      }
-      #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
-      __pyx_tp_dict_version = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
-      __pyx_obj_dict_version = __Pyx_get_object_dict_version(((PyObject *)__pyx_v_self));
-      if (unlikely(__pyx_type_dict_guard != __pyx_tp_dict_version)) {
-        __pyx_tp_dict_version = __pyx_obj_dict_version = __PYX_DICT_VERSION_INIT;
-      }
-      #endif
-      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
-    }
-    #endif
-  }
-
-  /* "pywrapfst.pyx":1273
- *     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 '%.30s'", "_encoder");
-    __PYX_ERR(0, 1273, __pyx_L1_error)
-  }
-  __pyx_r = __pyx_v_self->_encoder.get()->ArcType();
-  goto __pyx_L0;
-
-  /* "pywrapfst.pyx":1267
- *       raise FstOpError("Unknown arc type: {!r}".format(arc_type))
- * 
- *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
- *     """
- *     arc_type(self)
- */
-
-  /* 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_WriteUnraisable("pywrapfst.EncodeMapper.arc_type", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
-  __Pyx_pretend_to_initialize(&__pyx_r);
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* 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
-  __Pyx_RefNannySetupContext("arc_type (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_4arc_type(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self));
-
-  /* function exit code */
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_4arc_type(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  __Pyx_RefNannySetupContext("arc_type", 0);
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_12EncodeMapper_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1267, __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.EncodeMapper.arc_type", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "pywrapfst.pyx":1277
+/* "pywrapfst.pyx":1259
  *   # Python's equivalent to operator().
  * 
  *   def __call__(self, Arc arc):             # <<<<<<<<<<<<<<
@@ -14900,12 +14774,12 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_4arc_type(struct __pyx_obj_9
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_7__call__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_12EncodeMapper_6__call__[] = "\n    self(state, ilabel, olabel, weight, nextstate)\n\n    Uses the encoder to encode an arc.\n\n    Args:\n      ilabel: The integer index of the input label.\n      olabel: The integer index of the output label.\n      weight: A Weight or weight string indicating the desired final weight; if\n        null, it is set to semiring One.\n      nextstate: The integer index of the destination state.\n\n    Raises:\n      FstOpError: Incompatible or invalid weight.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_5__call__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_12EncodeMapper_4__call__[] = "\n    self(state, ilabel, olabel, weight, nextstate)\n\n    Uses the mapper to encode an arc.\n\n    Args:\n      ilabel: The integer index of the input label.\n      olabel: The integer index of the output label.\n      weight: A Weight or weight string indicating the desired final weight; if\n        null, it is set to semiring One.\n      nextstate: The integer index of the destination state.\n\n    Raises:\n      FstOpError: Incompatible or invalid weight.\n    ";
 #if CYTHON_COMPILING_IN_CPYTHON
-struct wrapperbase __pyx_wrapperbase_9pywrapfst_12EncodeMapper_6__call__;
+struct wrapperbase __pyx_wrapperbase_9pywrapfst_12EncodeMapper_4__call__;
 #endif
-static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_7__call__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_5__call__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -14929,7 +14803,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, 1277, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__call__") < 0)) __PYX_ERR(0, 1259, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
       goto __pyx_L5_argtuple_error;
@@ -14940,14 +14814,14 @@ 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, 1277, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__call__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1259, __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, 1277, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_6__call__(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self), __pyx_v_arc);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_arc), __pyx_ptype_9pywrapfst_Arc, 1, "arc", 0))) __PYX_ERR(0, 1259, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_4__call__(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self), __pyx_v_arc);
 
   /* function exit code */
   goto __pyx_L0;
@@ -14958,35 +14832,35 @@ static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_7__call__(PyObject *__pyx_v_
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_6__call__(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc) {
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_4__call__(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("__call__", 0);
 
-  /* "pywrapfst.pyx":1293
+  /* "pywrapfst.pyx":1275
  *       FstOpError: Incompatible or invalid weight.
  *     """
- *     return _init_Arc(self._encoder.get().__call__(deref(arc._arc)))             # <<<<<<<<<<<<<<
+ *     return _init_Arc(self._mapper.get().__call__(deref(arc._arc)))             # <<<<<<<<<<<<<<
  * 
- *   cpdef uint32 flags(self):
+ *   # Registers the class for pickling.
  */
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_encoder");
-    __PYX_ERR(0, 1293, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
+    __PYX_ERR(0, 1275, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_arc) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 1293, __pyx_L1_error)
+    __PYX_ERR(0, 1275, __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, 1293, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_Arc(__pyx_v_self->_mapper.get()->operator()((*__pyx_v_arc->_arc)))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1275, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1277
+  /* "pywrapfst.pyx":1259
  *   # Python's equivalent to operator().
  * 
  *   def __call__(self, Arc arc):             # <<<<<<<<<<<<<<
@@ -15005,24 +14879,107 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_6__call__(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1295
- *     return _init_Arc(self._encoder.get().__call__(deref(arc._arc)))
+/* "pywrapfst.pyx":1279
+ *   # Registers the class for pickling.
+ * 
+ *   def __reduce__(self):             # <<<<<<<<<<<<<<
+ *       return (_read_EncodeMapper_from_string, (self.write_to_string(),))
+ * 
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_7__reduce__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_7__reduce__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__reduce__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_6__reduce__(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_6__reduce__(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  __Pyx_RefNannySetupContext("__reduce__", 0);
+
+  /* "pywrapfst.pyx":1280
+ * 
+ *   def __reduce__(self):
+ *       return (_read_EncodeMapper_from_string, (self.write_to_string(),))             # <<<<<<<<<<<<<<
+ * 
+ *   cpdef string arc_type(self):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_read_EncodeMapper_from_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1280, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "write_to_string");
+    __PYX_ERR(0, 1280, __pyx_L1_error)
+  }
+  __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst_EncodeMapper *)__pyx_v_self->__pyx_vtab)->write_to_string(__pyx_v_self, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1280, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1280, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1280, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_3);
+  __pyx_t_1 = 0;
+  __pyx_t_3 = 0;
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  /* "pywrapfst.pyx":1279
+ *   # Registers the class for pickling.
+ * 
+ *   def __reduce__(self):             # <<<<<<<<<<<<<<
+ *       return (_read_EncodeMapper_from_string, (self.write_to_string(),))
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("pywrapfst.EncodeMapper.__reduce__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pywrapfst.pyx":1282
+ *       return (_read_EncodeMapper_from_string, (self.write_to_string(),))
  * 
- *   cpdef uint32 flags(self):             # <<<<<<<<<<<<<<
+ *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
  *     """
- *     flags(self)
+ *     arc_type(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_9flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_12EncodeMapper_flags(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, int __pyx_skip_dispatch) {
-  __pyx_t_10basictypes_uint32 __pyx_r;
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_9arc_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static std::string __pyx_f_9pywrapfst_12EncodeMapper_arc_type(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, int __pyx_skip_dispatch) {
+  std::string __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
-  __pyx_t_10basictypes_uint32 __pyx_t_5;
-  __Pyx_RefNannySetupContext("flags", 0);
+  std::string __pyx_t_5;
+  __Pyx_RefNannySetupContext("arc_type", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
@@ -15032,9 +14989,9 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_12EncodeMapper_flags(struc
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_flags); 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_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1282, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_9flags)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_9arc_type)) {
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
         if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -15048,10 +15005,10 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_12EncodeMapper_flags(struc
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1295, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1282, __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, 1295, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1282, __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;
@@ -15070,26 +15027,26 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_12EncodeMapper_flags(struc
     #endif
   }
 
-  /* "pywrapfst.pyx":1301
- *     Returns the encoder's flags.
+  /* "pywrapfst.pyx":1288
+ *     Returns a string indicating the arc type.
  *     """
- *     return self._encoder.get().Flags()             # <<<<<<<<<<<<<<
+ *     return self._mapper.get().ArcType()             # <<<<<<<<<<<<<<
  * 
- *   cpdef _EncodeMapperSymbolTable input_symbols(self):
+ *   cpdef string weight_type(self):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_encoder");
-    __PYX_ERR(0, 1301, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
+    __PYX_ERR(0, 1288, __pyx_L1_error)
   }
-  __pyx_r = __pyx_v_self->_encoder.get()->Flags();
+  __pyx_r = __pyx_v_self->_mapper.get()->ArcType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1295
- *     return _init_Arc(self._encoder.get().__call__(deref(arc._arc)))
+  /* "pywrapfst.pyx":1282
+ *       return (_read_EncodeMapper_from_string, (self.write_to_string(),))
  * 
- *   cpdef uint32 flags(self):             # <<<<<<<<<<<<<<
+ *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
  *     """
- *     flags(self)
+ *     arc_type(self)
  */
 
   /* function exit code */
@@ -15098,34 +15055,34 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_12EncodeMapper_flags(struc
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_WriteUnraisable("pywrapfst.EncodeMapper.flags", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
-  __pyx_r = 0;
+  __Pyx_WriteUnraisable("pywrapfst.EncodeMapper.arc_type", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_pretend_to_initialize(&__pyx_r);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
 /* 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) {
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_9arc_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_12EncodeMapper_8arc_type[] = "\n    arc_type(self)\n\n    Returns a string indicating the arc type.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_9arc_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("flags (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_8flags(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self));
+  __Pyx_RefNannySetupContext("arc_type (wrapper)", 0);
+  __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_8arc_type(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_8flags(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_8arc_type(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
-  __Pyx_RefNannySetupContext("flags", 0);
+  __Pyx_RefNannySetupContext("arc_type", 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, 1295, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_12EncodeMapper_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1282, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -15134,7 +15091,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_8flags(struct __pyx_obj_9pyw
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.EncodeMapper.flags", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.EncodeMapper.arc_type", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -15142,25 +15099,24 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_8flags(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1303
- *     return self._encoder.get().Flags()
+/* "pywrapfst.pyx":1290
+ *     return self._mapper.get().ArcType()
  * 
- *   cpdef _EncodeMapperSymbolTable input_symbols(self):             # <<<<<<<<<<<<<<
+ *   cpdef string weight_type(self):             # <<<<<<<<<<<<<<
  *     """
- *     input_symbols(self)
+ *     weight_type(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;
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_11weight_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static std::string __pyx_f_9pywrapfst_12EncodeMapper_weight_type(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, int __pyx_skip_dispatch) {
+  std::string __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
-  int __pyx_t_5;
-  __Pyx_RefNannySetupContext("input_symbols", 0);
+  std::string __pyx_t_5;
+  __Pyx_RefNannySetupContext("weight_type", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
@@ -15170,10 +15126,9 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_input_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1303, __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, 1290, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_11input_symbols)) {
-        __Pyx_XDECREF(((PyObject *)__pyx_r));
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_11weight_type)) {
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
         if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -15187,12 +15142,12 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1303, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1290, __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, 1303, __pyx_L1_error)
-        __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *)__pyx_t_2);
-        __pyx_t_2 = 0;
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1290, __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;
         goto __pyx_L0;
       }
@@ -15209,81 +15164,26 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_
     #endif
   }
 
-  /* "pywrapfst.pyx":1310
- *     """
- *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
- *         self._encoder.get().InputSymbols())             # <<<<<<<<<<<<<<
- *     if syms == NULL:
- *       return
- */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_encoder");
-    __PYX_ERR(0, 1310, __pyx_L1_error)
-  }
-
-  /* "pywrapfst.pyx":1309
- *     Returns the encoder's input symbol table, or None if none is present.
+  /* "pywrapfst.pyx":1296
+ *     Returns a string indicating the weight type.
  *     """
- *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](             # <<<<<<<<<<<<<<
- *         self._encoder.get().InputSymbols())
- *     if syms == NULL:
- */
-  __pyx_v_syms = const_cast<__pyx_t_9pywrapfst_SymbolTable_ptr>(__pyx_v_self->_encoder.get()->InputSymbols());
-
-  /* "pywrapfst.pyx":1311
- *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
- *         self._encoder.get().InputSymbols())
- *     if syms == NULL:             # <<<<<<<<<<<<<<
- *       return
- *     return _init_EncodeMapperSymbolTable(syms, self._encoder)
- */
-  __pyx_t_5 = ((__pyx_v_syms == NULL) != 0);
-  if (__pyx_t_5) {
-
-    /* "pywrapfst.pyx":1312
- *         self._encoder.get().InputSymbols())
- *     if syms == NULL:
- *       return             # <<<<<<<<<<<<<<
- *     return _init_EncodeMapperSymbolTable(syms, self._encoder)
+ *     return self._mapper.get().WeightType()             # <<<<<<<<<<<<<<
  * 
+ *   cpdef uint8 flags(self):
  */
-    __Pyx_XDECREF(((PyObject *)__pyx_r));
-    __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *)Py_None); __Pyx_INCREF(Py_None);
-    goto __pyx_L0;
-
-    /* "pywrapfst.pyx":1311
- *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
- *         self._encoder.get().InputSymbols())
- *     if syms == NULL:             # <<<<<<<<<<<<<<
- *       return
- *     return _init_EncodeMapperSymbolTable(syms, self._encoder)
- */
-  }
-
-  /* "pywrapfst.pyx":1313
- *     if syms == NULL:
- *       return
- *     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 '%.30s'", "_encoder");
-    __PYX_ERR(0, 1313, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
+    __PYX_ERR(0, 1296, __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, 1313, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *)__pyx_t_1);
-  __pyx_t_1 = 0;
+  __pyx_r = __pyx_v_self->_mapper.get()->WeightType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1303
- *     return self._encoder.get().Flags()
+  /* "pywrapfst.pyx":1290
+ *     return self._mapper.get().ArcType()
  * 
- *   cpdef _EncodeMapperSymbolTable input_symbols(self):             # <<<<<<<<<<<<<<
+ *   cpdef string weight_type(self):             # <<<<<<<<<<<<<<
  *     """
- *     input_symbols(self)
+ *     weight_type(self)
  */
 
   /* function exit code */
@@ -15292,35 +15192,34 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst.EncodeMapper.input_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = 0;
+  __Pyx_WriteUnraisable("pywrapfst.EncodeMapper.weight_type", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_pretend_to_initialize(&__pyx_r);
   __pyx_L0:;
-  __Pyx_XGIVEREF((PyObject *)__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
 /* 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) {
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_11weight_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_12EncodeMapper_10weight_type[] = "\n    weight_type(self)\n\n    Returns a string indicating the weight type.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_11weight_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("input_symbols (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_10input_symbols(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self));
+  __Pyx_RefNannySetupContext("weight_type (wrapper)", 0);
+  __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_10weight_type(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_10input_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_10weight_type(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
-  __Pyx_RefNannySetupContext("input_symbols", 0);
+  __Pyx_RefNannySetupContext("weight_type", 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, 1303, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_12EncodeMapper_weight_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1290, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -15329,7 +15228,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_10input_symbols(struct __pyx
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.EncodeMapper.input_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.EncodeMapper.weight_type", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -15337,25 +15236,24 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_10input_symbols(struct __pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1315
- *     return _init_EncodeMapperSymbolTable(syms, self._encoder)
+/* "pywrapfst.pyx":1298
+ *     return self._mapper.get().WeightType()
  * 
- *   cpdef _EncodeMapperSymbolTable output_symbols(self):             # <<<<<<<<<<<<<<
+ *   cpdef uint8 flags(self):             # <<<<<<<<<<<<<<
  *     """
- *     output_symbols(self)
+ *     flags(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;
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_13flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static __pyx_t_10basictypes_uint8 __pyx_f_9pywrapfst_12EncodeMapper_flags(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, int __pyx_skip_dispatch) {
+  __pyx_t_10basictypes_uint8 __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
-  int __pyx_t_5;
-  __Pyx_RefNannySetupContext("output_symbols", 0);
+  __pyx_t_10basictypes_uint8 __pyx_t_5;
+  __Pyx_RefNannySetupContext("flags", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
@@ -15365,10 +15263,9 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_output_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1315, __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, 1298, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_13output_symbols)) {
-        __Pyx_XDECREF(((PyObject *)__pyx_r));
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_13flags)) {
         __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))) {
@@ -15382,12 +15279,12 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1315, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1298, __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, 1315, __pyx_L1_error)
-        __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *)__pyx_t_2);
-        __pyx_t_2 = 0;
+        __pyx_t_5 = __Pyx_PyInt_As_uint8_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((uint8_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1298, __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;
         goto __pyx_L0;
       }
@@ -15404,81 +15301,26 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_
     #endif
   }
 
-  /* "pywrapfst.pyx":1322
+  /* "pywrapfst.pyx":1304
+ *     Returns the mapper's flags.
  *     """
- *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
- *         self._encoder.get().OutputSymbols())             # <<<<<<<<<<<<<<
- *     if syms == NULL:
- *       return
- */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_encoder");
-    __PYX_ERR(0, 1322, __pyx_L1_error)
-  }
-
-  /* "pywrapfst.pyx":1321
- *     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_v_syms = const_cast<__pyx_t_9pywrapfst_SymbolTable_ptr>(__pyx_v_self->_encoder.get()->OutputSymbols());
-
-  /* "pywrapfst.pyx":1323
- *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
- *         self._encoder.get().OutputSymbols())
- *     if syms == NULL:             # <<<<<<<<<<<<<<
- *       return
- *     return _init_EncodeMapperSymbolTable(syms, self._encoder)
- */
-  __pyx_t_5 = ((__pyx_v_syms == NULL) != 0);
-  if (__pyx_t_5) {
-
-    /* "pywrapfst.pyx":1324
- *         self._encoder.get().OutputSymbols())
- *     if syms == NULL:
- *       return             # <<<<<<<<<<<<<<
- *     return _init_EncodeMapperSymbolTable(syms, self._encoder)
- * 
- */
-    __Pyx_XDECREF(((PyObject *)__pyx_r));
-    __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *)Py_None); __Pyx_INCREF(Py_None);
-    goto __pyx_L0;
-
-    /* "pywrapfst.pyx":1323
- *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
- *         self._encoder.get().OutputSymbols())
- *     if syms == NULL:             # <<<<<<<<<<<<<<
- *       return
- *     return _init_EncodeMapperSymbolTable(syms, self._encoder)
- */
-  }
-
-  /* "pywrapfst.pyx":1325
- *     if syms == NULL:
- *       return
- *     return _init_EncodeMapperSymbolTable(syms, self._encoder)             # <<<<<<<<<<<<<<
+ *     return self._mapper.get().Flags()             # <<<<<<<<<<<<<<
  * 
  *   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 '%.30s'", "_encoder");
-    __PYX_ERR(0, 1325, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
+    __PYX_ERR(0, 1304, __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, 1325, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *)__pyx_t_1);
-  __pyx_t_1 = 0;
+  __pyx_r = __pyx_v_self->_mapper.get()->Flags();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1315
- *     return _init_EncodeMapperSymbolTable(syms, self._encoder)
+  /* "pywrapfst.pyx":1298
+ *     return self._mapper.get().WeightType()
  * 
- *   cpdef _EncodeMapperSymbolTable output_symbols(self):             # <<<<<<<<<<<<<<
+ *   cpdef uint8 flags(self):             # <<<<<<<<<<<<<<
  *     """
- *     output_symbols(self)
+ *     flags(self)
  */
 
   /* function exit code */
@@ -15487,35 +15329,34 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst.EncodeMapper.output_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_WriteUnraisable("pywrapfst.EncodeMapper.flags", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_r = 0;
   __pyx_L0:;
-  __Pyx_XGIVEREF((PyObject *)__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
 /* 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) {
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_13flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_12EncodeMapper_12flags[] = "\n    flags(self)\n\n    Returns the mapper's flags.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_13flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("output_symbols (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_12output_symbols(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self));
+  __Pyx_RefNannySetupContext("flags (wrapper)", 0);
+  __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_12flags(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_12output_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_12flags(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
-  __Pyx_RefNannySetupContext("output_symbols", 0);
+  __Pyx_RefNannySetupContext("flags", 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, 1315, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(__pyx_f_9pywrapfst_12EncodeMapper_flags(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1298, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -15524,7 +15365,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_12output_symbols(struct __py
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.EncodeMapper.output_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.EncodeMapper.flags", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -15532,8 +15373,8 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_12output_symbols(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1327
- *     return _init_EncodeMapperSymbolTable(syms, self._encoder)
+/* "pywrapfst.pyx":1306
+ *     return self._mapper.get().Flags()
  * 
  *   cpdef uint64 properties(self, uint64 mask):             # <<<<<<<<<<<<<<
  *     """
@@ -15560,10 +15401,10 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_12EncodeMapper_properties(
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_properties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1327, __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, 1306, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_15properties)) {
-        __pyx_t_3 = __Pyx_PyInt_From_uint64_t(__pyx_v_mask); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1327, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_uint64_t(__pyx_v_mask); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1306, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -15579,10 +15420,10 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_12EncodeMapper_properties(
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1327, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1306, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        __pyx_t_6 = __Pyx_PyInt_As_uint64_t(__pyx_t_2); if (unlikely((__pyx_t_6 == ((uint64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1327, __pyx_L1_error)
+        __pyx_t_6 = __Pyx_PyInt_As_uint64_t(__pyx_t_2); if (unlikely((__pyx_t_6 == ((uint64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1306, __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;
@@ -15601,22 +15442,22 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_12EncodeMapper_properties(
     #endif
   }
 
-  /* "pywrapfst.pyx":1341
+  /* "pywrapfst.pyx":1320
  *       A 64-bit bitmask representing the requested properties.
  *     """
- *     return self._encoder.get().Properties(mask)             # <<<<<<<<<<<<<<
+ *     return self._mapper.get().Properties(mask)             # <<<<<<<<<<<<<<
  * 
- *   cpdef void set_input_symbols(self, _SymbolTable syms) except *:
+ *   @classmethod
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_encoder");
-    __PYX_ERR(0, 1341, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
+    __PYX_ERR(0, 1320, __pyx_L1_error)
   }
-  __pyx_r = __pyx_v_self->_encoder.get()->Properties(__pyx_v_mask);
+  __pyx_r = __pyx_v_self->_mapper.get()->Properties(__pyx_v_mask);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1327
- *     return _init_EncodeMapperSymbolTable(syms, self._encoder)
+  /* "pywrapfst.pyx":1306
+ *     return self._mapper.get().Flags()
  * 
  *   cpdef uint64 properties(self, uint64 mask):             # <<<<<<<<<<<<<<
  *     """
@@ -15639,14 +15480,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 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 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 mapper.\n\n    Args:\n      mask: The property mask to be compared to the mapper'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, 1327, __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, 1306, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -15667,7 +15508,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, 1327, __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, 1306, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -15684,22 +15525,271 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_14properties(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1343
- *     return self._encoder.get().Properties(mask)
+/* "pywrapfst.pyx":1323
  * 
- *   cpdef void set_input_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
+ *   @classmethod
+ *   def read(cls, source):             # <<<<<<<<<<<<<<
  *     """
- *     set_input_symbols(self, syms)
+ *     EncodeMapper.read(source)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_17set_input_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms); /*proto*/
-static void __pyx_f_9pywrapfst_12EncodeMapper_set_input_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms, int __pyx_skip_dispatch) {
+/* Python wrapper */
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_17read(PyObject *__pyx_v_cls, PyObject *__pyx_v_source); /*proto*/
+static char __pyx_doc_9pywrapfst_12EncodeMapper_16read[] = "\n    EncodeMapper.read(source)\n\n    Reads encode mapper from binary file.\n\n    This class method creates a new EncodeMapper from an encode mapper binary\n    file.\n\n    Args:\n      source: The string location of the input binary file.\n\n    Returns:\n      A new EncodeMapper instance.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_17read(PyObject *__pyx_v_cls, PyObject *__pyx_v_source) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("read (wrapper)", 0);
+  __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_16read(((PyTypeObject*)__pyx_v_cls), ((PyObject *)__pyx_v_source));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_16read(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_source) {
+  std::unique_ptr<fst::script::EncodeMapperClass>  __pyx_v_mapper;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  std::string __pyx_t_1;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  __Pyx_RefNannySetupContext("read", 0);
+
+  /* "pywrapfst.pyx":1339
+ *     """
+ *     cdef unique_ptr[fst.EncodeMapperClass] mapper
+ *     mapper.reset(fst.EncodeMapperClass.Read(tostring(source)))             # <<<<<<<<<<<<<<
+ *     if mapper.get() == NULL:
+ *       raise FstIOError("Read failed: {!r}".format(source))
+ */
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1339, __pyx_L1_error)
+  __pyx_v_mapper.reset(fst::script::EncodeMapperClass::Read(__pyx_t_1));
+
+  /* "pywrapfst.pyx":1340
+ *     cdef unique_ptr[fst.EncodeMapperClass] mapper
+ *     mapper.reset(fst.EncodeMapperClass.Read(tostring(source)))
+ *     if mapper.get() == NULL:             # <<<<<<<<<<<<<<
+ *       raise FstIOError("Read failed: {!r}".format(source))
+ *     return _init_EncodeMapper(mapper.release())
+ */
+  __pyx_t_2 = ((__pyx_v_mapper.get() == NULL) != 0);
+  if (unlikely(__pyx_t_2)) {
+
+    /* "pywrapfst.pyx":1341
+ *     mapper.reset(fst.EncodeMapperClass.Read(tostring(source)))
+ *     if mapper.get() == NULL:
+ *       raise FstIOError("Read failed: {!r}".format(source))             # <<<<<<<<<<<<<<
+ *     return _init_EncodeMapper(mapper.release())
+ * 
+ */
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1341, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1341, __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_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_6, function);
+      }
+    }
+    __pyx_t_5 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_source);
+    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1341, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_5);
+    __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_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_4, function);
+      }
+    }
+    __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5);
+    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1341, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __PYX_ERR(0, 1341, __pyx_L1_error)
+
+    /* "pywrapfst.pyx":1340
+ *     cdef unique_ptr[fst.EncodeMapperClass] mapper
+ *     mapper.reset(fst.EncodeMapperClass.Read(tostring(source)))
+ *     if mapper.get() == NULL:             # <<<<<<<<<<<<<<
+ *       raise FstIOError("Read failed: {!r}".format(source))
+ *     return _init_EncodeMapper(mapper.release())
+ */
+  }
+
+  /* "pywrapfst.pyx":1342
+ *     if mapper.get() == NULL:
+ *       raise FstIOError("Read failed: {!r}".format(source))
+ *     return _init_EncodeMapper(mapper.release())             # <<<<<<<<<<<<<<
+ * 
+ *   @staticmethod
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_EncodeMapper(__pyx_v_mapper.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1342, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_r = __pyx_t_3;
+  __pyx_t_3 = 0;
+  goto __pyx_L0;
+
+  /* "pywrapfst.pyx":1323
+ * 
+ *   @classmethod
+ *   def read(cls, source):             # <<<<<<<<<<<<<<
+ *     """
+ *     EncodeMapper.read(source)
+ */
+
+  /* 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_AddTraceback("pywrapfst.EncodeMapper.read", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pywrapfst.pyx":1345
+ * 
+ *   @staticmethod
+ *   def read_from_string(state):             # <<<<<<<<<<<<<<
+ *     """
+ *     read_from_string(state)
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_19read_from_string(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_12EncodeMapper_18read_from_string[] = "\n    read_from_string(state)\n\n    Reads an EncodeMapper from a serialized string.\n\n    Args:\n      state: A string containing the serialized EncodeMapper.\n\n    Returns:\n      An EncodeMapper object.\n\n    Raises:\n      FstIOError: Read failed.\n    ";
+static PyMethodDef __pyx_mdef_9pywrapfst_12EncodeMapper_19read_from_string = {"read_from_string", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_12EncodeMapper_19read_from_string, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_12EncodeMapper_18read_from_string};
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_19read_from_string(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_state = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("read_from_string (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_state,0};
+    PyObject* values[1] = {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  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        CYTHON_FALLTHROUGH;
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_state)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "read_from_string") < 0)) __PYX_ERR(0, 1345, __pyx_L3_error)
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+    }
+    __pyx_v_state = values[0];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("read_from_string", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1345, __pyx_L3_error)
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("pywrapfst.EncodeMapper.read_from_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_18read_from_string(__pyx_v_state);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_18read_from_string(PyObject *__pyx_v_state) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  __Pyx_RefNannySetupContext("read_from_string", 0);
+
+  /* "pywrapfst.pyx":1360
+ *       FstIOError: Read failed.
+ *     """
+ *     return _read_EncodeMapper_from_string(state)             # <<<<<<<<<<<<<<
+ * 
+ *   cpdef void write(self, source) except *:
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_EncodeMapper_from_string(__pyx_v_state, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1360, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "pywrapfst.pyx":1345
+ * 
+ *   @staticmethod
+ *   def read_from_string(state):             # <<<<<<<<<<<<<<
+ *     """
+ *     read_from_string(state)
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("pywrapfst.EncodeMapper.read_from_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pywrapfst.pyx":1362
+ *     return _read_EncodeMapper_from_string(state)
+ * 
+ *   cpdef void write(self, source) except *:             # <<<<<<<<<<<<<<
+ *       """
+ *       write(self, source)
+ */
+
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_21write(PyObject *__pyx_v_self, PyObject *__pyx_v_source); /*proto*/
+static void __pyx_f_9pywrapfst_12EncodeMapper_write(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
-  __Pyx_RefNannySetupContext("set_input_symbols", 0);
+  std::string __pyx_t_5;
+  int __pyx_t_6;
+  PyObject *__pyx_t_7 = NULL;
+  __Pyx_RefNannySetupContext("write", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
@@ -15709,9 +15799,9 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_set_input_symbols(struct __pyx_obj
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_input_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1343, __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, 1362, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_17set_input_symbols)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_21write)) {
         __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))) {
@@ -15723,9 +15813,9 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_set_input_symbols(struct __pyx_obj
             __Pyx_DECREF_SET(__pyx_t_3, function);
           }
         }
-        __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, ((PyObject *)__pyx_v_syms)) : __Pyx_PyObject_CallOneArg(__pyx_t_3, ((PyObject *)__pyx_v_syms));
+        __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_source);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1343, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1362, __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;
@@ -15745,29 +15835,82 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_set_input_symbols(struct __pyx_obj
     #endif
   }
 
-  /* "pywrapfst.pyx":1354
- *     See also: `set_output_symbols`.
- *     """
- *     self._encoder.get().SetInputSymbols(syms._table)             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":1375
+ *         FstIOError: Write failed.
+ *       """
+ *       if not self._mapper.get().Write(tostring(source)):             # <<<<<<<<<<<<<<
+ *         raise FstIOError("Write failed: {!r}".format(source))
  * 
- *   cpdef void set_output_symbols(self, _SymbolTable syms) except *:
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_encoder");
-    __PYX_ERR(0, 1354, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
+    __PYX_ERR(0, 1375, __pyx_L1_error)
   }
-  if (unlikely(((PyObject *)__pyx_v_syms) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 1354, __pyx_L1_error)
+  __pyx_t_5 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1375, __pyx_L1_error)
+  __pyx_t_6 = ((!(__pyx_v_self->_mapper.get()->Write(__pyx_t_5) != 0)) != 0);
+  if (unlikely(__pyx_t_6)) {
+
+    /* "pywrapfst.pyx":1376
+ *       """
+ *       if not self._mapper.get().Write(tostring(source)):
+ *         raise FstIOError("Write failed: {!r}".format(source))             # <<<<<<<<<<<<<<
+ * 
+ *   cpdef bytes write_to_string(self):
+ */
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1376, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Write_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1376, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_7 = NULL;
+    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) {
+      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_4);
+      if (likely(__pyx_t_7)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+        __Pyx_INCREF(__pyx_t_7);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_4, function);
+      }
+    }
+    __pyx_t_3 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_7, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_source);
+    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1376, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_4 = NULL;
+    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
+      __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
+      if (likely(__pyx_t_4)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+        __Pyx_INCREF(__pyx_t_4);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_2, function);
+      }
+    }
+    __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
+    __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1376, __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, 1376, __pyx_L1_error)
+
+    /* "pywrapfst.pyx":1375
+ *         FstIOError: Write failed.
+ *       """
+ *       if not self._mapper.get().Write(tostring(source)):             # <<<<<<<<<<<<<<
+ *         raise FstIOError("Write failed: {!r}".format(source))
+ * 
+ */
   }
-  __pyx_v_self->_encoder.get()->SetInputSymbols(__pyx_v_syms->_table);
 
-  /* "pywrapfst.pyx":1343
- *     return self._encoder.get().Properties(mask)
+  /* "pywrapfst.pyx":1362
+ *     return _read_EncodeMapper_from_string(state)
  * 
- *   cpdef void set_input_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
- *     """
- *     set_input_symbols(self, syms)
+ *   cpdef void write(self, source) except *:             # <<<<<<<<<<<<<<
+ *       """
+ *       write(self, source)
  */
 
   /* function exit code */
@@ -15777,38 +15920,615 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_set_input_symbols(struct __pyx_obj
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst.EncodeMapper.set_input_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_AddTraceback("pywrapfst.EncodeMapper.write", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
 /* 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 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) {
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_21write(PyObject *__pyx_v_self, PyObject *__pyx_v_source); /*proto*/
+static char __pyx_doc_9pywrapfst_12EncodeMapper_20write[] = "\n      write(self, source)\n\n      Serializes mapper to a file.\n\n      This method writes the mapper to a file in a binary format.\n\n      Args:\n        source: The string location of the output file.\n      Raises:\n        FstIOError: Write failed.\n      ";
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_21write(PyObject *__pyx_v_self, PyObject *__pyx_v_source) {
   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, 1343, __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));
+  __Pyx_RefNannySetupContext("write (wrapper)", 0);
+  __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_20write(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self), ((PyObject *)__pyx_v_source));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_20write(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, PyObject *__pyx_v_source) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  __Pyx_RefNannySetupContext("write", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_f_9pywrapfst_12EncodeMapper_write(__pyx_v_self, __pyx_v_source, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1362, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1362, __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.EncodeMapper.write", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pywrapfst.pyx":1378
+ *         raise FstIOError("Write failed: {!r}".format(source))
+ * 
+ *   cpdef bytes write_to_string(self):             # <<<<<<<<<<<<<<
+ *       """
+ *       write_to_string(self)
+ */
+
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_23write_to_string(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_f_9pywrapfst_12EncodeMapper_write_to_string(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, int __pyx_skip_dispatch) {
+  std::stringstream __pyx_v_sstrm;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_t_5;
+  __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) || (Py_TYPE(((PyObject *)__pyx_v_self))->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)))) {
+    #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
+    static PY_UINT64_T __pyx_tp_dict_version = __PYX_DICT_VERSION_INIT, __pyx_obj_dict_version = __PYX_DICT_VERSION_INIT;
+    if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
+      PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
+      #endif
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write_to_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1378, __pyx_L1_error)
+      __Pyx_GOTREF(__pyx_t_1);
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_23write_to_string)) {
+        __Pyx_XDECREF(__pyx_r);
+        __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);
+          }
+        }
+        __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
+        __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1378, __pyx_L1_error)
+        __Pyx_GOTREF(__pyx_t_2);
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+        if (!(likely(PyBytes_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_2)->tp_name), 0))) __PYX_ERR(0, 1378, __pyx_L1_error)
+        __pyx_r = ((PyObject*)__pyx_t_2);
+        __pyx_t_2 = 0;
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        goto __pyx_L0;
+      }
+      #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
+      __pyx_tp_dict_version = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
+      __pyx_obj_dict_version = __Pyx_get_object_dict_version(((PyObject *)__pyx_v_self));
+      if (unlikely(__pyx_type_dict_guard != __pyx_tp_dict_version)) {
+        __pyx_tp_dict_version = __pyx_obj_dict_version = __PYX_DICT_VERSION_INIT;
+      }
+      #endif
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
+    }
+    #endif
+  }
+
+  /* "pywrapfst.pyx":1391
+ *       """
+ *       cdef stringstream sstrm
+ *       if not self._mapper.get().WriteStream(sstrm, b"<pywrapfst>"):             # <<<<<<<<<<<<<<
+ *         raise FstIOError("Write to string failed")
+ *       return sstrm.str()
+ */
+  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
+    __PYX_ERR(0, 1391, __pyx_L1_error)
+  }
+  __pyx_t_5 = ((!(__pyx_v_self->_mapper.get()->Write(__pyx_v_sstrm, __pyx_k_pywrapfst) != 0)) != 0);
+  if (unlikely(__pyx_t_5)) {
+
+    /* "pywrapfst.pyx":1392
+ *       cdef stringstream sstrm
+ *       if not self._mapper.get().WriteStream(sstrm, b"<pywrapfst>"):
+ *         raise FstIOError("Write to string failed")             # <<<<<<<<<<<<<<
+ *       return sstrm.str()
+ * 
+ */
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1392, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_3 = NULL;
+    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
+      __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+      if (likely(__pyx_t_3)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+        __Pyx_INCREF(__pyx_t_3);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_2, function);
+      }
+    }
+    __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_kp_u_Write_to_string_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_Write_to_string_failed);
+    __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1392, __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, 1392, __pyx_L1_error)
+
+    /* "pywrapfst.pyx":1391
+ *       """
+ *       cdef stringstream sstrm
+ *       if not self._mapper.get().WriteStream(sstrm, b"<pywrapfst>"):             # <<<<<<<<<<<<<<
+ *         raise FstIOError("Write to string failed")
+ *       return sstrm.str()
+ */
+  }
+
+  /* "pywrapfst.pyx":1393
+ *       if not self._mapper.get().WriteStream(sstrm, b"<pywrapfst>"):
+ *         raise FstIOError("Write to string failed")
+ *       return sstrm.str()             # <<<<<<<<<<<<<<
+ * 
+ *   cpdef _EncodeMapperSymbolTable input_symbols(self):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_sstrm.str()); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1393, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = ((PyObject*)__pyx_t_1);
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "pywrapfst.pyx":1378
+ *         raise FstIOError("Write failed: {!r}".format(source))
+ * 
+ *   cpdef bytes write_to_string(self):             # <<<<<<<<<<<<<<
+ *       """
+ *       write_to_string(self)
+ */
+
+  /* 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_AddTraceback("pywrapfst.EncodeMapper.write_to_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_23write_to_string(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_12EncodeMapper_22write_to_string[] = "\n      write_to_string(self)\n\n      Serializes mapper to a string.\n\n      Returns:\n        A bytestring.\n\n      Raises:\n        FstIOError: Write to string failed.\n      ";
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_23write_to_string(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("write_to_string (wrapper)", 0);
+  __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_22write_to_string(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_22write_to_string(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  __Pyx_RefNannySetupContext("write_to_string", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __pyx_f_9pywrapfst_12EncodeMapper_write_to_string(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1378, __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.EncodeMapper.write_to_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pywrapfst.pyx":1395
+ *       return sstrm.str()
+ * 
+ *   cpdef _EncodeMapperSymbolTable input_symbols(self):             # <<<<<<<<<<<<<<
+ *     """
+ *     input_symbols(self)
+ */
+
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_25input_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;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_t_5;
+  __Pyx_RefNannySetupContext("input_symbols", 0);
+  /* Check if called by wrapper */
+  if (unlikely(__pyx_skip_dispatch)) ;
+  /* Check if overridden in Python */
+  else if (unlikely((Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0) || (Py_TYPE(((PyObject *)__pyx_v_self))->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)))) {
+    #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
+    static PY_UINT64_T __pyx_tp_dict_version = __PYX_DICT_VERSION_INIT, __pyx_obj_dict_version = __PYX_DICT_VERSION_INIT;
+    if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
+      PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
+      #endif
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_input_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1395, __pyx_L1_error)
+      __Pyx_GOTREF(__pyx_t_1);
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_25input_symbols)) {
+        __Pyx_XDECREF(((PyObject *)__pyx_r));
+        __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);
+          }
+        }
+        __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
+        __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1395, __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, 1395, __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;
+        goto __pyx_L0;
+      }
+      #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
+      __pyx_tp_dict_version = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
+      __pyx_obj_dict_version = __Pyx_get_object_dict_version(((PyObject *)__pyx_v_self));
+      if (unlikely(__pyx_type_dict_guard != __pyx_tp_dict_version)) {
+        __pyx_tp_dict_version = __pyx_obj_dict_version = __PYX_DICT_VERSION_INIT;
+      }
+      #endif
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
+    }
+    #endif
+  }
+
+  /* "pywrapfst.pyx":1402
+ *     """
+ *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
+ *         self._mapper.get().InputSymbols())             # <<<<<<<<<<<<<<
+ *     if syms == NULL:
+ *       return
+ */
+  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
+    __PYX_ERR(0, 1402, __pyx_L1_error)
+  }
+
+  /* "pywrapfst.pyx":1401
+ *     Returns the mapper's input symbol table, or None if none is present.
+ *     """
+ *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](             # <<<<<<<<<<<<<<
+ *         self._mapper.get().InputSymbols())
+ *     if syms == NULL:
+ */
+  __pyx_v_syms = const_cast<__pyx_t_9pywrapfst_SymbolTable_ptr>(__pyx_v_self->_mapper.get()->InputSymbols());
+
+  /* "pywrapfst.pyx":1403
+ *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
+ *         self._mapper.get().InputSymbols())
+ *     if syms == NULL:             # <<<<<<<<<<<<<<
+ *       return
+ *     return _init_EncodeMapperSymbolTable(syms, self._mapper)
+ */
+  __pyx_t_5 = ((__pyx_v_syms == NULL) != 0);
+  if (__pyx_t_5) {
+
+    /* "pywrapfst.pyx":1404
+ *         self._mapper.get().InputSymbols())
+ *     if syms == NULL:
+ *       return             # <<<<<<<<<<<<<<
+ *     return _init_EncodeMapperSymbolTable(syms, self._mapper)
+ * 
+ */
+    __Pyx_XDECREF(((PyObject *)__pyx_r));
+    __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *)Py_None); __Pyx_INCREF(Py_None);
+    goto __pyx_L0;
+
+    /* "pywrapfst.pyx":1403
+ *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
+ *         self._mapper.get().InputSymbols())
+ *     if syms == NULL:             # <<<<<<<<<<<<<<
+ *       return
+ *     return _init_EncodeMapperSymbolTable(syms, self._mapper)
+ */
+  }
+
+  /* "pywrapfst.pyx":1405
+ *     if syms == NULL:
+ *       return
+ *     return _init_EncodeMapperSymbolTable(syms, self._mapper)             # <<<<<<<<<<<<<<
+ * 
+ *   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 '%.30s'", "_mapper");
+    __PYX_ERR(0, 1405, __pyx_L1_error)
+  }
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_EncodeMapperSymbolTable(__pyx_v_syms, __pyx_v_self->_mapper)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1405, __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":1395
+ *       return sstrm.str()
+ * 
+ *   cpdef _EncodeMapperSymbolTable input_symbols(self):             # <<<<<<<<<<<<<<
+ *     """
+ *     input_symbols(self)
+ */
 
   /* 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_AddTraceback("pywrapfst.EncodeMapper.input_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF((PyObject *)__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_25input_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_12EncodeMapper_24input_symbols[] = "\n    input_symbols(self)\n\n    Returns the mapper's input symbol table, or None if none is present.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_25input_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("input_symbols (wrapper)", 0);
+  __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_24input_symbols(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_24input_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  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, 1395, __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.EncodeMapper.input_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_16set_input_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms) {
+/* "pywrapfst.pyx":1407
+ *     return _init_EncodeMapperSymbolTable(syms, self._mapper)
+ * 
+ *   cpdef _EncodeMapperSymbolTable output_symbols(self):             # <<<<<<<<<<<<<<
+ *     """
+ *     output_symbols(self)
+ */
+
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_27output_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;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_t_5;
+  __Pyx_RefNannySetupContext("output_symbols", 0);
+  /* Check if called by wrapper */
+  if (unlikely(__pyx_skip_dispatch)) ;
+  /* Check if overridden in Python */
+  else if (unlikely((Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0) || (Py_TYPE(((PyObject *)__pyx_v_self))->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)))) {
+    #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
+    static PY_UINT64_T __pyx_tp_dict_version = __PYX_DICT_VERSION_INIT, __pyx_obj_dict_version = __PYX_DICT_VERSION_INIT;
+    if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
+      PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
+      #endif
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_output_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1407, __pyx_L1_error)
+      __Pyx_GOTREF(__pyx_t_1);
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_27output_symbols)) {
+        __Pyx_XDECREF(((PyObject *)__pyx_r));
+        __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);
+          }
+        }
+        __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
+        __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1407, __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, 1407, __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;
+        goto __pyx_L0;
+      }
+      #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
+      __pyx_tp_dict_version = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
+      __pyx_obj_dict_version = __Pyx_get_object_dict_version(((PyObject *)__pyx_v_self));
+      if (unlikely(__pyx_type_dict_guard != __pyx_tp_dict_version)) {
+        __pyx_tp_dict_version = __pyx_obj_dict_version = __PYX_DICT_VERSION_INIT;
+      }
+      #endif
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
+    }
+    #endif
+  }
+
+  /* "pywrapfst.pyx":1414
+ *     """
+ *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
+ *         self._mapper.get().OutputSymbols())             # <<<<<<<<<<<<<<
+ *     if syms == NULL:
+ *       return
+ */
+  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
+    __PYX_ERR(0, 1414, __pyx_L1_error)
+  }
+
+  /* "pywrapfst.pyx":1413
+ *     Returns the mapper's output symbol table, or None if none is present.
+ *     """
+ *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](             # <<<<<<<<<<<<<<
+ *         self._mapper.get().OutputSymbols())
+ *     if syms == NULL:
+ */
+  __pyx_v_syms = const_cast<__pyx_t_9pywrapfst_SymbolTable_ptr>(__pyx_v_self->_mapper.get()->OutputSymbols());
+
+  /* "pywrapfst.pyx":1415
+ *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
+ *         self._mapper.get().OutputSymbols())
+ *     if syms == NULL:             # <<<<<<<<<<<<<<
+ *       return
+ *     return _init_EncodeMapperSymbolTable(syms, self._mapper)
+ */
+  __pyx_t_5 = ((__pyx_v_syms == NULL) != 0);
+  if (__pyx_t_5) {
+
+    /* "pywrapfst.pyx":1416
+ *         self._mapper.get().OutputSymbols())
+ *     if syms == NULL:
+ *       return             # <<<<<<<<<<<<<<
+ *     return _init_EncodeMapperSymbolTable(syms, self._mapper)
+ * 
+ */
+    __Pyx_XDECREF(((PyObject *)__pyx_r));
+    __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *)Py_None); __Pyx_INCREF(Py_None);
+    goto __pyx_L0;
+
+    /* "pywrapfst.pyx":1415
+ *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
+ *         self._mapper.get().OutputSymbols())
+ *     if syms == NULL:             # <<<<<<<<<<<<<<
+ *       return
+ *     return _init_EncodeMapperSymbolTable(syms, self._mapper)
+ */
+  }
+
+  /* "pywrapfst.pyx":1417
+ *     if syms == NULL:
+ *       return
+ *     return _init_EncodeMapperSymbolTable(syms, self._mapper)             # <<<<<<<<<<<<<<
+ * 
+ *   cpdef void set_input_symbols(self, _SymbolTable syms) except *:
+ */
+  __Pyx_XDECREF(((PyObject *)__pyx_r));
+  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
+    __PYX_ERR(0, 1417, __pyx_L1_error)
+  }
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_EncodeMapperSymbolTable(__pyx_v_syms, __pyx_v_self->_mapper)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1417, __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":1407
+ *     return _init_EncodeMapperSymbolTable(syms, self._mapper)
+ * 
+ *   cpdef _EncodeMapperSymbolTable output_symbols(self):             # <<<<<<<<<<<<<<
+ *     """
+ *     output_symbols(self)
+ */
+
+  /* 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_AddTraceback("pywrapfst.EncodeMapper.output_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF((PyObject *)__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_27output_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_12EncodeMapper_26output_symbols[] = "\n    output_symbols(self)\n\n    Returns the mapper's output symbol table, or None if none is present.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_27output_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("output_symbols (wrapper)", 0);
+  __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_26output_symbols(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_26output_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
-  __Pyx_RefNannySetupContext("set_input_symbols", 0);
+  __Pyx_RefNannySetupContext("output_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, 1343, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1343, __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, 1407, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -15817,7 +16537,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_16set_input_symbols(struct _
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.EncodeMapper.set_input_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.EncodeMapper.output_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -15825,22 +16545,22 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_16set_input_symbols(struct _
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1356
- *     self._encoder.get().SetInputSymbols(syms._table)
+/* "pywrapfst.pyx":1419
+ *     return _init_EncodeMapperSymbolTable(syms, self._mapper)
  * 
- *   cpdef void set_output_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
+ *   cpdef void set_input_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
  *     """
- *     set_output_symbols(self, syms)
+ *     set_input_symbols(self, syms)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_19set_output_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms); /*proto*/
-static void __pyx_f_9pywrapfst_12EncodeMapper_set_output_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_29set_input_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms); /*proto*/
+static void __pyx_f_9pywrapfst_12EncodeMapper_set_input_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
-  __Pyx_RefNannySetupContext("set_output_symbols", 0);
+  __Pyx_RefNannySetupContext("set_input_symbols", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
@@ -15850,9 +16570,9 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_set_output_symbols(struct __pyx_ob
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_output_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1356, __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, 1419, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_19set_output_symbols)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_29set_input_symbols)) {
         __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))) {
@@ -15866,7 +16586,7 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_set_output_symbols(struct __pyx_ob
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, ((PyObject *)__pyx_v_syms)) : __Pyx_PyObject_CallOneArg(__pyx_t_3, ((PyObject *)__pyx_v_syms));
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1356, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1419, __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;
@@ -15886,29 +16606,29 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_set_output_symbols(struct __pyx_ob
     #endif
   }
 
-  /* "pywrapfst.pyx":1367
- *     See also: `set_input_symbols`.
+  /* "pywrapfst.pyx":1428
+ *       syms: A SymbolTable.
  *     """
- *     self._encoder.get().SetOutputSymbols(syms._table)             # <<<<<<<<<<<<<<
+ *     self._mapper.get().SetInputSymbols(syms._table)             # <<<<<<<<<<<<<<
  * 
- *   cpdef string weight_type(self):
+ *   cpdef void set_output_symbols(self, _SymbolTable syms) except *:
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_encoder");
-    __PYX_ERR(0, 1367, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
+    __PYX_ERR(0, 1428, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_syms) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 1367, __pyx_L1_error)
+    __PYX_ERR(0, 1428, __pyx_L1_error)
   }
-  __pyx_v_self->_encoder.get()->SetOutputSymbols(__pyx_v_syms->_table);
+  __pyx_v_self->_mapper.get()->SetInputSymbols(__pyx_v_syms->_table);
 
-  /* "pywrapfst.pyx":1356
- *     self._encoder.get().SetInputSymbols(syms._table)
+  /* "pywrapfst.pyx":1419
+ *     return _init_EncodeMapperSymbolTable(syms, self._mapper)
  * 
- *   cpdef void set_output_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
+ *   cpdef void set_input_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
  *     """
- *     set_output_symbols(self, syms)
+ *     set_input_symbols(self, syms)
  */
 
   /* function exit code */
@@ -15918,20 +16638,20 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_set_output_symbols(struct __pyx_ob
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst.EncodeMapper.set_output_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.EncodeMapper.set_input_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
 /* 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 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) {
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_29set_input_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms); /*proto*/
+static char __pyx_doc_9pywrapfst_12EncodeMapper_28set_input_symbols[] = "\n    set_input_symbols(self, syms)\n\n    Sets the mapper's input symbol table.\n\n    Args:\n      syms: A SymbolTable.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_29set_input_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, 1356, __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));
+  __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, 1419, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_28set_input_symbols(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_syms));
 
   /* function exit code */
   goto __pyx_L0;
@@ -15942,14 +16662,14 @@ static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_19set_output_symbols(PyObjec
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_18set_output_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms) {
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_28set_input_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
-  __Pyx_RefNannySetupContext("set_output_symbols", 0);
+  __Pyx_RefNannySetupContext("set_input_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, 1356, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1356, __pyx_L1_error)
+  __pyx_f_9pywrapfst_12EncodeMapper_set_input_symbols(__pyx_v_self, __pyx_v_syms, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1419, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1419, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -15958,7 +16678,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_18set_output_symbols(struct
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.EncodeMapper.set_output_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.EncodeMapper.set_input_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -15966,24 +16686,22 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_18set_output_symbols(struct
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1369
- *     self._encoder.get().SetOutputSymbols(syms._table)
+/* "pywrapfst.pyx":1430
+ *     self._mapper.get().SetInputSymbols(syms._table)
  * 
- *   cpdef string weight_type(self):             # <<<<<<<<<<<<<<
+ *   cpdef void set_output_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
  *     """
- *     weight_type(self)
+ *     set_output_symbols(self, syms)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_21weight_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static std::string __pyx_f_9pywrapfst_12EncodeMapper_weight_type(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, int __pyx_skip_dispatch) {
-  std::string __pyx_r;
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_31set_output_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms); /*proto*/
+static void __pyx_f_9pywrapfst_12EncodeMapper_set_output_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
-  std::string __pyx_t_5;
-  __Pyx_RefNannySetupContext("weight_type", 0);
+  __Pyx_RefNannySetupContext("set_output_symbols", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
@@ -15993,9 +16711,9 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_weight_type(struct __pyx_ob
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_weight_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1369, __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, 1430, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_21weight_type)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_31set_output_symbols)) {
         __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))) {
@@ -16007,14 +16725,12 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_weight_type(struct __pyx_ob
             __Pyx_DECREF_SET(__pyx_t_3, function);
           }
         }
-        __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
+        __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, ((PyObject *)__pyx_v_syms)) : __Pyx_PyObject_CallOneArg(__pyx_t_3, ((PyObject *)__pyx_v_syms));
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1369, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1430, __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, 1369, __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;
         goto __pyx_L0;
       }
@@ -16031,62 +16747,70 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_weight_type(struct __pyx_ob
     #endif
   }
 
-  /* "pywrapfst.pyx":1375
- *     Returns a string indicating the weight type.
+  /* "pywrapfst.pyx":1439
+ *       syms: A SymbolTable.
  *     """
- *     return self._encoder.get().WeightType()             # <<<<<<<<<<<<<<
+ *     self._mapper.get().SetOutputSymbols(syms._table)             # <<<<<<<<<<<<<<
  * 
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_encoder");
-    __PYX_ERR(0, 1375, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
+    __PYX_ERR(0, 1439, __pyx_L1_error)
   }
-  __pyx_r = __pyx_v_self->_encoder.get()->WeightType();
-  goto __pyx_L0;
+  if (unlikely(((PyObject *)__pyx_v_syms) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
+    __PYX_ERR(0, 1439, __pyx_L1_error)
+  }
+  __pyx_v_self->_mapper.get()->SetOutputSymbols(__pyx_v_syms->_table);
 
-  /* "pywrapfst.pyx":1369
- *     self._encoder.get().SetOutputSymbols(syms._table)
+  /* "pywrapfst.pyx":1430
+ *     self._mapper.get().SetInputSymbols(syms._table)
  * 
- *   cpdef string weight_type(self):             # <<<<<<<<<<<<<<
+ *   cpdef void set_output_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
  *     """
- *     weight_type(self)
+ *     set_output_symbols(self, syms)
  */
 
   /* function exit code */
+  goto __pyx_L0;
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_WriteUnraisable("pywrapfst.EncodeMapper.weight_type", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
-  __Pyx_pretend_to_initialize(&__pyx_r);
+  __Pyx_AddTraceback("pywrapfst.EncodeMapper.set_output_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
-  return __pyx_r;
 }
 
 /* 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) {
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_31set_output_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms); /*proto*/
+static char __pyx_doc_9pywrapfst_12EncodeMapper_30set_output_symbols[] = "\n    set_output_symbols(self, syms)\n\n    Sets the mapper's output symbol table.\n\n    Args:\n      syms: A SymbolTable.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_31set_output_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("weight_type (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_20weight_type(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self));
+  __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, 1430, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_30set_output_symbols(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__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_12EncodeMapper_20weight_type(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_30set_output_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
-  __Pyx_RefNannySetupContext("weight_type", 0);
+  __Pyx_RefNannySetupContext("set_output_symbols", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_12EncodeMapper_weight_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1369, __pyx_L1_error)
+  __pyx_f_9pywrapfst_12EncodeMapper_set_output_symbols(__pyx_v_self, __pyx_v_syms, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1430, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1430, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -16095,7 +16819,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_20weight_type(struct __pyx_o
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.EncodeMapper.weight_type", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.EncodeMapper.set_output_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -16103,114 +16827,237 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_20weight_type(struct __pyx_o
   return __pyx_r;
 }
 
-/* "(tree fragment)":1
- * def __reduce_cython__(self):             # <<<<<<<<<<<<<<
- *     raise TypeError("self._encoder cannot be converted to a Python object for pickling")
- * def __setstate_cython__(self, __pyx_state):
+/* "pywrapfst.pyx":1442
+ * 
+ * 
+ * cdef EncodeMapper _init_EncodeMapper(fst.EncodeMapperClass *mapper):             # <<<<<<<<<<<<<<
+ *   cdef EncodeMapper result = EncodeMapper.__new__(EncodeMapper)
+ *   result._mapper.reset(mapper)
  */
 
-/* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_23__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_23__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
-  PyObject *__pyx_r = 0;
+static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__init_EncodeMapper(fst::script::EncodeMapperClass *__pyx_v_mapper) {
+  struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_result = 0;
+  struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_22__reduce_cython__(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self));
+  PyObject *__pyx_t_1 = NULL;
+  __Pyx_RefNannySetupContext("_init_EncodeMapper", 0);
+
+  /* "pywrapfst.pyx":1443
+ * 
+ * cdef EncodeMapper _init_EncodeMapper(fst.EncodeMapperClass *mapper):
+ *   cdef EncodeMapper result = EncodeMapper.__new__(EncodeMapper)             # <<<<<<<<<<<<<<
+ *   result._mapper.reset(mapper)
+ *   return result
+ */
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_EncodeMapper(((PyTypeObject *)__pyx_ptype_9pywrapfst_EncodeMapper), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1443, __pyx_L1_error)
+  __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+  __pyx_v_result = ((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "pywrapfst.pyx":1444
+ * cdef EncodeMapper _init_EncodeMapper(fst.EncodeMapperClass *mapper):
+ *   cdef EncodeMapper result = EncodeMapper.__new__(EncodeMapper)
+ *   result._mapper.reset(mapper)             # <<<<<<<<<<<<<<
+ *   return result
+ * 
+ */
+  if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
+    __PYX_ERR(0, 1444, __pyx_L1_error)
+  }
+  __pyx_v_result->_mapper.reset(__pyx_v_mapper);
+
+  /* "pywrapfst.pyx":1445
+ *   cdef EncodeMapper result = EncodeMapper.__new__(EncodeMapper)
+ *   result._mapper.reset(mapper)
+ *   return result             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(((PyObject *)__pyx_r));
+  __Pyx_INCREF(((PyObject *)__pyx_v_result));
+  __pyx_r = __pyx_v_result;
+  goto __pyx_L0;
+
+  /* "pywrapfst.pyx":1442
+ * 
+ * 
+ * cdef EncodeMapper _init_EncodeMapper(fst.EncodeMapperClass *mapper):             # <<<<<<<<<<<<<<
+ *   cdef EncodeMapper result = EncodeMapper.__new__(EncodeMapper)
+ *   result._mapper.reset(mapper)
+ */
 
   /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("pywrapfst._init_EncodeMapper", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_result);
+  __Pyx_XGIVEREF((PyObject *)__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_22__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self) {
-  PyObject *__pyx_r = NULL;
+/* "pywrapfst.pyx":1448
+ * 
+ * 
+ * cpdef EncodeMapper _read_EncodeMapper_from_string(state):             # <<<<<<<<<<<<<<
+ *   cdef stringstream sstrm
+ *   sstrm << tostring(state)
+ */
+
+static PyObject *__pyx_pw_9pywrapfst_15_read_EncodeMapper_from_string(PyObject *__pyx_self, PyObject *__pyx_v_state); /*proto*/
+static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__read_EncodeMapper_from_string(PyObject *__pyx_v_state, CYTHON_UNUSED int __pyx_skip_dispatch) {
+  std::stringstream __pyx_v_sstrm;
+  std::unique_ptr<fst::script::EncodeMapperClass>  __pyx_v_mapper;
+  struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  __Pyx_RefNannySetupContext("__reduce_cython__", 0);
+  std::string __pyx_t_1;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  __Pyx_RefNannySetupContext("_read_EncodeMapper_from_string", 0);
 
-  /* "(tree fragment)":2
- * def __reduce_cython__(self):
- *     raise TypeError("self._encoder cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
- * def __setstate_cython__(self, __pyx_state):
- *     raise TypeError("self._encoder cannot be converted to a Python object for pickling")
+  /* "pywrapfst.pyx":1450
+ * cpdef EncodeMapper _read_EncodeMapper_from_string(state):
+ *   cdef stringstream sstrm
+ *   sstrm << tostring(state)             # <<<<<<<<<<<<<<
+ *   cdef unique_ptr[fst.EncodeMapperClass] mapper
+ *   mapper.reset(fst.EncodeMapperClass.ReadStream(sstrm, b"<pywrapfst>"))
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_Raise(__pyx_t_1, 0, 0, 0);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __PYX_ERR(1, 2, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1450, __pyx_L1_error)
+  (void)((__pyx_v_sstrm << __pyx_t_1));
 
-  /* "(tree fragment)":1
- * def __reduce_cython__(self):             # <<<<<<<<<<<<<<
- *     raise TypeError("self._encoder cannot be converted to a Python object for pickling")
- * def __setstate_cython__(self, __pyx_state):
+  /* "pywrapfst.pyx":1452
+ *   sstrm << tostring(state)
+ *   cdef unique_ptr[fst.EncodeMapperClass] mapper
+ *   mapper.reset(fst.EncodeMapperClass.ReadStream(sstrm, b"<pywrapfst>"))             # <<<<<<<<<<<<<<
+ *   if mapper.get() == NULL:
+ *     raise FstIOError("Read failed")
+ */
+  __pyx_v_mapper.reset(fst::script::EncodeMapperClass::Read(__pyx_v_sstrm, __pyx_k_pywrapfst));
+
+  /* "pywrapfst.pyx":1453
+ *   cdef unique_ptr[fst.EncodeMapperClass] mapper
+ *   mapper.reset(fst.EncodeMapperClass.ReadStream(sstrm, b"<pywrapfst>"))
+ *   if mapper.get() == NULL:             # <<<<<<<<<<<<<<
+ *     raise FstIOError("Read failed")
+ *   return _init_EncodeMapper(mapper.release())
+ */
+  __pyx_t_2 = ((__pyx_v_mapper.get() == NULL) != 0);
+  if (unlikely(__pyx_t_2)) {
+
+    /* "pywrapfst.pyx":1454
+ *   mapper.reset(fst.EncodeMapperClass.ReadStream(sstrm, b"<pywrapfst>"))
+ *   if mapper.get() == NULL:
+ *     raise FstIOError("Read failed")             # <<<<<<<<<<<<<<
+ *   return _init_EncodeMapper(mapper.release())
+ * 
+ */
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1454, __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);
+      }
+    }
+    __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_kp_u_Read_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_kp_u_Read_failed);
+    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1454, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __PYX_ERR(0, 1454, __pyx_L1_error)
+
+    /* "pywrapfst.pyx":1453
+ *   cdef unique_ptr[fst.EncodeMapperClass] mapper
+ *   mapper.reset(fst.EncodeMapperClass.ReadStream(sstrm, b"<pywrapfst>"))
+ *   if mapper.get() == NULL:             # <<<<<<<<<<<<<<
+ *     raise FstIOError("Read failed")
+ *   return _init_EncodeMapper(mapper.release())
+ */
+  }
+
+  /* "pywrapfst.pyx":1455
+ *   if mapper.get() == NULL:
+ *     raise FstIOError("Read failed")
+ *   return _init_EncodeMapper(mapper.release())             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(((PyObject *)__pyx_r));
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_EncodeMapper(__pyx_v_mapper.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1455, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_t_3);
+  __pyx_t_3 = 0;
+  goto __pyx_L0;
+
+  /* "pywrapfst.pyx":1448
+ * 
+ * 
+ * cpdef EncodeMapper _read_EncodeMapper_from_string(state):             # <<<<<<<<<<<<<<
+ *   cdef stringstream sstrm
+ *   sstrm << tostring(state)
  */
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.EncodeMapper.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("pywrapfst._read_EncodeMapper_from_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF((PyObject *)__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "(tree fragment)":3
- * def __reduce_cython__(self):
- *     raise TypeError("self._encoder cannot be converted to a Python object for pickling")
- * def __setstate_cython__(self, __pyx_state):             # <<<<<<<<<<<<<<
- *     raise TypeError("self._encoder cannot be converted to a Python object for pickling")
- */
-
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_25__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_25__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) {
+static PyObject *__pyx_pw_9pywrapfst_15_read_EncodeMapper_from_string(PyObject *__pyx_self, PyObject *__pyx_v_state); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_15_read_EncodeMapper_from_string(PyObject *__pyx_self, PyObject *__pyx_v_state) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_24__setstate_cython__(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state));
+  __Pyx_RefNannySetupContext("_read_EncodeMapper_from_string (wrapper)", 0);
+  __pyx_r = __pyx_pf_9pywrapfst_14_read_EncodeMapper_from_string(__pyx_self, ((PyObject *)__pyx_v_state));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_24__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) {
+static PyObject *__pyx_pf_9pywrapfst_14_read_EncodeMapper_from_string(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_state) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
-  __Pyx_RefNannySetupContext("__setstate_cython__", 0);
-
-  /* "(tree fragment)":4
- *     raise TypeError("self._encoder cannot be converted to a Python object for pickling")
- * def __setstate_cython__(self, __pyx_state):
- *     raise TypeError("self._encoder cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
- */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __Pyx_RefNannySetupContext("_read_EncodeMapper_from_string", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_EncodeMapper_from_string(__pyx_v_state, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1448, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_Raise(__pyx_t_1, 0, 0, 0);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __PYX_ERR(1, 4, __pyx_L1_error)
-
-  /* "(tree fragment)":3
- * def __reduce_cython__(self):
- *     raise TypeError("self._encoder cannot be converted to a Python object for pickling")
- * def __setstate_cython__(self, __pyx_state):             # <<<<<<<<<<<<<<
- *     raise TypeError("self._encoder cannot be converted to a Python object for pickling")
- */
+  __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.EncodeMapper.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._read_EncodeMapper_from_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
+  __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1401
+/* "pywrapfst.pyx":1481
  * 
  *   @staticmethod
  *   cdef string _local_render_svg(const string &dot):             # <<<<<<<<<<<<<<
@@ -16229,77 +17076,77 @@ static std::string __pyx_f_9pywrapfst_4_Fst__local_render_svg(std::string const
   std::string __pyx_t_5;
   __Pyx_RefNannySetupContext("_local_render_svg", 0);
 
-  /* "pywrapfst.pyx":1402
+  /* "pywrapfst.pyx":1482
  *   @staticmethod
  *   cdef string _local_render_svg(const string &dot):
  *     proc = subprocess.Popen(("dot", "-Tsvg"),             # <<<<<<<<<<<<<<
  *                             stdin=subprocess.PIPE,
  *                             stdout=subprocess.PIPE)
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_subprocess); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1402, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_subprocess); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1482, __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, 1402, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_Popen); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1482, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1403
+  /* "pywrapfst.pyx":1483
  *   cdef string _local_render_svg(const string &dot):
  *     proc = subprocess.Popen(("dot", "-Tsvg"),
  *                             stdin=subprocess.PIPE,             # <<<<<<<<<<<<<<
  *                             stdout=subprocess.PIPE)
  *     return proc.communicate(dot.encode("utf8"))[0]
  */
-  __pyx_t_1 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1403, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1483, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_subprocess); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1403, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_subprocess); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1483, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_PIPE); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1403, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_PIPE); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1483, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_stdin, __pyx_t_4) < 0) __PYX_ERR(0, 1403, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_stdin, __pyx_t_4) < 0) __PYX_ERR(0, 1483, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":1404
+  /* "pywrapfst.pyx":1484
  *     proc = subprocess.Popen(("dot", "-Tsvg"),
  *                             stdin=subprocess.PIPE,
  *                             stdout=subprocess.PIPE)             # <<<<<<<<<<<<<<
  *     return proc.communicate(dot.encode("utf8"))[0]
  * 
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_subprocess); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1404, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_subprocess); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1484, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_PIPE); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1404, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_PIPE); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1484, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_stdout, __pyx_t_3) < 0) __PYX_ERR(0, 1403, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_stdout, __pyx_t_3) < 0) __PYX_ERR(0, 1483, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-  /* "pywrapfst.pyx":1402
+  /* "pywrapfst.pyx":1482
  *   @staticmethod
  *   cdef string _local_render_svg(const string &dot):
  *     proc = subprocess.Popen(("dot", "-Tsvg"),             # <<<<<<<<<<<<<<
  *                             stdin=subprocess.PIPE,
  *                             stdout=subprocess.PIPE)
  */
-  __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__9, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1402, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__7, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1482, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_v_proc = __pyx_t_3;
   __pyx_t_3 = 0;
 
-  /* "pywrapfst.pyx":1405
+  /* "pywrapfst.pyx":1485
  *                             stdin=subprocess.PIPE,
  *                             stdout=subprocess.PIPE)
  *     return proc.communicate(dot.encode("utf8"))[0]             # <<<<<<<<<<<<<<
  * 
  *   def _repr_svg_(self):
  */
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_proc, __pyx_n_s_communicate); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1405, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_proc, __pyx_n_s_communicate); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1485, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_dot); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1405, __pyx_L1_error)
+  __pyx_t_2 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_dot); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1485, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = PyUnicode_AsUTF8String(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1405, __pyx_L1_error)
+  __pyx_t_4 = PyUnicode_AsUTF8String(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1485, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __pyx_t_2 = NULL;
@@ -16315,22 +17162,22 @@ static std::string __pyx_f_9pywrapfst_4_Fst__local_render_svg(std::string const
   __pyx_t_3 = (__pyx_t_2) ? __Pyx_PyObject_Call2Args(__pyx_t_1, __pyx_t_2, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_4);
   __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1405, __pyx_L1_error)
+  if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1485, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   if (unlikely(__pyx_t_3 == Py_None)) {
     PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
-    __PYX_ERR(0, 1405, __pyx_L1_error)
+    __PYX_ERR(0, 1485, __pyx_L1_error)
   }
-  __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_3, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1405, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_3, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1485, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1405, __pyx_L1_error)
+  __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1485, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_5;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1401
+  /* "pywrapfst.pyx":1481
  * 
  *   @staticmethod
  *   cdef string _local_render_svg(const string &dot):             # <<<<<<<<<<<<<<
@@ -16352,7 +17199,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst__local_render_svg(std::string const
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1407
+/* "pywrapfst.pyx":1487
  *     return proc.communicate(dot.encode("utf8"))[0]
  * 
  *   def _repr_svg_(self):             # <<<<<<<<<<<<<<
@@ -16362,7 +17209,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst__local_render_svg(std::string const
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_1_repr_svg_(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst__repr_svg_[] = "IPython notebook magic to produce an SVG of the FST using GraphViz.\n\n    This method produces an SVG of the internal graph. Users wishing to create\n    publication-quality graphs should instead use the method `draw`, which\n    exposes additional parameters.\n\n    See also: `draw`, `text`.\n    ";
+static char __pyx_doc_9pywrapfst_4_Fst__repr_svg_[] = "IPython notebook magic to produce an SVG of the FST using GraphViz.\n\n    This method produces an SVG of the internal graph. Users wishing to create\n    publication-quality graphs should instead use the method `draw`, which\n    exposes additional parameters.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_1_repr_svg_(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -16401,67 +17248,67 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_t_19 = NULL;
   __Pyx_RefNannySetupContext("_repr_svg_", 0);
 
-  /* "pywrapfst.pyx":1417
+  /* "pywrapfst.pyx":1495
  *     """
  *     cdef stringstream sstrm
  *     cdef bool acceptor = (self._fst.get().Properties(fst.kAcceptor, True) ==             # <<<<<<<<<<<<<<
  *                           fst.kAcceptor)
- *     fst.DrawFst(deref(self._fst), self._fst.get().InputSymbols(),
+ *     fst.Draw(deref(self._fst), self._fst.get().InputSymbols(),
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1417, __pyx_L1_error)
+    __PYX_ERR(0, 1495, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1418
+  /* "pywrapfst.pyx":1496
  *     cdef stringstream sstrm
  *     cdef bool acceptor = (self._fst.get().Properties(fst.kAcceptor, True) ==
  *                           fst.kAcceptor)             # <<<<<<<<<<<<<<
- *     fst.DrawFst(deref(self._fst), self._fst.get().InputSymbols(),
- *                 self._fst.get().OutputSymbols(), NULL, acceptor,
+ *     fst.Draw(deref(self._fst), self._fst.get().InputSymbols(),
+ *              self._fst.get().OutputSymbols(), NULL, acceptor, b"", 8.5, 11,
  */
   __pyx_v_acceptor = (__pyx_v_self->_fst.get()->Properties(fst::kAcceptor, 1) == fst::kAcceptor);
 
-  /* "pywrapfst.pyx":1419
+  /* "pywrapfst.pyx":1497
  *     cdef bool acceptor = (self._fst.get().Properties(fst.kAcceptor, True) ==
  *                           fst.kAcceptor)
- *     fst.DrawFst(deref(self._fst), self._fst.get().InputSymbols(),             # <<<<<<<<<<<<<<
- *                 self._fst.get().OutputSymbols(), NULL, acceptor,
- *                 b"", 8.5, 11, True, False, 0.4, 0.25, 14, 5, b"g", False,
+ *     fst.Draw(deref(self._fst), self._fst.get().InputSymbols(),             # <<<<<<<<<<<<<<
+ *              self._fst.get().OutputSymbols(), NULL, acceptor, b"", 8.5, 11,
+ *              True, False, 0.4, 0.25, 14, 5, b"g", False, sstrm,
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1419, __pyx_L1_error)
+    __PYX_ERR(0, 1497, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1419, __pyx_L1_error)
+    __PYX_ERR(0, 1497, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1420
+  /* "pywrapfst.pyx":1498
  *                           fst.kAcceptor)
- *     fst.DrawFst(deref(self._fst), self._fst.get().InputSymbols(),
- *                 self._fst.get().OutputSymbols(), NULL, acceptor,             # <<<<<<<<<<<<<<
- *                 b"", 8.5, 11, True, False, 0.4, 0.25, 14, 5, b"g", False,
- *                 addr(sstrm), b"<pywrapfst>")
+ *     fst.Draw(deref(self._fst), self._fst.get().InputSymbols(),
+ *              self._fst.get().OutputSymbols(), NULL, acceptor, b"", 8.5, 11,             # <<<<<<<<<<<<<<
+ *              True, False, 0.4, 0.25, 14, 5, b"g", False, sstrm,
+ *              b"<pywrapfst>")
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1420, __pyx_L1_error)
+    __PYX_ERR(0, 1498, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1419
+  /* "pywrapfst.pyx":1497
  *     cdef bool acceptor = (self._fst.get().Properties(fst.kAcceptor, True) ==
  *                           fst.kAcceptor)
- *     fst.DrawFst(deref(self._fst), self._fst.get().InputSymbols(),             # <<<<<<<<<<<<<<
- *                 self._fst.get().OutputSymbols(), NULL, acceptor,
- *                 b"", 8.5, 11, True, False, 0.4, 0.25, 14, 5, b"g", False,
+ *     fst.Draw(deref(self._fst), self._fst.get().InputSymbols(),             # <<<<<<<<<<<<<<
+ *              self._fst.get().OutputSymbols(), NULL, acceptor, b"", 8.5, 11,
+ *              True, False, 0.4, 0.25, 14, 5, b"g", False, sstrm,
  */
-  fst::script::DrawFst((*__pyx_v_self->_fst), __pyx_v_self->_fst.get()->InputSymbols(), __pyx_v_self->_fst.get()->OutputSymbols(), NULL, __pyx_v_acceptor, __pyx_k__10, 8.5, 11.0, 1, 0, 0.4, 0.25, 14, 5, __pyx_k_g, 0, (&__pyx_v_sstrm), __pyx_k_pywrapfst);
+  fst::script::Draw((*__pyx_v_self->_fst), __pyx_v_self->_fst.get()->InputSymbols(), __pyx_v_self->_fst.get()->OutputSymbols(), NULL, __pyx_v_acceptor, __pyx_k__8, 8.5, 11.0, 1, 0, 0.4, 0.25, 14, 5, __pyx_k_g, 0, __pyx_v_sstrm, __pyx_k_pywrapfst);
 
-  /* "pywrapfst.pyx":1423
- *                 b"", 8.5, 11, True, False, 0.4, 0.25, 14, 5, b"g", False,
- *                 addr(sstrm), b"<pywrapfst>")
+  /* "pywrapfst.pyx":1501
+ *              True, False, 0.4, 0.25, 14, 5, b"g", False, sstrm,
+ *              b"<pywrapfst>")
  *     try:             # <<<<<<<<<<<<<<
  *       return _Fst._local_render_svg(sstrm.str())
  *     except Exception as e:
@@ -16475,23 +17322,23 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
     __Pyx_XGOTREF(__pyx_t_3);
     /*try:*/ {
 
-      /* "pywrapfst.pyx":1424
- *                 addr(sstrm), b"<pywrapfst>")
+      /* "pywrapfst.pyx":1502
+ *              b"<pywrapfst>")
  *     try:
  *       return _Fst._local_render_svg(sstrm.str())             # <<<<<<<<<<<<<<
  *     except Exception as e:
  *       logging.error("Dot rendering failed: %s", e)
  */
       __Pyx_XDECREF(__pyx_r);
-      __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_4_Fst__local_render_svg(__pyx_v_sstrm.str())); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1424, __pyx_L3_error)
+      __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_4_Fst__local_render_svg(__pyx_v_sstrm.str())); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1502, __pyx_L3_error)
       __Pyx_GOTREF(__pyx_t_4);
       __pyx_r = __pyx_t_4;
       __pyx_t_4 = 0;
       goto __pyx_L7_try_return;
 
-      /* "pywrapfst.pyx":1423
- *                 b"", 8.5, 11, True, False, 0.4, 0.25, 14, 5, b"g", False,
- *                 addr(sstrm), b"<pywrapfst>")
+      /* "pywrapfst.pyx":1501
+ *              True, False, 0.4, 0.25, 14, 5, b"g", False, sstrm,
+ *              b"<pywrapfst>")
  *     try:             # <<<<<<<<<<<<<<
  *       return _Fst._local_render_svg(sstrm.str())
  *     except Exception as e:
@@ -16500,7 +17347,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
     __pyx_L3_error:;
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-    /* "pywrapfst.pyx":1425
+    /* "pywrapfst.pyx":1503
  *     try:
  *       return _Fst._local_render_svg(sstrm.str())
  *     except Exception as e:             # <<<<<<<<<<<<<<
@@ -16510,7 +17357,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
     __pyx_t_5 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
     if (__pyx_t_5) {
       __Pyx_AddTraceback("pywrapfst._Fst._repr_svg_", __pyx_clineno, __pyx_lineno, __pyx_filename);
-      if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(0, 1425, __pyx_L5_except_error)
+      if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(0, 1503, __pyx_L5_except_error)
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_GOTREF(__pyx_t_6);
       __Pyx_GOTREF(__pyx_t_7);
@@ -16518,16 +17365,16 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
       __pyx_v_e = __pyx_t_6;
       /*try:*/ {
 
-        /* "pywrapfst.pyx":1426
+        /* "pywrapfst.pyx":1504
  *       return _Fst._local_render_svg(sstrm.str())
  *     except Exception as e:
  *       logging.error("Dot rendering failed: %s", e)             # <<<<<<<<<<<<<<
  * 
  *   def __init__(self):
  */
-        __Pyx_GetModuleGlobalName(__pyx_t_9, __pyx_n_s_logging); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1426, __pyx_L14_error)
+        __Pyx_GetModuleGlobalName(__pyx_t_9, __pyx_n_s_logging); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1504, __pyx_L14_error)
         __Pyx_GOTREF(__pyx_t_9);
-        __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_error); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1426, __pyx_L14_error)
+        __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_error); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1504, __pyx_L14_error)
         __Pyx_GOTREF(__pyx_t_10);
         __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
         __pyx_t_9 = NULL;
@@ -16545,7 +17392,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_10)) {
           PyObject *__pyx_temp[3] = {__pyx_t_9, __pyx_kp_u_Dot_rendering_failed_s, __pyx_v_e};
-          __pyx_t_8 = __Pyx_PyFunction_FastCall(__pyx_t_10, __pyx_temp+1-__pyx_t_5, 2+__pyx_t_5); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1426, __pyx_L14_error)
+          __pyx_t_8 = __Pyx_PyFunction_FastCall(__pyx_t_10, __pyx_temp+1-__pyx_t_5, 2+__pyx_t_5); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1504, __pyx_L14_error)
           __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
           __Pyx_GOTREF(__pyx_t_8);
         } else
@@ -16553,13 +17400,13 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_10)) {
           PyObject *__pyx_temp[3] = {__pyx_t_9, __pyx_kp_u_Dot_rendering_failed_s, __pyx_v_e};
-          __pyx_t_8 = __Pyx_PyCFunction_FastCall(__pyx_t_10, __pyx_temp+1-__pyx_t_5, 2+__pyx_t_5); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1426, __pyx_L14_error)
+          __pyx_t_8 = __Pyx_PyCFunction_FastCall(__pyx_t_10, __pyx_temp+1-__pyx_t_5, 2+__pyx_t_5); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1504, __pyx_L14_error)
           __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
           __Pyx_GOTREF(__pyx_t_8);
         } else
         #endif
         {
-          __pyx_t_11 = PyTuple_New(2+__pyx_t_5); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1426, __pyx_L14_error)
+          __pyx_t_11 = PyTuple_New(2+__pyx_t_5); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1504, __pyx_L14_error)
           __Pyx_GOTREF(__pyx_t_11);
           if (__pyx_t_9) {
             __Pyx_GIVEREF(__pyx_t_9); PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_9); __pyx_t_9 = NULL;
@@ -16570,7 +17417,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
           __Pyx_INCREF(__pyx_v_e);
           __Pyx_GIVEREF(__pyx_v_e);
           PyTuple_SET_ITEM(__pyx_t_11, 1+__pyx_t_5, __pyx_v_e);
-          __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_11, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1426, __pyx_L14_error)
+          __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_11, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1504, __pyx_L14_error)
           __Pyx_GOTREF(__pyx_t_8);
           __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
         }
@@ -16578,7 +17425,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
 
-      /* "pywrapfst.pyx":1425
+      /* "pywrapfst.pyx":1503
  *     try:
  *       return _Fst._local_render_svg(sstrm.str())
  *     except Exception as e:             # <<<<<<<<<<<<<<
@@ -16637,9 +17484,9 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
     goto __pyx_L5_except_error;
     __pyx_L5_except_error:;
 
-    /* "pywrapfst.pyx":1423
- *                 b"", 8.5, 11, True, False, 0.4, 0.25, 14, 5, b"g", False,
- *                 addr(sstrm), b"<pywrapfst>")
+    /* "pywrapfst.pyx":1501
+ *              True, False, 0.4, 0.25, 14, 5, b"g", False, sstrm,
+ *              b"<pywrapfst>")
  *     try:             # <<<<<<<<<<<<<<
  *       return _Fst._local_render_svg(sstrm.str())
  *     except Exception as e:
@@ -16662,7 +17509,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
     __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3);
   }
 
-  /* "pywrapfst.pyx":1407
+  /* "pywrapfst.pyx":1487
  *     return proc.communicate(dot.encode("utf8"))[0]
  * 
  *   def _repr_svg_(self):             # <<<<<<<<<<<<<<
@@ -16690,7 +17537,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1428
+/* "pywrapfst.pyx":1506
  *       logging.error("Dot rendering failed: %s", e)
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -16725,28 +17572,28 @@ static int __pyx_pf_9pywrapfst_4_Fst_2__init__(struct __pyx_obj_9pywrapfst__Fst
   PyObject *__pyx_t_6 = NULL;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":1429
+  /* "pywrapfst.pyx":1507
  * 
  *   def __init__(self):
  *     raise FstDeletedConstructorError(             # <<<<<<<<<<<<<<
  *         "Cannot construct {}".format(self.__class__.__name__))
  * 
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstDeletedConstructorError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1429, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstDeletedConstructorError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1507, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":1430
+  /* "pywrapfst.pyx":1508
  *   def __init__(self):
  *     raise FstDeletedConstructorError(
  *         "Cannot construct {}".format(self.__class__.__name__))             # <<<<<<<<<<<<<<
  * 
  *   # Registers the class for pickling; must be repeated in any subclass which
  */
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Cannot_construct, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1430, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Cannot_construct, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1508, __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, 1430, __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, 1508, __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, 1430, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_name); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1508, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_t_5 = NULL;
@@ -16762,7 +17609,7 @@ static int __pyx_pf_9pywrapfst_4_Fst_2__init__(struct __pyx_obj_9pywrapfst__Fst
   __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6);
   __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1430, __pyx_L1_error)
+  if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1508, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_4 = NULL;
@@ -16778,14 +17625,14 @@ static int __pyx_pf_9pywrapfst_4_Fst_2__init__(struct __pyx_obj_9pywrapfst__Fst
   __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1429, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1507, __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, 1429, __pyx_L1_error)
+  __PYX_ERR(0, 1507, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1428
+  /* "pywrapfst.pyx":1506
  *       logging.error("Dot rendering failed: %s", e)
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -16807,7 +17654,7 @@ static int __pyx_pf_9pywrapfst_4_Fst_2__init__(struct __pyx_obj_9pywrapfst__Fst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1435
+/* "pywrapfst.pyx":1513
  *   # can't be derived by _init_XFst.
  * 
  *   def __reduce__(self):             # <<<<<<<<<<<<<<
@@ -16836,7 +17683,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_4__reduce__(struct __pyx_obj_9pywrapf
   PyObject *__pyx_t_3 = NULL;
   __Pyx_RefNannySetupContext("__reduce__", 0);
 
-  /* "pywrapfst.pyx":1436
+  /* "pywrapfst.pyx":1514
  * 
  *   def __reduce__(self):
  *     return (_read_Fst_from_string, (self.write_to_string(),))             # <<<<<<<<<<<<<<
@@ -16844,20 +17691,20 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_4__reduce__(struct __pyx_obj_9pywrapf
  *   def __repr__(self):
  */
   __Pyx_XDECREF(__pyx_r);
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_read_Fst_from_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1436, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_read_Fst_from_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1514, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "write_to_string");
-    __PYX_ERR(0, 1436, __pyx_L1_error)
+    __PYX_ERR(0, 1514, __pyx_L1_error)
   }
-  __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_self->__pyx_vtab)->write_to_string(__pyx_v_self, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1436, __pyx_L1_error)
+  __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_self->__pyx_vtab)->write_to_string(__pyx_v_self, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1514, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1436, __pyx_L1_error)
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1514, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_GIVEREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
   __pyx_t_2 = 0;
-  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1436, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1514, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
@@ -16869,7 +17716,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_4__reduce__(struct __pyx_obj_9pywrapf
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1435
+  /* "pywrapfst.pyx":1513
  *   # can't be derived by _init_XFst.
  * 
  *   def __reduce__(self):             # <<<<<<<<<<<<<<
@@ -16890,7 +17737,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_4__reduce__(struct __pyx_obj_9pywrapf
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1438
+/* "pywrapfst.pyx":1516
  *     return (_read_Fst_from_string, (self.write_to_string(),))
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -16923,7 +17770,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_6__repr__(struct __pyx_obj_9pywrapfst
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":1439
+  /* "pywrapfst.pyx":1517
  * 
  *   def __repr__(self):
  *     return "<{} Fst at 0x{:x}>".format(self.fst_type(), id(self))             # <<<<<<<<<<<<<<
@@ -16931,15 +17778,15 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_6__repr__(struct __pyx_obj_9pywrapfst
  *   def __str__(self):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Fst_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1439, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Fst_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1517, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "fst_type");
-    __PYX_ERR(0, 1439, __pyx_L1_error)
+    __PYX_ERR(0, 1517, __pyx_L1_error)
   }
-  __pyx_t_3 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_self->__pyx_vtab)->fst_type(__pyx_v_self, 0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1439, __pyx_L1_error)
+  __pyx_t_3 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_self->__pyx_vtab)->fst_type(__pyx_v_self, 0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1517, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1439, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1517, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __pyx_t_5 = NULL;
   __pyx_t_6 = 0;
@@ -16956,7 +17803,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_6__repr__(struct __pyx_obj_9pywrapfst
   #if CYTHON_FAST_PYCALL
   if (PyFunction_Check(__pyx_t_2)) {
     PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_t_3, __pyx_t_4};
-    __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1439, __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, 1517, __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;
@@ -16966,7 +17813,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_6__repr__(struct __pyx_obj_9pywrapfst
   #if CYTHON_FAST_PYCCALL
   if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
     PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_t_3, __pyx_t_4};
-    __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1439, __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, 1517, __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;
@@ -16974,7 +17821,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_6__repr__(struct __pyx_obj_9pywrapfst
   } else
   #endif
   {
-    __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1439, __pyx_L1_error)
+    __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1517, __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;
@@ -16985,7 +17832,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_6__repr__(struct __pyx_obj_9pywrapfst
     PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_4);
     __pyx_t_3 = 0;
     __pyx_t_4 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1439, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1517, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
   }
@@ -16994,7 +17841,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_6__repr__(struct __pyx_obj_9pywrapfst
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1438
+  /* "pywrapfst.pyx":1516
  *     return (_read_Fst_from_string, (self.write_to_string(),))
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -17018,7 +17865,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_6__repr__(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1441
+/* "pywrapfst.pyx":1519
  *     return "<{} Fst at 0x{:x}>".format(self.fst_type(), id(self))
  * 
  *   def __str__(self):             # <<<<<<<<<<<<<<
@@ -17045,7 +17892,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_8__str__(struct __pyx_obj_9pywrapfst_
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("__str__", 0);
 
-  /* "pywrapfst.pyx":1442
+  /* "pywrapfst.pyx":1520
  * 
  *   def __str__(self):
  *     return self.text()             # <<<<<<<<<<<<<<
@@ -17055,15 +17902,15 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_8__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 '%.30s'", "text");
-    __PYX_ERR(0, 1442, __pyx_L1_error)
+    __PYX_ERR(0, 1520, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_self->__pyx_vtab)->text(__pyx_v_self, 0, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1442, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_self->__pyx_vtab)->text(__pyx_v_self, 0, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1520, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1441
+  /* "pywrapfst.pyx":1519
  *     return "<{} Fst at 0x{:x}>".format(self.fst_type(), id(self))
  * 
  *   def __str__(self):             # <<<<<<<<<<<<<<
@@ -17082,7 +17929,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_8__str__(struct __pyx_obj_9pywrapfst_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1444
+/* "pywrapfst.pyx":1522
  *     return self.text()
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
@@ -17109,7 +17956,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_arc_type(struct __pyx_obj_9pywrapfst
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1444, __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, 1522, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_4_Fst_11arc_type)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -17125,10 +17972,10 @@ static std::string __pyx_f_9pywrapfst_4_Fst_arc_type(struct __pyx_obj_9pywrapfst
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1444, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1522, __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, 1444, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1522, __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;
@@ -17147,7 +17994,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_arc_type(struct __pyx_obj_9pywrapfst
     #endif
   }
 
-  /* "pywrapfst.pyx":1450
+  /* "pywrapfst.pyx":1528
  *     Returns a string indicating the arc type.
  *     """
  *     return self._fst.get().ArcType()             # <<<<<<<<<<<<<<
@@ -17156,12 +18003,12 @@ static std::string __pyx_f_9pywrapfst_4_Fst_arc_type(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1450, __pyx_L1_error)
+    __PYX_ERR(0, 1528, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_fst.get()->ArcType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1444
+  /* "pywrapfst.pyx":1522
  *     return self.text()
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
@@ -17202,7 +18049,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_10arc_type(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("arc_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_4_Fst_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1444, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_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, 1522, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -17219,7 +18066,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_10arc_type(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1452
+/* "pywrapfst.pyx":1530
  *     return self._fst.get().ArcType()
  * 
  *   cpdef ArcIterator arcs(self, int64 state):             # <<<<<<<<<<<<<<
@@ -17246,11 +18093,11 @@ static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_4_Fst_arcs(st
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arcs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1452, __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, 1530, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_4_Fst_13arcs)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
-        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1452, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1530, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -17266,10 +18113,10 @@ static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_4_Fst_arcs(st
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1452, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1530, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_ArcIterator))))) __PYX_ERR(0, 1452, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_ArcIterator))))) __PYX_ERR(0, 1530, __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;
@@ -17288,17 +18135,17 @@ static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_4_Fst_arcs(st
     #endif
   }
 
-  /* "pywrapfst.pyx":1466
- *     See also: `mutable_arcs`, `states`.
+  /* "pywrapfst.pyx":1542
+ *       An ArcIterator.
  *     """
  *     return ArcIterator(self, state)             # <<<<<<<<<<<<<<
  * 
  *   cpdef _Fst copy(self):
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1466, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1542, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1466, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1542, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
@@ -17306,14 +18153,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, 1466, __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, 1542, __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":1452
+  /* "pywrapfst.pyx":1530
  *     return self._fst.get().ArcType()
  * 
  *   cpdef ArcIterator arcs(self, int64 state):             # <<<<<<<<<<<<<<
@@ -17338,14 +18185,14 @@ static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_4_Fst_arcs(st
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_13arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_12arcs[] = "\n    arcs(self, state)\n\n    Returns an iterator over arcs leaving the specified state.\n\n    Args:\n      state: The source state ID.\n\n    Returns:\n      An ArcIterator.\n\n    See also: `mutable_arcs`, `states`.\n    ";
+static char __pyx_doc_9pywrapfst_4_Fst_12arcs[] = "\n    arcs(self, state)\n\n    Returns an iterator over arcs leaving the specified state.\n\n    Args:\n      state: The source state ID.\n\n    Returns:\n      An ArcIterator.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_13arcs(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, 1452, __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, 1530, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -17366,7 +18213,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_12arcs(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, 1452, __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, 1530, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -17383,7 +18230,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_12arcs(struct __pyx_obj_9pywrapfst__F
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1468
+/* "pywrapfst.pyx":1544
  *     return ArcIterator(self, state)
  * 
  *   cpdef _Fst copy(self):             # <<<<<<<<<<<<<<
@@ -17409,7 +18256,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_4_Fst_copy(struct __
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_copy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1468, __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, 1544, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_4_Fst_15copy)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -17426,10 +18273,10 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_4_Fst_copy(struct __
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1468, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1544, __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, 1468, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__Fst))))) __PYX_ERR(0, 1544, __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;
@@ -17448,7 +18295,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_4_Fst_copy(struct __
     #endif
   }
 
-  /* "pywrapfst.pyx":1474
+  /* "pywrapfst.pyx":1550
  *     Makes a copy of the FST.
  *     """
  *     return _init_XFst(new fst.FstClass(deref(self._fst)))             # <<<<<<<<<<<<<<
@@ -17458,15 +18305,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 '%.30s'", "_fst");
-    __PYX_ERR(0, 1474, __pyx_L1_error)
+    __PYX_ERR(0, 1550, __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, 1474, __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, 1550, __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":1468
+  /* "pywrapfst.pyx":1544
  *     return ArcIterator(self, state)
  * 
  *   cpdef _Fst copy(self):             # <<<<<<<<<<<<<<
@@ -17508,7 +18355,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_14copy(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, 1468, __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, 1544, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -17525,57 +18372,57 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_14copy(struct __pyx_obj_9pywrapfst__F
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1476
+/* "pywrapfst.pyx":1552
  *     return _init_XFst(new fst.FstClass(deref(self._fst)))
  * 
  *   cpdef void draw(self,             # <<<<<<<<<<<<<<
- *                   filename,
+ *                   source,
  *                   _SymbolTable isymbols=None,
  */
 
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_17draw(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) {
+static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_4_Fst_draw *__pyx_optional_args) {
 
-  /* "pywrapfst.pyx":1478
+  /* "pywrapfst.pyx":1554
  *   cpdef void draw(self,
- *                   filename,
+ *                   source,
  *                   _SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
  *                   _SymbolTable osymbols=None,
- *                   SymbolTable ssymbols=None,
+ *                   _SymbolTable ssymbols=None,
  */
   struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_isymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
 
-  /* "pywrapfst.pyx":1479
- *                   filename,
+  /* "pywrapfst.pyx":1555
+ *                   source,
  *                   _SymbolTable isymbols=None,
  *                   _SymbolTable osymbols=None,             # <<<<<<<<<<<<<<
- *                   SymbolTable ssymbols=None,
+ *                   _SymbolTable ssymbols=None,
  *                   bool acceptor=False,
  */
   struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_osymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
 
-  /* "pywrapfst.pyx":1480
+  /* "pywrapfst.pyx":1556
  *                   _SymbolTable isymbols=None,
  *                   _SymbolTable osymbols=None,
- *                   SymbolTable ssymbols=None,             # <<<<<<<<<<<<<<
+ *                   _SymbolTable ssymbols=None,             # <<<<<<<<<<<<<<
  *                   bool acceptor=False,
  *                   title=b"",
  */
-  struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v_ssymbols = ((struct __pyx_obj_9pywrapfst_SymbolTable *)Py_None);
+  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_ssymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
 
-  /* "pywrapfst.pyx":1481
+  /* "pywrapfst.pyx":1557
  *                   _SymbolTable osymbols=None,
- *                   SymbolTable ssymbols=None,
+ *                   _SymbolTable ssymbols=None,
  *                   bool acceptor=False,             # <<<<<<<<<<<<<<
  *                   title=b"",
  *                   double width=8.5,
  */
   bool __pyx_v_acceptor = ((bool)0);
-  PyObject *__pyx_v_title = ((PyObject *)__pyx_kp_b__10);
+  PyObject *__pyx_v_title = ((PyObject *)__pyx_kp_b__8);
   double __pyx_v_width = ((double)8.5);
   double __pyx_v_height = ((double)11.0);
 
-  /* "pywrapfst.pyx":1485
+  /* "pywrapfst.pyx":1561
  *                   double width=8.5,
  *                   double height=11,
  *                   bool portrait=False,             # <<<<<<<<<<<<<<
@@ -17584,7 +18431,7 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
  */
   bool __pyx_v_portrait = ((bool)0);
 
-  /* "pywrapfst.pyx":1486
+  /* "pywrapfst.pyx":1562
  *                   double height=11,
  *                   bool portrait=False,
  *                   bool vertical=False,             # <<<<<<<<<<<<<<
@@ -17598,17 +18445,19 @@ 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":1492
+  /* "pywrapfst.pyx":1568
  *                   int32 precision=5,
  *                   float_format=b"g",
  *                   bool show_weight_one=False):             # <<<<<<<<<<<<<<
  *     """
- *     draw(self, filename, isymbols=None, osymbols=None, ssymbols=None,
+ *     draw(self, source, isymbols=None, osymbols=None, ssymbols=None,
  */
   bool __pyx_v_show_weight_one = ((bool)0);
-  std::string __pyx_v_filename_string;
-  std::unique_ptr<std::ofstream>  __pyx_v_ostrm;
-  fst::SymbolTable *__pyx_v_ssymbols_ptr;
+  std::string __pyx_v_source_string;
+  std::unique_ptr<std::ostream>  __pyx_v_fstrm;
+  fst::SymbolTable const *__pyx_v__isymbols;
+  fst::SymbolTable const *__pyx_v__osymbols;
+  fst::SymbolTable *__pyx_v__ssymbols;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -17630,9 +18479,7 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
   int __pyx_t_18;
   int __pyx_t_19;
   fst::SymbolTable *__pyx_t_20;
-  fst::SymbolTable const *__pyx_t_21;
-  fst::SymbolTable const *__pyx_t_22;
-  std::string __pyx_t_23;
+  std::string __pyx_t_21;
   __Pyx_RefNannySetupContext("draw", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -17682,11 +18529,11 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
     }
   }
 
-  /* "pywrapfst.pyx":1476
+  /* "pywrapfst.pyx":1552
  *     return _init_XFst(new fst.FstClass(deref(self._fst)))
  * 
  *   cpdef void draw(self,             # <<<<<<<<<<<<<<
- *                   filename,
+ *                   source,
  *                   _SymbolTable isymbols=None,
  */
   /* Check if called by wrapper */
@@ -17698,28 +18545,28 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_draw); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1476, __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, 1552, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_4_Fst_17draw)) {
-        __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_v_acceptor); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1476, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_v_acceptor); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1552, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
-        __pyx_t_4 = PyFloat_FromDouble(__pyx_v_width); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1476, __pyx_L1_error)
+        __pyx_t_4 = PyFloat_FromDouble(__pyx_v_width); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1552, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
-        __pyx_t_5 = PyFloat_FromDouble(__pyx_v_height); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1476, __pyx_L1_error)
+        __pyx_t_5 = PyFloat_FromDouble(__pyx_v_height); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1552, __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, 1476, __pyx_L1_error)
+        __pyx_t_6 = __Pyx_PyBool_FromLong(__pyx_v_portrait); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1552, __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, 1476, __pyx_L1_error)
+        __pyx_t_7 = __Pyx_PyBool_FromLong(__pyx_v_vertical); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1552, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_7);
-        __pyx_t_8 = PyFloat_FromDouble(__pyx_v_ranksep); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1476, __pyx_L1_error)
+        __pyx_t_8 = PyFloat_FromDouble(__pyx_v_ranksep); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1552, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
-        __pyx_t_9 = PyFloat_FromDouble(__pyx_v_nodesep); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1476, __pyx_L1_error)
+        __pyx_t_9 = PyFloat_FromDouble(__pyx_v_nodesep); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1552, __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, 1476, __pyx_L1_error)
+        __pyx_t_10 = __Pyx_PyInt_From_int32_t(__pyx_v_fontsize); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1552, __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, 1476, __pyx_L1_error)
+        __pyx_t_11 = __Pyx_PyInt_From_int32_t(__pyx_v_precision); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1552, __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, 1476, __pyx_L1_error)
+        __pyx_t_12 = __Pyx_PyBool_FromLong(__pyx_v_show_weight_one); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 1552, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_12);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_13 = __pyx_t_1; __pyx_t_14 = NULL;
@@ -17736,8 +18583,8 @@ 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, 1476, __pyx_L1_error)
+          PyObject *__pyx_temp[17] = {__pyx_t_14, __pyx_v_source, ((PyObject *)__pyx_v_isymbols), ((PyObject *)__pyx_v_osymbols), ((PyObject *)__pyx_v_ssymbols), __pyx_t_3, __pyx_v_title, __pyx_t_4, __pyx_t_5, __pyx_t_6, __pyx_t_7, __pyx_t_8, __pyx_t_9, __pyx_t_10, __pyx_t_11, __pyx_v_float_format, __pyx_t_12};
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_13, __pyx_temp+1-__pyx_t_15, 16+__pyx_t_15); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1552, __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;
@@ -17754,8 +18601,8 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
         #endif
         #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, 1476, __pyx_L1_error)
+          PyObject *__pyx_temp[17] = {__pyx_t_14, __pyx_v_source, ((PyObject *)__pyx_v_isymbols), ((PyObject *)__pyx_v_osymbols), ((PyObject *)__pyx_v_ssymbols), __pyx_t_3, __pyx_v_title, __pyx_t_4, __pyx_t_5, __pyx_t_6, __pyx_t_7, __pyx_t_8, __pyx_t_9, __pyx_t_10, __pyx_t_11, __pyx_v_float_format, __pyx_t_12};
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_13, __pyx_temp+1-__pyx_t_15, 16+__pyx_t_15); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1552, __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;
@@ -17771,14 +18618,14 @@ 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, 1476, __pyx_L1_error)
+          __pyx_t_16 = PyTuple_New(16+__pyx_t_15); if (unlikely(!__pyx_t_16)) __PYX_ERR(0, 1552, __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;
           }
-          __Pyx_INCREF(__pyx_v_filename);
-          __Pyx_GIVEREF(__pyx_v_filename);
-          PyTuple_SET_ITEM(__pyx_t_16, 0+__pyx_t_15, __pyx_v_filename);
+          __Pyx_INCREF(__pyx_v_source);
+          __Pyx_GIVEREF(__pyx_v_source);
+          PyTuple_SET_ITEM(__pyx_t_16, 0+__pyx_t_15, __pyx_v_source);
           __Pyx_INCREF(((PyObject *)__pyx_v_isymbols));
           __Pyx_GIVEREF(((PyObject *)__pyx_v_isymbols));
           PyTuple_SET_ITEM(__pyx_t_16, 1+__pyx_t_15, ((PyObject *)__pyx_v_isymbols));
@@ -17824,7 +18671,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, 1476, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_13, __pyx_t_16, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1552, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
         }
@@ -17846,172 +18693,206 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
     #endif
   }
 
-  /* "pywrapfst.pyx":1526
- *     See also: `text`.
+  /* "pywrapfst.pyx":1600
+ *       show_weight_one: Should weights equivalent to semiring One be printed?
  *     """
- *     cdef string filename_string = tostring(filename)             # <<<<<<<<<<<<<<
- *     cdef unique_ptr[ofstream] ostrm
- *     ostrm.reset(new ofstream(filename_string))
+ *     cdef string source_string = tostring(source)             # <<<<<<<<<<<<<<
+ *     cdef unique_ptr[ostream] fstrm
+ *     fstrm.reset(new ofstream(source_string))
  */
-  __pyx_t_17 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1526, __pyx_L1_error)
-  __pyx_v_filename_string = __pyx_t_17;
+  __pyx_t_17 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1600, __pyx_L1_error)
+  __pyx_v_source_string = __pyx_t_17;
 
-  /* "pywrapfst.pyx":1528
- *     cdef string filename_string = tostring(filename)
- *     cdef unique_ptr[ofstream] ostrm
- *     ostrm.reset(new ofstream(filename_string))             # <<<<<<<<<<<<<<
- *     cdef fst.SymbolTable *ssymbols_ptr = NULL
- *     if ssymbols is not None:
+  /* "pywrapfst.pyx":1602
+ *     cdef string source_string = tostring(source)
+ *     cdef unique_ptr[ostream] fstrm
+ *     fstrm.reset(new ofstream(source_string))             # <<<<<<<<<<<<<<
+ *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
+ *     if isymbols is not None:
  */
-  __pyx_v_ostrm.reset(new std::ofstream(__pyx_v_filename_string));
+  __pyx_v_fstrm.reset(new std::ofstream(__pyx_v_source_string));
 
-  /* "pywrapfst.pyx":1529
- *     cdef unique_ptr[ofstream] ostrm
- *     ostrm.reset(new ofstream(filename_string))
- *     cdef fst.SymbolTable *ssymbols_ptr = NULL             # <<<<<<<<<<<<<<
- *     if ssymbols is not None:
- *       ssymbols_ptr = ssymbols._table
+  /* "pywrapfst.pyx":1603
+ *     cdef unique_ptr[ostream] fstrm
+ *     fstrm.reset(new ofstream(source_string))
+ *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()             # <<<<<<<<<<<<<<
+ *     if isymbols is not None:
+ *        _isymbols = isymbols._table
  */
-  __pyx_v_ssymbols_ptr = NULL;
+  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
+    __PYX_ERR(0, 1603, __pyx_L1_error)
+  }
+  __pyx_v__isymbols = __pyx_v_self->_fst.get()->InputSymbols();
 
-  /* "pywrapfst.pyx":1530
- *     ostrm.reset(new ofstream(filename_string))
- *     cdef fst.SymbolTable *ssymbols_ptr = NULL
- *     if ssymbols is not None:             # <<<<<<<<<<<<<<
- *       ssymbols_ptr = ssymbols._table
- *     fst.DrawFst(deref(self._fst),
+  /* "pywrapfst.pyx":1604
+ *     fstrm.reset(new ofstream(source_string))
+ *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
+ *     if isymbols is not None:             # <<<<<<<<<<<<<<
+ *        _isymbols = isymbols._table
+ *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
  */
-  __pyx_t_18 = (((PyObject *)__pyx_v_ssymbols) != Py_None);
+  __pyx_t_18 = (((PyObject *)__pyx_v_isymbols) != Py_None);
   __pyx_t_19 = (__pyx_t_18 != 0);
   if (__pyx_t_19) {
 
-    /* "pywrapfst.pyx":1531
- *     cdef fst.SymbolTable *ssymbols_ptr = NULL
- *     if ssymbols is not None:
- *       ssymbols_ptr = ssymbols._table             # <<<<<<<<<<<<<<
- *     fst.DrawFst(deref(self._fst),
- *         self._fst.get().InputSymbols() if isymbols is None
+    /* "pywrapfst.pyx":1605
+ *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
+ *     if isymbols is not None:
+ *        _isymbols = isymbols._table             # <<<<<<<<<<<<<<
+ *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
+ *     if osymbols is not None:
  */
-    if (unlikely(((PyObject *)__pyx_v_ssymbols) == Py_None)) {
+    if (unlikely(((PyObject *)__pyx_v_isymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 1531, __pyx_L1_error)
+      __PYX_ERR(0, 1605, __pyx_L1_error)
     }
-    __pyx_t_20 = __pyx_v_ssymbols->__pyx_base.__pyx_base._table;
-    __pyx_v_ssymbols_ptr = __pyx_t_20;
+    __pyx_t_20 = __pyx_v_isymbols->_table;
+    __pyx_v__isymbols = __pyx_t_20;
 
-    /* "pywrapfst.pyx":1530
- *     ostrm.reset(new ofstream(filename_string))
- *     cdef fst.SymbolTable *ssymbols_ptr = NULL
- *     if ssymbols is not None:             # <<<<<<<<<<<<<<
- *       ssymbols_ptr = ssymbols._table
- *     fst.DrawFst(deref(self._fst),
+    /* "pywrapfst.pyx":1604
+ *     fstrm.reset(new ofstream(source_string))
+ *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
+ *     if isymbols is not None:             # <<<<<<<<<<<<<<
+ *        _isymbols = isymbols._table
+ *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
  */
   }
 
-  /* "pywrapfst.pyx":1532
- *     if ssymbols is not None:
- *       ssymbols_ptr = ssymbols._table
- *     fst.DrawFst(deref(self._fst),             # <<<<<<<<<<<<<<
- *         self._fst.get().InputSymbols() if isymbols is None
- *         else isymbols._table,
+  /* "pywrapfst.pyx":1606
+ *     if isymbols is not None:
+ *        _isymbols = isymbols._table
+ *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()             # <<<<<<<<<<<<<<
+ *     if osymbols is not None:
+ *        _osymbols = osymbols._table
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1532, __pyx_L1_error)
+    __PYX_ERR(0, 1606, __pyx_L1_error)
   }
+  __pyx_v__osymbols = __pyx_v_self->_fst.get()->OutputSymbols();
 
-  /* "pywrapfst.pyx":1533
- *       ssymbols_ptr = ssymbols._table
- *     fst.DrawFst(deref(self._fst),
- *         self._fst.get().InputSymbols() if isymbols is None             # <<<<<<<<<<<<<<
- *         else isymbols._table,
- *         self._fst.get().OutputSymbols() if osymbols is None
+  /* "pywrapfst.pyx":1607
+ *        _isymbols = isymbols._table
+ *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
+ *     if osymbols is not None:             # <<<<<<<<<<<<<<
+ *        _osymbols = osymbols._table
+ *     cdef fst.SymbolTable *_ssymbols = NULL
  */
-  __pyx_t_19 = (((PyObject *)__pyx_v_isymbols) == Py_None);
-  if ((__pyx_t_19 != 0)) {
-    if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-      __PYX_ERR(0, 1533, __pyx_L1_error)
-    }
-    __pyx_t_21 = __pyx_v_self->_fst.get()->InputSymbols();
-  } else {
+  __pyx_t_19 = (((PyObject *)__pyx_v_osymbols) != Py_None);
+  __pyx_t_18 = (__pyx_t_19 != 0);
+  if (__pyx_t_18) {
 
-    /* "pywrapfst.pyx":1534
- *     fst.DrawFst(deref(self._fst),
- *         self._fst.get().InputSymbols() if isymbols is None
- *         else isymbols._table,             # <<<<<<<<<<<<<<
- *         self._fst.get().OutputSymbols() if osymbols is None
- *         else osymbols._table,
+    /* "pywrapfst.pyx":1608
+ *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
+ *     if osymbols is not None:
+ *        _osymbols = osymbols._table             # <<<<<<<<<<<<<<
+ *     cdef fst.SymbolTable *_ssymbols = NULL
+ *     if ssymbols is not None:
  */
-    if (unlikely(((PyObject *)__pyx_v_isymbols) == Py_None)) {
+    if (unlikely(((PyObject *)__pyx_v_osymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 1534, __pyx_L1_error)
+      __PYX_ERR(0, 1608, __pyx_L1_error)
     }
-    __pyx_t_21 = __pyx_v_isymbols->_table;
+    __pyx_t_20 = __pyx_v_osymbols->_table;
+    __pyx_v__osymbols = __pyx_t_20;
+
+    /* "pywrapfst.pyx":1607
+ *        _isymbols = isymbols._table
+ *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
+ *     if osymbols is not None:             # <<<<<<<<<<<<<<
+ *        _osymbols = osymbols._table
+ *     cdef fst.SymbolTable *_ssymbols = NULL
+ */
   }
 
-  /* "pywrapfst.pyx":1535
- *         self._fst.get().InputSymbols() if isymbols is None
- *         else isymbols._table,
- *         self._fst.get().OutputSymbols() if osymbols is None             # <<<<<<<<<<<<<<
- *         else osymbols._table,
- *         ssymbols_ptr, acceptor, tostring(title), width, height, portrait,
+  /* "pywrapfst.pyx":1609
+ *     if osymbols is not None:
+ *        _osymbols = osymbols._table
+ *     cdef fst.SymbolTable *_ssymbols = NULL             # <<<<<<<<<<<<<<
+ *     if ssymbols is not None:
+ *       _ssymbols = ssymbols._table
  */
-  __pyx_t_19 = (((PyObject *)__pyx_v_osymbols) == Py_None);
-  if ((__pyx_t_19 != 0)) {
-    if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-      __PYX_ERR(0, 1535, __pyx_L1_error)
-    }
-    __pyx_t_22 = __pyx_v_self->_fst.get()->OutputSymbols();
-  } else {
+  __pyx_v__ssymbols = NULL;
 
-    /* "pywrapfst.pyx":1536
- *         else isymbols._table,
- *         self._fst.get().OutputSymbols() if osymbols is None
- *         else osymbols._table,             # <<<<<<<<<<<<<<
- *         ssymbols_ptr, acceptor, tostring(title), width, height, portrait,
- *         vertical, ranksep, nodesep, fontsize, precision,
+  /* "pywrapfst.pyx":1610
+ *        _osymbols = osymbols._table
+ *     cdef fst.SymbolTable *_ssymbols = NULL
+ *     if ssymbols is not None:             # <<<<<<<<<<<<<<
+ *       _ssymbols = ssymbols._table
+ *     fst.Draw(deref(self._fst),
  */
-    if (unlikely(((PyObject *)__pyx_v_osymbols) == Py_None)) {
+  __pyx_t_18 = (((PyObject *)__pyx_v_ssymbols) != Py_None);
+  __pyx_t_19 = (__pyx_t_18 != 0);
+  if (__pyx_t_19) {
+
+    /* "pywrapfst.pyx":1611
+ *     cdef fst.SymbolTable *_ssymbols = NULL
+ *     if ssymbols is not None:
+ *       _ssymbols = ssymbols._table             # <<<<<<<<<<<<<<
+ *     fst.Draw(deref(self._fst),
+ *         _isymbols,
+ */
+    if (unlikely(((PyObject *)__pyx_v_ssymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 1536, __pyx_L1_error)
+      __PYX_ERR(0, 1611, __pyx_L1_error)
     }
-    __pyx_t_22 = __pyx_v_osymbols->_table;
+    __pyx_t_20 = __pyx_v_ssymbols->_table;
+    __pyx_v__ssymbols = __pyx_t_20;
+
+    /* "pywrapfst.pyx":1610
+ *        _osymbols = osymbols._table
+ *     cdef fst.SymbolTable *_ssymbols = NULL
+ *     if ssymbols is not None:             # <<<<<<<<<<<<<<
+ *       _ssymbols = ssymbols._table
+ *     fst.Draw(deref(self._fst),
+ */
+  }
+
+  /* "pywrapfst.pyx":1612
+ *     if ssymbols is not None:
+ *       _ssymbols = ssymbols._table
+ *     fst.Draw(deref(self._fst),             # <<<<<<<<<<<<<<
+ *         _isymbols,
+ *         _osymbols,
+ */
+  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
+    __PYX_ERR(0, 1612, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1537
- *         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(),
+  /* "pywrapfst.pyx":1617
+ *         _ssymbols,
+ *         acceptor,
+ *         tostring(title),             # <<<<<<<<<<<<<<
+ *         width,
+ *         height,
  */
-  __pyx_t_17 = __pyx_f_9pywrapfst_tostring(__pyx_v_title); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1537, __pyx_L1_error)
+  __pyx_t_17 = __pyx_f_9pywrapfst_tostring(__pyx_v_title); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1617, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1539
- *         ssymbols_ptr, acceptor, tostring(title), width, height, portrait,
- *         vertical, ranksep, nodesep, fontsize, precision,
- *         tostring(float_format), show_weight_one, ostrm.get(),             # <<<<<<<<<<<<<<
- *         filename_string)
- * 
+  /* "pywrapfst.pyx":1626
+ *         fontsize,
+ *         precision,
+ *         tostring(float_format),             # <<<<<<<<<<<<<<
+ *         show_weight_one,
+ *         deref(fstrm),
  */
-  __pyx_t_23 = __pyx_f_9pywrapfst_tostring(__pyx_v_float_format); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1539, __pyx_L1_error)
+  __pyx_t_21 = __pyx_f_9pywrapfst_tostring(__pyx_v_float_format); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1626, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1532
+  /* "pywrapfst.pyx":1612
  *     if ssymbols is not None:
- *       ssymbols_ptr = ssymbols._table
- *     fst.DrawFst(deref(self._fst),             # <<<<<<<<<<<<<<
- *         self._fst.get().InputSymbols() if isymbols is None
- *         else isymbols._table,
+ *       _ssymbols = ssymbols._table
+ *     fst.Draw(deref(self._fst),             # <<<<<<<<<<<<<<
+ *         _isymbols,
+ *         _osymbols,
  */
-  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);
+  fst::script::Draw((*__pyx_v_self->_fst), __pyx_v__isymbols, __pyx_v__osymbols, __pyx_v__ssymbols, __pyx_v_acceptor, __pyx_t_17, __pyx_v_width, __pyx_v_height, __pyx_v_portrait, __pyx_v_vertical, __pyx_v_ranksep, __pyx_v_nodesep, __pyx_v_fontsize, __pyx_v_precision, __pyx_t_21, __pyx_v_show_weight_one, (*__pyx_v_fstrm), __pyx_v_source_string);
 
-  /* "pywrapfst.pyx":1476
+  /* "pywrapfst.pyx":1552
  *     return _init_XFst(new fst.FstClass(deref(self._fst)))
  * 
  *   cpdef void draw(self,             # <<<<<<<<<<<<<<
- *                   filename,
+ *                   source,
  *                   _SymbolTable isymbols=None,
  */
 
@@ -18040,12 +18921,12 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_17draw(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_16draw[] = "\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 char __pyx_doc_9pywrapfst_4_Fst_16draw[] = "\n    draw(self, source, 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      source: 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    ";
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_17draw(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyObject *__pyx_v_filename = 0;
+  PyObject *__pyx_v_source = 0;
   struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_isymbols = 0;
   struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_osymbols = 0;
-  struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v_ssymbols = 0;
+  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_ssymbols = 0;
   bool __pyx_v_acceptor;
   PyObject *__pyx_v_title = 0;
   double __pyx_v_width;
@@ -18062,36 +18943,36 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_17draw(PyObject *__pyx_v_self, PyObje
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("draw (wrapper)", 0);
   {
-    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};
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_source,&__pyx_n_s_isymbols,&__pyx_n_s_osymbols,&__pyx_n_s_ssymbols,&__pyx_n_s_acceptor,&__pyx_n_s_title,&__pyx_n_s_width,&__pyx_n_s_height,&__pyx_n_s_portrait,&__pyx_n_s_vertical,&__pyx_n_s_ranksep,&__pyx_n_s_nodesep,&__pyx_n_s_fontsize,&__pyx_n_s_precision,&__pyx_n_s_float_format,&__pyx_n_s_show_weight_one,0};
     PyObject* values[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
 
-    /* "pywrapfst.pyx":1478
+    /* "pywrapfst.pyx":1554
  *   cpdef void draw(self,
- *                   filename,
+ *                   source,
  *                   _SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
  *                   _SymbolTable osymbols=None,
- *                   SymbolTable ssymbols=None,
+ *                   _SymbolTable ssymbols=None,
  */
     values[1] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
 
-    /* "pywrapfst.pyx":1479
- *                   filename,
+    /* "pywrapfst.pyx":1555
+ *                   source,
  *                   _SymbolTable isymbols=None,
  *                   _SymbolTable osymbols=None,             # <<<<<<<<<<<<<<
- *                   SymbolTable ssymbols=None,
+ *                   _SymbolTable ssymbols=None,
  *                   bool acceptor=False,
  */
     values[2] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
 
-    /* "pywrapfst.pyx":1480
+    /* "pywrapfst.pyx":1556
  *                   _SymbolTable isymbols=None,
  *                   _SymbolTable osymbols=None,
- *                   SymbolTable ssymbols=None,             # <<<<<<<<<<<<<<
+ *                   _SymbolTable ssymbols=None,             # <<<<<<<<<<<<<<
  *                   bool acceptor=False,
  *                   title=b"",
  */
-    values[3] = (PyObject *)((struct __pyx_obj_9pywrapfst_SymbolTable *)Py_None);
-    values[5] = ((PyObject *)__pyx_kp_b__10);
+    values[3] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
+    values[5] = ((PyObject *)__pyx_kp_b__8);
     values[14] = ((PyObject *)__pyx_n_b_g);
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
@@ -18135,7 +19016,7 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_17draw(PyObject *__pyx_v_self, PyObje
       kw_args = PyDict_Size(__pyx_kwds);
       switch (pos_args) {
         case  0:
-        if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_filename)) != 0)) kw_args--;
+        if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_source)) != 0)) kw_args--;
         else goto __pyx_L5_argtuple_error;
         CYTHON_FALLTHROUGH;
         case  1:
@@ -18229,7 +19110,7 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_17draw(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, 1476, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "draw") < 0)) __PYX_ERR(0, 1552, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -18268,17 +19149,17 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_17draw(PyObject *__pyx_v_self, PyObje
         default: goto __pyx_L5_argtuple_error;
       }
     }
-    __pyx_v_filename = values[0];
+    __pyx_v_source = values[0];
     __pyx_v_isymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)values[1]);
     __pyx_v_osymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)values[2]);
-    __pyx_v_ssymbols = ((struct __pyx_obj_9pywrapfst_SymbolTable *)values[3]);
+    __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, 1481, __pyx_L3_error)
+      __pyx_v_acceptor = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_acceptor == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1557, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1481
+      /* "pywrapfst.pyx":1557
  *                   _SymbolTable osymbols=None,
- *                   SymbolTable ssymbols=None,
+ *                   _SymbolTable ssymbols=None,
  *                   bool acceptor=False,             # <<<<<<<<<<<<<<
  *                   title=b"",
  *                   double width=8.5,
@@ -18287,20 +19168,20 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_17draw(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, 1483, __pyx_L3_error)
+      __pyx_v_width = __pyx_PyFloat_AsDouble(values[6]); if (unlikely((__pyx_v_width == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1559, __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, 1484, __pyx_L3_error)
+      __pyx_v_height = __pyx_PyFloat_AsDouble(values[7]); if (unlikely((__pyx_v_height == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1560, __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, 1485, __pyx_L3_error)
+      __pyx_v_portrait = __Pyx_PyObject_IsTrue(values[8]); if (unlikely((__pyx_v_portrait == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1561, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1485
+      /* "pywrapfst.pyx":1561
  *                   double width=8.5,
  *                   double height=11,
  *                   bool portrait=False,             # <<<<<<<<<<<<<<
@@ -18310,10 +19191,10 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_17draw(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, 1486, __pyx_L3_error)
+      __pyx_v_vertical = __Pyx_PyObject_IsTrue(values[9]); if (unlikely((__pyx_v_vertical == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1562, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1486
+      /* "pywrapfst.pyx":1562
  *                   double height=11,
  *                   bool portrait=False,
  *                   bool vertical=False,             # <<<<<<<<<<<<<<
@@ -18323,58 +19204,58 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_17draw(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, 1487, __pyx_L3_error)
+      __pyx_v_ranksep = __pyx_PyFloat_AsDouble(values[10]); if (unlikely((__pyx_v_ranksep == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1563, __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, 1488, __pyx_L3_error)
+      __pyx_v_nodesep = __pyx_PyFloat_AsDouble(values[11]); if (unlikely((__pyx_v_nodesep == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1564, __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, 1489, __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, 1565, __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, 1490, __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, 1566, __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, 1492, __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, 1568, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1492
+      /* "pywrapfst.pyx":1568
  *                   int32 precision=5,
  *                   float_format=b"g",
  *                   bool show_weight_one=False):             # <<<<<<<<<<<<<<
  *     """
- *     draw(self, filename, isymbols=None, osymbols=None, ssymbols=None,
+ *     draw(self, source, isymbols=None, osymbols=None, ssymbols=None,
  */
       __pyx_v_show_weight_one = ((bool)0);
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("draw", 0, 1, 16, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1476, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("draw", 0, 1, 16, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1552, __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, 1478, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_osymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "osymbols", 0))) __PYX_ERR(0, 1479, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ssymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "ssymbols", 0))) __PYX_ERR(0, 1480, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_4_Fst_16draw(((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);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_isymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "isymbols", 0))) __PYX_ERR(0, 1554, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_osymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "osymbols", 0))) __PYX_ERR(0, 1555, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ssymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "ssymbols", 0))) __PYX_ERR(0, 1556, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_4_Fst_16draw(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self), __pyx_v_source, __pyx_v_isymbols, __pyx_v_osymbols, __pyx_v_ssymbols, __pyx_v_acceptor, __pyx_v_title, __pyx_v_width, __pyx_v_height, __pyx_v_portrait, __pyx_v_vertical, __pyx_v_ranksep, __pyx_v_nodesep, __pyx_v_fontsize, __pyx_v_precision, __pyx_v_float_format, __pyx_v_show_weight_one);
 
-  /* "pywrapfst.pyx":1476
+  /* "pywrapfst.pyx":1552
  *     return _init_XFst(new fst.FstClass(deref(self._fst)))
  * 
  *   cpdef void draw(self,             # <<<<<<<<<<<<<<
- *                   filename,
+ *                   source,
  *                   _SymbolTable isymbols=None,
  */
 
@@ -18387,7 +19268,7 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_17draw(PyObject *__pyx_v_self, PyObje
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_16draw(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, PyObject *__pyx_v_filename, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_isymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_osymbols, struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v_ssymbols, bool __pyx_v_acceptor, PyObject *__pyx_v_title, double __pyx_v_width, double __pyx_v_height, bool __pyx_v_portrait, bool __pyx_v_vertical, double __pyx_v_ranksep, double __pyx_v_nodesep, __pyx_t_10basictypes_int32 __pyx_v_fontsize, __pyx_t_10basictypes_int32 __pyx_v_precision, PyObject *__pyx_v_float_format, bool __pyx_v_show_weight_one) {
+static PyObject *__pyx_pf_9pywrapfst_4_Fst_16draw(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, PyObject *__pyx_v_source, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_isymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_osymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_ssymbols, bool __pyx_v_acceptor, PyObject *__pyx_v_title, double __pyx_v_width, double __pyx_v_height, bool __pyx_v_portrait, bool __pyx_v_vertical, double __pyx_v_ranksep, double __pyx_v_nodesep, __pyx_t_10basictypes_int32 __pyx_v_fontsize, __pyx_t_10basictypes_int32 __pyx_v_precision, PyObject *__pyx_v_float_format, bool __pyx_v_show_weight_one) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   struct __pyx_opt_args_9pywrapfst_4_Fst_draw __pyx_t_1;
@@ -18410,8 +19291,8 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_16draw(struct __pyx_obj_9pywrapfst__F
   __pyx_t_1.precision = __pyx_v_precision;
   __pyx_t_1.float_format = __pyx_v_float_format;
   __pyx_t_1.show_weight_one = __pyx_v_show_weight_one;
-  __pyx_vtabptr_9pywrapfst__Fst->draw(__pyx_v_self, __pyx_v_filename, 1, &__pyx_t_1); 
-  __pyx_t_2 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1476, __pyx_L1_error)
+  __pyx_vtabptr_9pywrapfst__Fst->draw(__pyx_v_self, __pyx_v_source, 1, &__pyx_t_1); 
+  __pyx_t_2 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1552, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -18428,8 +19309,8 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_16draw(struct __pyx_obj_9pywrapfst__F
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1542
- *         filename_string)
+/* "pywrapfst.pyx":1631
+ *         source_string)
  * 
  *   cpdef Weight final(self, int64 state):             # <<<<<<<<<<<<<<
  *     """
@@ -18457,11 +19338,11 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_4_Fst_final(struct
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_final); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1542, __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, 1631, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_4_Fst_19final)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
-        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1542, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1631, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -18477,10 +19358,10 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_4_Fst_final(struct
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1542, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1631, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Weight))))) __PYX_ERR(0, 1542, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Weight))))) __PYX_ERR(0, 1631, __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;
@@ -18499,19 +19380,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_4_Fst_final(struct
     #endif
   }
 
-  /* "pywrapfst.pyx":1557
+  /* "pywrapfst.pyx":1646
  *       FstIndexError: State index out of range.
  *     """
  *     cdef Weight weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
  *     weight._weight.reset(new fst.WeightClass(self._fst.get().Final(state)))
  *     if not weight.member():
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1557, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1646, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v_weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1558
+  /* "pywrapfst.pyx":1647
  *     """
  *     cdef Weight weight = Weight.__new__(Weight)
  *     weight._weight.reset(new fst.WeightClass(self._fst.get().Final(state)))             # <<<<<<<<<<<<<<
@@ -18520,15 +19401,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 '%.30s'", "_weight");
-    __PYX_ERR(0, 1558, __pyx_L1_error)
+    __PYX_ERR(0, 1647, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1558, __pyx_L1_error)
+    __PYX_ERR(0, 1647, __pyx_L1_error)
   }
   __pyx_v_weight->_weight.reset(new fst::script::WeightClass(__pyx_v_self->_fst.get()->Final(__pyx_v_state)));
 
-  /* "pywrapfst.pyx":1559
+  /* "pywrapfst.pyx":1648
  *     cdef Weight weight = Weight.__new__(Weight)
  *     weight._weight.reset(new fst.WeightClass(self._fst.get().Final(state)))
  *     if not weight.member():             # <<<<<<<<<<<<<<
@@ -18537,19 +19418,19 @@ 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 '%.30s'", "member");
-    __PYX_ERR(0, 1559, __pyx_L1_error)
+    __PYX_ERR(0, 1648, __pyx_L1_error)
   }
   __pyx_t_6 = ((!(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_weight->__pyx_vtab)->member(__pyx_v_weight, 0) != 0)) != 0);
   if (unlikely(__pyx_t_6)) {
 
-    /* "pywrapfst.pyx":1560
+    /* "pywrapfst.pyx":1649
  *     weight._weight.reset(new fst.WeightClass(self._fst.get().Final(state)))
  *     if not weight.member():
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     return weight
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1560, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1649, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -18563,14 +19444,14 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_4_Fst_final(struct
     }
     __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1560, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1649, __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, 1560, __pyx_L1_error)
+    __PYX_ERR(0, 1649, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1559
+    /* "pywrapfst.pyx":1648
  *     cdef Weight weight = Weight.__new__(Weight)
  *     weight._weight.reset(new fst.WeightClass(self._fst.get().Final(state)))
  *     if not weight.member():             # <<<<<<<<<<<<<<
@@ -18579,7 +19460,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_4_Fst_final(struct
  */
   }
 
-  /* "pywrapfst.pyx":1561
+  /* "pywrapfst.pyx":1650
  *     if not weight.member():
  *       raise FstIndexError("State index out of range")
  *     return weight             # <<<<<<<<<<<<<<
@@ -18591,8 +19472,8 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_4_Fst_final(struct
   __pyx_r = __pyx_v_weight;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1542
- *         filename_string)
+  /* "pywrapfst.pyx":1631
+ *         source_string)
  * 
  *   cpdef Weight final(self, int64 state):             # <<<<<<<<<<<<<<
  *     """
@@ -18624,7 +19505,7 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_19final(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, 1542, __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, 1631, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -18645,7 +19526,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_18final(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, 1542, __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, 1631, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -18662,7 +19543,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_18final(struct __pyx_obj_9pywrapfst__
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1563
+/* "pywrapfst.pyx":1652
  *     return weight
  * 
  *   cpdef string fst_type(self):             # <<<<<<<<<<<<<<
@@ -18689,7 +19570,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_fst_type(struct __pyx_obj_9pywrapfst
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_fst_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1563, __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, 1652, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_4_Fst_21fst_type)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -18705,10 +19586,10 @@ static std::string __pyx_f_9pywrapfst_4_Fst_fst_type(struct __pyx_obj_9pywrapfst
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1563, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1652, __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, 1563, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1652, __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;
@@ -18727,7 +19608,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_fst_type(struct __pyx_obj_9pywrapfst
     #endif
   }
 
-  /* "pywrapfst.pyx":1569
+  /* "pywrapfst.pyx":1658
  *     Returns a string indicating the FST type.
  *     """
  *     return self._fst.get().FstType()             # <<<<<<<<<<<<<<
@@ -18736,12 +19617,12 @@ static std::string __pyx_f_9pywrapfst_4_Fst_fst_type(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1569, __pyx_L1_error)
+    __PYX_ERR(0, 1658, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_fst.get()->FstType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1563
+  /* "pywrapfst.pyx":1652
  *     return weight
  * 
  *   cpdef string fst_type(self):             # <<<<<<<<<<<<<<
@@ -18782,7 +19663,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_20fst_type(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("fst_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_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, 1563, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_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, 1652, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -18799,7 +19680,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_20fst_type(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1571
+/* "pywrapfst.pyx":1660
  *     return self._fst.get().FstType()
  * 
  *   cpdef _FstSymbolTable input_symbols(self):             # <<<<<<<<<<<<<<
@@ -18827,7 +19708,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_inp
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_input_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1571, __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, 1660, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_4_Fst_23input_symbols)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -18844,10 +19725,10 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_inp
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1571, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1660, __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, 1571, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__FstSymbolTable))))) __PYX_ERR(0, 1660, __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;
@@ -18866,7 +19747,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_inp
     #endif
   }
 
-  /* "pywrapfst.pyx":1580
+  /* "pywrapfst.pyx":1667
  *     """
  *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
  *       self._fst.get().InputSymbols())             # <<<<<<<<<<<<<<
@@ -18875,11 +19756,11 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_inp
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1580, __pyx_L1_error)
+    __PYX_ERR(0, 1667, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1579
- *     See also: `input_symbols`.
+  /* "pywrapfst.pyx":1666
+ *     Returns the FST's input symbol table, or None if none is present.
  *     """
  *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](             # <<<<<<<<<<<<<<
  *       self._fst.get().InputSymbols())
@@ -18887,7 +19768,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_inp
  */
   __pyx_v_syms = const_cast<__pyx_t_9pywrapfst_SymbolTable_ptr>(__pyx_v_self->_fst.get()->InputSymbols());
 
-  /* "pywrapfst.pyx":1581
+  /* "pywrapfst.pyx":1668
  *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
  *       self._fst.get().InputSymbols())
  *     if syms == NULL:             # <<<<<<<<<<<<<<
@@ -18897,7 +19778,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_inp
   __pyx_t_5 = ((__pyx_v_syms == NULL) != 0);
   if (__pyx_t_5) {
 
-    /* "pywrapfst.pyx":1582
+    /* "pywrapfst.pyx":1669
  *       self._fst.get().InputSymbols())
  *     if syms == NULL:
  *       return             # <<<<<<<<<<<<<<
@@ -18908,7 +19789,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_inp
     __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTable *)Py_None); __Pyx_INCREF(Py_None);
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":1581
+    /* "pywrapfst.pyx":1668
  *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
  *       self._fst.get().InputSymbols())
  *     if syms == NULL:             # <<<<<<<<<<<<<<
@@ -18917,7 +19798,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_inp
  */
   }
 
-  /* "pywrapfst.pyx":1583
+  /* "pywrapfst.pyx":1670
  *     if syms == NULL:
  *       return
  *     return _init_FstSymbolTable(syms, self._fst)             # <<<<<<<<<<<<<<
@@ -18927,15 +19808,15 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_inp
   __Pyx_XDECREF(((PyObject *)__pyx_r));
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1583, __pyx_L1_error)
+    __PYX_ERR(0, 1670, __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, 1583, __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, 1670, __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":1571
+  /* "pywrapfst.pyx":1660
  *     return self._fst.get().FstType()
  * 
  *   cpdef _FstSymbolTable input_symbols(self):             # <<<<<<<<<<<<<<
@@ -18959,7 +19840,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_inp
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_23input_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_22input_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 char __pyx_doc_9pywrapfst_4_Fst_22input_symbols[] = "\n    input_symbols(self)\n\n    Returns the FST's input symbol table, or None if none is present.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_23input_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -18977,7 +19858,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_22input_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, 1571, __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, 1660, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -18994,7 +19875,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_22input_symbols(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1585
+/* "pywrapfst.pyx":1672
  *     return _init_FstSymbolTable(syms, self._fst)
  * 
  *   cpdef size_t num_arcs(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -19024,10 +19905,10 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_arcs(struct __pyx_obj_9pywrapfst__Fst
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_arcs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1585, __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, 1672, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_4_Fst_25num_arcs)) {
-        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1585, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1672, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -19043,10 +19924,10 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_arcs(struct __pyx_obj_9pywrapfst__Fst
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1585, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1672, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        __pyx_t_6 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_6 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1585, __pyx_L1_error)
+        __pyx_t_6 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_6 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1672, __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;
@@ -19065,8 +19946,8 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_arcs(struct __pyx_obj_9pywrapfst__Fst
     #endif
   }
 
-  /* "pywrapfst.pyx":1602
- *     See also: `num_states`.
+  /* "pywrapfst.pyx":1687
+ *       FstIndexError: State index out of range.
  *     """
  *     cdef size_t result = self._fst.get().NumArcs(state)             # <<<<<<<<<<<<<<
  *     if result == SIZE_MAX:
@@ -19074,11 +19955,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 '%.30s'", "_fst");
-    __PYX_ERR(0, 1602, __pyx_L1_error)
+    __PYX_ERR(0, 1687, __pyx_L1_error)
   }
   __pyx_v_result = __pyx_v_self->_fst.get()->NumArcs(__pyx_v_state);
 
-  /* "pywrapfst.pyx":1603
+  /* "pywrapfst.pyx":1688
  *     """
  *     cdef size_t result = self._fst.get().NumArcs(state)
  *     if result == SIZE_MAX:             # <<<<<<<<<<<<<<
@@ -19088,14 +19969,14 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_arcs(struct __pyx_obj_9pywrapfst__Fst
   __pyx_t_7 = ((__pyx_v_result == SIZE_MAX) != 0);
   if (unlikely(__pyx_t_7)) {
 
-    /* "pywrapfst.pyx":1604
+    /* "pywrapfst.pyx":1689
  *     cdef size_t result = self._fst.get().NumArcs(state)
  *     if result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     return result
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1604, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1689, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -19109,14 +19990,14 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_arcs(struct __pyx_obj_9pywrapfst__Fst
     }
     __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1604, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1689, __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, 1604, __pyx_L1_error)
+    __PYX_ERR(0, 1689, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1603
+    /* "pywrapfst.pyx":1688
  *     """
  *     cdef size_t result = self._fst.get().NumArcs(state)
  *     if result == SIZE_MAX:             # <<<<<<<<<<<<<<
@@ -19125,7 +20006,7 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_arcs(struct __pyx_obj_9pywrapfst__Fst
  */
   }
 
-  /* "pywrapfst.pyx":1605
+  /* "pywrapfst.pyx":1690
  *     if result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")
  *     return result             # <<<<<<<<<<<<<<
@@ -19135,7 +20016,7 @@ 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":1585
+  /* "pywrapfst.pyx":1672
  *     return _init_FstSymbolTable(syms, self._fst)
  * 
  *   cpdef size_t num_arcs(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -19159,14 +20040,14 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_arcs(struct __pyx_obj_9pywrapfst__Fst
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_25num_arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_24num_arcs[] = "\n    num_arcs(self, state)\n\n    Returns the number of arcs leaving a state.\n\n    Args:\n      state: The integer index of a state.\n\n    Returns:\n      The number of arcs leaving that state.\n\n    Raises:\n      FstIndexError: State index out of range.\n\n    See also: `num_states`.\n    ";
+static char __pyx_doc_9pywrapfst_4_Fst_24num_arcs[] = "\n    num_arcs(self, state)\n\n    Returns the number of arcs leaving a state.\n\n    Args:\n      state: The integer index of a state.\n\n    Returns:\n      The number of arcs leaving that state.\n\n    Raises:\n      FstIndexError: State index out of range.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_25num_arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state) {
   __pyx_t_10basictypes_int64 __pyx_v_state;
   PyObject *__pyx_r = 0;
   __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, 1585, __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, 1672, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -19188,8 +20069,8 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_24num_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, 1585, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1585, __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, 1672, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1672, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -19206,7 +20087,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_24num_arcs(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1607
+/* "pywrapfst.pyx":1692
  *     return result
  * 
  *   cpdef size_t num_input_epsilons(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -19236,10 +20117,10 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_input_epsilons(struct __pyx_obj_9pywr
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_input_epsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1607, __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, 1692, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_4_Fst_27num_input_epsilons)) {
-        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1607, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1692, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -19255,10 +20136,10 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_input_epsilons(struct __pyx_obj_9pywr
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1607, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1692, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        __pyx_t_6 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_6 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1607, __pyx_L1_error)
+        __pyx_t_6 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_6 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1692, __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;
@@ -19277,8 +20158,8 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_input_epsilons(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":1624
- *     See also: `num_output_epsilons`.
+  /* "pywrapfst.pyx":1707
+ *       FstIndexError: State index out of range.
  *     """
  *     cdef size_t result = self._fst.get().NumInputEpsilons(state)             # <<<<<<<<<<<<<<
  *     if result == SIZE_MAX:
@@ -19286,11 +20167,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 '%.30s'", "_fst");
-    __PYX_ERR(0, 1624, __pyx_L1_error)
+    __PYX_ERR(0, 1707, __pyx_L1_error)
   }
   __pyx_v_result = __pyx_v_self->_fst.get()->NumInputEpsilons(__pyx_v_state);
 
-  /* "pywrapfst.pyx":1625
+  /* "pywrapfst.pyx":1708
  *     """
  *     cdef size_t result = self._fst.get().NumInputEpsilons(state)
  *     if result == SIZE_MAX:             # <<<<<<<<<<<<<<
@@ -19300,14 +20181,14 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_input_epsilons(struct __pyx_obj_9pywr
   __pyx_t_7 = ((__pyx_v_result == SIZE_MAX) != 0);
   if (unlikely(__pyx_t_7)) {
 
-    /* "pywrapfst.pyx":1626
+    /* "pywrapfst.pyx":1709
  *     cdef size_t result = self._fst.get().NumInputEpsilons(state)
  *     if result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     return result
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1626, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1709, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -19321,14 +20202,14 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_input_epsilons(struct __pyx_obj_9pywr
     }
     __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1626, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1709, __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, 1626, __pyx_L1_error)
+    __PYX_ERR(0, 1709, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1625
+    /* "pywrapfst.pyx":1708
  *     """
  *     cdef size_t result = self._fst.get().NumInputEpsilons(state)
  *     if result == SIZE_MAX:             # <<<<<<<<<<<<<<
@@ -19337,7 +20218,7 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_input_epsilons(struct __pyx_obj_9pywr
  */
   }
 
-  /* "pywrapfst.pyx":1627
+  /* "pywrapfst.pyx":1710
  *     if result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")
  *     return result             # <<<<<<<<<<<<<<
@@ -19347,7 +20228,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":1607
+  /* "pywrapfst.pyx":1692
  *     return result
  * 
  *   cpdef size_t num_input_epsilons(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -19371,14 +20252,14 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_input_epsilons(struct __pyx_obj_9pywr
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_27num_input_epsilons(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_26num_input_epsilons[] = "\n    num_input_epsilons(self, state)\n\n    Returns the number of arcs with epsilon input labels leaving a state.\n\n    Args:\n      state: The integer index of a state.\n\n    Returns:\n      The number of epsilon-input-labeled arcs leaving that state.\n\n    Raises:\n      FstIndexError: State index out of range.\n\n    See also: `num_output_epsilons`.\n    ";
+static char __pyx_doc_9pywrapfst_4_Fst_26num_input_epsilons[] = "\n    num_input_epsilons(self, state)\n\n    Returns the number of arcs with epsilon input labels leaving a state.\n\n    Args:\n      state: The integer index of a state.\n\n    Returns:\n      The number of epsilon-input-labeled arcs leaving that state.\n\n    Raises:\n      FstIndexError: State index out of range.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_27num_input_epsilons(PyObject *__pyx_v_self, PyObject *__pyx_arg_state) {
   __pyx_t_10basictypes_int64 __pyx_v_state;
   PyObject *__pyx_r = 0;
   __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, 1607, __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, 1692, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -19400,8 +20281,8 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_26num_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, 1607, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1607, __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, 1692, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1692, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -19418,7 +20299,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_26num_input_epsilons(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1629
+/* "pywrapfst.pyx":1712
  *     return result
  * 
  *   cpdef size_t num_output_epsilons(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -19448,10 +20329,10 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_output_epsilons(struct __pyx_obj_9pyw
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_output_epsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1629, __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, 1712, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_4_Fst_29num_output_epsilons)) {
-        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1629, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1712, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -19467,10 +20348,10 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_output_epsilons(struct __pyx_obj_9pyw
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1629, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1712, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        __pyx_t_6 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_6 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1629, __pyx_L1_error)
+        __pyx_t_6 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_6 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1712, __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;
@@ -19489,8 +20370,8 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_output_epsilons(struct __pyx_obj_9pyw
     #endif
   }
 
-  /* "pywrapfst.pyx":1646
- *     See also: `num_input_epsilons`.
+  /* "pywrapfst.pyx":1727
+ *       FstIndexError: State index out of range.
  *     """
  *     cdef size_t result = self._fst.get().NumOutputEpsilons(state)             # <<<<<<<<<<<<<<
  *     if result == SIZE_MAX:
@@ -19498,11 +20379,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 '%.30s'", "_fst");
-    __PYX_ERR(0, 1646, __pyx_L1_error)
+    __PYX_ERR(0, 1727, __pyx_L1_error)
   }
   __pyx_v_result = __pyx_v_self->_fst.get()->NumOutputEpsilons(__pyx_v_state);
 
-  /* "pywrapfst.pyx":1647
+  /* "pywrapfst.pyx":1728
  *     """
  *     cdef size_t result = self._fst.get().NumOutputEpsilons(state)
  *     if result == SIZE_MAX:             # <<<<<<<<<<<<<<
@@ -19512,14 +20393,14 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_output_epsilons(struct __pyx_obj_9pyw
   __pyx_t_7 = ((__pyx_v_result == SIZE_MAX) != 0);
   if (unlikely(__pyx_t_7)) {
 
-    /* "pywrapfst.pyx":1648
+    /* "pywrapfst.pyx":1729
  *     cdef size_t result = self._fst.get().NumOutputEpsilons(state)
  *     if result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     return result
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1648, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1729, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -19533,14 +20414,14 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_output_epsilons(struct __pyx_obj_9pyw
     }
     __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1648, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1729, __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, 1648, __pyx_L1_error)
+    __PYX_ERR(0, 1729, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1647
+    /* "pywrapfst.pyx":1728
  *     """
  *     cdef size_t result = self._fst.get().NumOutputEpsilons(state)
  *     if result == SIZE_MAX:             # <<<<<<<<<<<<<<
@@ -19549,7 +20430,7 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_output_epsilons(struct __pyx_obj_9pyw
  */
   }
 
-  /* "pywrapfst.pyx":1649
+  /* "pywrapfst.pyx":1730
  *     if result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")
  *     return result             # <<<<<<<<<<<<<<
@@ -19559,7 +20440,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":1629
+  /* "pywrapfst.pyx":1712
  *     return result
  * 
  *   cpdef size_t num_output_epsilons(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -19583,14 +20464,14 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_output_epsilons(struct __pyx_obj_9pyw
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_29num_output_epsilons(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_28num_output_epsilons[] = "\n    num_output_epsilons(self, state)\n\n    Returns the number of arcs with epsilon output labels leaving a state.\n\n    Args:\n      state: The integer index of a state.\n\n    Returns:\n      The number of epsilon-output-labeled arcs leaving that state.\n\n    Raises:\n      FstIndexError: State index out of range.\n\n    See also: `num_input_epsilons`.\n    ";
+static char __pyx_doc_9pywrapfst_4_Fst_28num_output_epsilons[] = "\n    num_output_epsilons(self, state)\n\n    Returns the number of arcs with epsilon output labels leaving a state.\n\n    Args:\n      state: The integer index of a state.\n\n    Returns:\n      The number of epsilon-output-labeled arcs leaving that state.\n\n    Raises:\n      FstIndexError: State index out of range.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_29num_output_epsilons(PyObject *__pyx_v_self, PyObject *__pyx_arg_state) {
   __pyx_t_10basictypes_int64 __pyx_v_state;
   PyObject *__pyx_r = 0;
   __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, 1629, __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, 1712, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -19612,8 +20493,8 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_28num_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, 1629, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1629, __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, 1712, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1712, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -19630,7 +20511,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_28num_output_epsilons(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1651
+/* "pywrapfst.pyx":1732
  *     return result
  * 
  *   cpdef _FstSymbolTable output_symbols(self):             # <<<<<<<<<<<<<<
@@ -19658,7 +20539,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_out
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_output_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1651, __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, 1732, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_4_Fst_31output_symbols)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -19675,10 +20556,10 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_out
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1651, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1732, __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, 1651, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__FstSymbolTable))))) __PYX_ERR(0, 1732, __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;
@@ -19697,7 +20578,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_out
     #endif
   }
 
-  /* "pywrapfst.pyx":1660
+  /* "pywrapfst.pyx":1739
  *     """
  *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
  *       self._fst.get().OutputSymbols())             # <<<<<<<<<<<<<<
@@ -19706,11 +20587,11 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_out
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1660, __pyx_L1_error)
+    __PYX_ERR(0, 1739, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1659
- *     See also: `input_symbols`.
+  /* "pywrapfst.pyx":1738
+ *     Returns the FST's output symbol table, or None if none is present.
  *     """
  *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](             # <<<<<<<<<<<<<<
  *       self._fst.get().OutputSymbols())
@@ -19718,7 +20599,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_out
  */
   __pyx_v_syms = const_cast<__pyx_t_9pywrapfst_SymbolTable_ptr>(__pyx_v_self->_fst.get()->OutputSymbols());
 
-  /* "pywrapfst.pyx":1661
+  /* "pywrapfst.pyx":1740
  *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
  *       self._fst.get().OutputSymbols())
  *     if syms == NULL:             # <<<<<<<<<<<<<<
@@ -19728,7 +20609,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_out
   __pyx_t_5 = ((__pyx_v_syms == NULL) != 0);
   if (__pyx_t_5) {
 
-    /* "pywrapfst.pyx":1662
+    /* "pywrapfst.pyx":1741
  *       self._fst.get().OutputSymbols())
  *     if syms == NULL:
  *       return             # <<<<<<<<<<<<<<
@@ -19739,7 +20620,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_out
     __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTable *)Py_None); __Pyx_INCREF(Py_None);
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":1661
+    /* "pywrapfst.pyx":1740
  *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
  *       self._fst.get().OutputSymbols())
  *     if syms == NULL:             # <<<<<<<<<<<<<<
@@ -19748,7 +20629,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_out
  */
   }
 
-  /* "pywrapfst.pyx":1663
+  /* "pywrapfst.pyx":1742
  *     if syms == NULL:
  *       return
  *     return _init_FstSymbolTable(syms, self._fst)             # <<<<<<<<<<<<<<
@@ -19758,15 +20639,15 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_out
   __Pyx_XDECREF(((PyObject *)__pyx_r));
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1663, __pyx_L1_error)
+    __PYX_ERR(0, 1742, __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, 1663, __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, 1742, __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":1651
+  /* "pywrapfst.pyx":1732
  *     return result
  * 
  *   cpdef _FstSymbolTable output_symbols(self):             # <<<<<<<<<<<<<<
@@ -19790,7 +20671,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_out
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_31output_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_30output_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 char __pyx_doc_9pywrapfst_4_Fst_30output_symbols[] = "\n    output_symbols(self)\n\n    Returns the FST's output symbol table, or None if none is present.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_31output_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -19808,7 +20689,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_30output_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, 1651, __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, 1732, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -19825,7 +20706,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_30output_symbols(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1665
+/* "pywrapfst.pyx":1744
  *     return _init_FstSymbolTable(syms, self._fst)
  * 
  *   cpdef uint64 properties(self, uint64 mask, bool test):             # <<<<<<<<<<<<<<
@@ -19856,12 +20737,12 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_4_Fst_properties(struct __
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_properties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1665, __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, 1744, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_4_Fst_33properties)) {
-        __pyx_t_3 = __Pyx_PyInt_From_uint64_t(__pyx_v_mask); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1665, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_uint64_t(__pyx_v_mask); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1744, __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, 1665, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_v_test); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1744, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_5 = __pyx_t_1; __pyx_t_6 = NULL;
@@ -19879,7 +20760,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, 1665, __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, 1744, __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;
@@ -19889,7 +20770,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, 1665, __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, 1744, __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;
@@ -19897,7 +20778,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, 1665, __pyx_L1_error)
+          __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1744, __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;
@@ -19908,12 +20789,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, 1665, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1744, __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, 1665, __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, 1744, __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;
@@ -19932,7 +20813,7 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_4_Fst_properties(struct __
     #endif
   }
 
-  /* "pywrapfst.pyx":1683
+  /* "pywrapfst.pyx":1762
  *       A 64-bit bitmask representing the requested properties.
  *     """
  *     return self._fst.get().Properties(mask, test)             # <<<<<<<<<<<<<<
@@ -19941,12 +20822,12 @@ 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 '%.30s'", "_fst");
-    __PYX_ERR(0, 1683, __pyx_L1_error)
+    __PYX_ERR(0, 1762, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_fst.get()->Properties(__pyx_v_mask, __pyx_v_test);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1665
+  /* "pywrapfst.pyx":1744
  *     return _init_FstSymbolTable(syms, self._fst)
  * 
  *   cpdef uint64 properties(self, uint64 mask, bool test):             # <<<<<<<<<<<<<<
@@ -20002,11 +20883,11 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_33properties(PyObject *__pyx_v_self,
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_test)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("properties", 1, 2, 2, 1); __PYX_ERR(0, 1665, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("properties", 1, 2, 2, 1); __PYX_ERR(0, 1744, __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, 1665, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "properties") < 0)) __PYX_ERR(0, 1744, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -20014,12 +20895,12 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_33properties(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, 1665, __pyx_L3_error)
-    __pyx_v_test = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_test == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1665, __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, 1744, __pyx_L3_error)
+    __pyx_v_test = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_test == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1744, __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, 1665, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("properties", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1744, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._Fst.properties", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -20038,7 +20919,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_32properties(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, 1665, __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, 1744, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -20055,7 +20936,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_32properties(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1685
+/* "pywrapfst.pyx":1764
  *     return self._fst.get().Properties(mask, test)
  * 
  *   cpdef int64 start(self):             # <<<<<<<<<<<<<<
@@ -20082,7 +20963,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_4_Fst_start(struct __pyx_ob
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_start); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1685, __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, 1764, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_4_Fst_35start)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -20098,10 +20979,10 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_4_Fst_start(struct __pyx_ob
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1685, __pyx_L1_error)
+        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_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1685, __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, 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;
@@ -20120,7 +21001,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_4_Fst_start(struct __pyx_ob
     #endif
   }
 
-  /* "pywrapfst.pyx":1691
+  /* "pywrapfst.pyx":1770
  *     Returns the start state.
  *     """
  *     return self._fst.get().Start()             # <<<<<<<<<<<<<<
@@ -20129,12 +21010,12 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_4_Fst_start(struct __pyx_ob
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1691, __pyx_L1_error)
+    __PYX_ERR(0, 1770, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_fst.get()->Start();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1685
+  /* "pywrapfst.pyx":1764
  *     return self._fst.get().Properties(mask, test)
  * 
  *   cpdef int64 start(self):             # <<<<<<<<<<<<<<
@@ -20175,7 +21056,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_34start(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, 1685, __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, 1764, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -20192,7 +21073,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_34start(struct __pyx_obj_9pywrapfst__
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1693
+/* "pywrapfst.pyx":1772
  *     return self._fst.get().Start()
  * 
  *   cpdef StateIterator states(self):             # <<<<<<<<<<<<<<
@@ -20218,7 +21099,7 @@ static struct __pyx_obj_9pywrapfst_StateIterator *__pyx_f_9pywrapfst_4_Fst_state
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1693, __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, 1772, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_4_Fst_37states)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -20235,10 +21116,10 @@ static struct __pyx_obj_9pywrapfst_StateIterator *__pyx_f_9pywrapfst_4_Fst_state
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1693, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1772, __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, 1693, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_StateIterator))))) __PYX_ERR(0, 1772, __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;
@@ -20257,21 +21138,21 @@ static struct __pyx_obj_9pywrapfst_StateIterator *__pyx_f_9pywrapfst_4_Fst_state
     #endif
   }
 
-  /* "pywrapfst.pyx":1704
- *     See also: `arcs`, `mutable_arcs`.
+  /* "pywrapfst.pyx":1781
+ *       A StateIterator object for the FST.
  *     """
  *     return StateIterator(self)             # <<<<<<<<<<<<<<
  * 
  *   cpdef string text(self, _SymbolTable isymbols=None,
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = __Pyx_PyObject_CallOneArg(((PyObject *)__pyx_ptype_9pywrapfst_StateIterator), ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1704, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_CallOneArg(((PyObject *)__pyx_ptype_9pywrapfst_StateIterator), ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1781, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_StateIterator *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1693
+  /* "pywrapfst.pyx":1772
  *     return self._fst.get().Start()
  * 
  *   cpdef StateIterator states(self):             # <<<<<<<<<<<<<<
@@ -20295,7 +21176,7 @@ static struct __pyx_obj_9pywrapfst_StateIterator *__pyx_f_9pywrapfst_4_Fst_state
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_37states(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_36states[] = "\n    states(self)\n\n    Returns an iterator over all states in the FST.\n\n    Returns:\n      A StateIterator object for the FST.\n\n    See also: `arcs`, `mutable_arcs`.\n    ";
+static char __pyx_doc_9pywrapfst_4_Fst_36states[] = "\n    states(self)\n\n    Returns an iterator over all states in the FST.\n\n    Returns:\n      A StateIterator object for the FST.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_37states(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -20313,7 +21194,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_36states(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, 1693, __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, 1772, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -20330,7 +21211,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_36states(struct __pyx_obj_9pywrapfst_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1706
+/* "pywrapfst.pyx":1783
  *     return StateIterator(self)
  * 
  *   cpdef string text(self, _SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
@@ -20342,7 +21223,7 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_39text(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":1707
+  /* "pywrapfst.pyx":1784
  * 
  *   cpdef string text(self, _SymbolTable isymbols=None,
  *       _SymbolTable osymbols=None, _SymbolTable ssymbols=None,             # <<<<<<<<<<<<<<
@@ -20352,7 +21233,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":1708
+  /* "pywrapfst.pyx":1785
  *   cpdef string text(self, _SymbolTable isymbols=None,
  *       _SymbolTable osymbols=None, _SymbolTable ssymbols=None,
  *       bool acceptor=False, bool show_weight_one=False, missing_sym=b""):             # <<<<<<<<<<<<<<
@@ -20361,8 +21242,10 @@ 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__10);
-  fst::SymbolTable *__pyx_v_ssymbols_ptr;
+  PyObject *__pyx_v_missing_sym = ((PyObject *)__pyx_kp_b__8);
+  fst::SymbolTable const *__pyx_v__isymbols;
+  fst::SymbolTable const *__pyx_v__osymbols;
+  fst::SymbolTable *__pyx_v__ssymbols;
   std::stringstream __pyx_v_sstrm;
   std::string __pyx_r;
   __Pyx_RefNannyDeclarations
@@ -20378,8 +21261,6 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
   int __pyx_t_10;
   int __pyx_t_11;
   fst::SymbolTable *__pyx_t_12;
-  fst::SymbolTable const *__pyx_t_13;
-  fst::SymbolTable const *__pyx_t_14;
   __Pyx_RefNannySetupContext("text", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -20402,7 +21283,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
     }
   }
 
-  /* "pywrapfst.pyx":1706
+  /* "pywrapfst.pyx":1783
  *     return StateIterator(self)
  * 
  *   cpdef string text(self, _SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
@@ -20418,12 +21299,12 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_text); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1706, __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, 1783, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_4_Fst_39text)) {
-        __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_v_acceptor); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1706, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_v_acceptor); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1783, __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, 1706, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_v_show_weight_one); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1783, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_5 = __pyx_t_1; __pyx_t_6 = NULL;
@@ -20441,7 +21322,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, 1706, __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, 1783, __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;
@@ -20451,7 +21332,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, 1706, __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, 1783, __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;
@@ -20459,7 +21340,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, 1706, __pyx_L1_error)
+          __pyx_t_8 = PyTuple_New(6+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1783, __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;
@@ -20482,12 +21363,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, 1706, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1783, __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, 1706, __pyx_L1_error)
+        __pyx_t_9 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1783, __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;
@@ -20506,142 +21387,210 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
     #endif
   }
 
-  /* "pywrapfst.pyx":1731
+  /* "pywrapfst.pyx":1808
  *     """
  *     # Prints FST to stringstream, then returns resulting string.
- *     cdef fst.SymbolTable *ssymbols_ptr = NULL             # <<<<<<<<<<<<<<
- *     if ssymbols is not None:
- *       ssymbols_ptr = ssymbols._table
+ *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()             # <<<<<<<<<<<<<<
+ *     if isymbols is not None:
+ *        _isymbols = isymbols._table
  */
-  __pyx_v_ssymbols_ptr = NULL;
+  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
+    __PYX_ERR(0, 1808, __pyx_L1_error)
+  }
+  __pyx_v__isymbols = __pyx_v_self->_fst.get()->InputSymbols();
 
-  /* "pywrapfst.pyx":1732
+  /* "pywrapfst.pyx":1809
  *     # Prints FST to stringstream, then returns resulting string.
- *     cdef fst.SymbolTable *ssymbols_ptr = NULL
- *     if ssymbols is not None:             # <<<<<<<<<<<<<<
- *       ssymbols_ptr = ssymbols._table
- *     cdef stringstream sstrm
+ *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
+ *     if isymbols is not None:             # <<<<<<<<<<<<<<
+ *        _isymbols = isymbols._table
+ *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
  */
-  __pyx_t_10 = (((PyObject *)__pyx_v_ssymbols) != Py_None);
+  __pyx_t_10 = (((PyObject *)__pyx_v_isymbols) != Py_None);
   __pyx_t_11 = (__pyx_t_10 != 0);
   if (__pyx_t_11) {
 
-    /* "pywrapfst.pyx":1733
- *     cdef fst.SymbolTable *ssymbols_ptr = NULL
- *     if ssymbols is not None:
- *       ssymbols_ptr = ssymbols._table             # <<<<<<<<<<<<<<
- *     cdef stringstream sstrm
- *     fst.PrintFst(deref(self._fst), sstrm, b"<pywrapfst>",
+    /* "pywrapfst.pyx":1810
+ *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
+ *     if isymbols is not None:
+ *        _isymbols = isymbols._table             # <<<<<<<<<<<<<<
+ *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
+ *     if osymbols is not None:
  */
-    if (unlikely(((PyObject *)__pyx_v_ssymbols) == Py_None)) {
+    if (unlikely(((PyObject *)__pyx_v_isymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 1733, __pyx_L1_error)
+      __PYX_ERR(0, 1810, __pyx_L1_error)
     }
-    __pyx_t_12 = __pyx_v_ssymbols->_table;
-    __pyx_v_ssymbols_ptr = __pyx_t_12;
+    __pyx_t_12 = __pyx_v_isymbols->_table;
+    __pyx_v__isymbols = __pyx_t_12;
 
-    /* "pywrapfst.pyx":1732
+    /* "pywrapfst.pyx":1809
  *     # Prints FST to stringstream, then returns resulting string.
- *     cdef fst.SymbolTable *ssymbols_ptr = NULL
- *     if ssymbols is not None:             # <<<<<<<<<<<<<<
- *       ssymbols_ptr = ssymbols._table
- *     cdef stringstream sstrm
+ *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
+ *     if isymbols is not None:             # <<<<<<<<<<<<<<
+ *        _isymbols = isymbols._table
+ *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
  */
   }
 
-  /* "pywrapfst.pyx":1735
- *       ssymbols_ptr = ssymbols._table
- *     cdef stringstream sstrm
- *     fst.PrintFst(deref(self._fst), sstrm, b"<pywrapfst>",             # <<<<<<<<<<<<<<
- *         self._fst.get().InputSymbols() if isymbols is None
- *         else isymbols._table,
+  /* "pywrapfst.pyx":1811
+ *     if isymbols is not None:
+ *        _isymbols = isymbols._table
+ *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()             # <<<<<<<<<<<<<<
+ *     if osymbols is not None:
+ *        _osymbols = osymbols._table
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1735, __pyx_L1_error)
+    __PYX_ERR(0, 1811, __pyx_L1_error)
   }
+  __pyx_v__osymbols = __pyx_v_self->_fst.get()->OutputSymbols();
 
-  /* "pywrapfst.pyx":1736
- *     cdef stringstream sstrm
- *     fst.PrintFst(deref(self._fst), sstrm, b"<pywrapfst>",
- *         self._fst.get().InputSymbols() if isymbols is None             # <<<<<<<<<<<<<<
- *         else isymbols._table,
- *         self._fst.get().OutputSymbols() if osymbols is None
+  /* "pywrapfst.pyx":1812
+ *        _isymbols = isymbols._table
+ *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
+ *     if osymbols is not None:             # <<<<<<<<<<<<<<
+ *        _osymbols = osymbols._table
+ *     cdef fst.SymbolTable *_ssymbols = NULL
  */
-  __pyx_t_11 = (((PyObject *)__pyx_v_isymbols) == Py_None);
-  if ((__pyx_t_11 != 0)) {
-    if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-      __PYX_ERR(0, 1736, __pyx_L1_error)
-    }
-    __pyx_t_13 = __pyx_v_self->_fst.get()->InputSymbols();
-  } else {
+  __pyx_t_11 = (((PyObject *)__pyx_v_osymbols) != Py_None);
+  __pyx_t_10 = (__pyx_t_11 != 0);
+  if (__pyx_t_10) {
 
-    /* "pywrapfst.pyx":1737
- *     fst.PrintFst(deref(self._fst), sstrm, b"<pywrapfst>",
- *         self._fst.get().InputSymbols() if isymbols is None
- *         else isymbols._table,             # <<<<<<<<<<<<<<
- *         self._fst.get().OutputSymbols() if osymbols is None
- *         else osymbols._table,
+    /* "pywrapfst.pyx":1813
+ *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
+ *     if osymbols is not None:
+ *        _osymbols = osymbols._table             # <<<<<<<<<<<<<<
+ *     cdef fst.SymbolTable *_ssymbols = NULL
+ *     if ssymbols is not None:
  */
-    if (unlikely(((PyObject *)__pyx_v_isymbols) == Py_None)) {
+    if (unlikely(((PyObject *)__pyx_v_osymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 1737, __pyx_L1_error)
+      __PYX_ERR(0, 1813, __pyx_L1_error)
     }
-    __pyx_t_13 = __pyx_v_isymbols->_table;
+    __pyx_t_12 = __pyx_v_osymbols->_table;
+    __pyx_v__osymbols = __pyx_t_12;
+
+    /* "pywrapfst.pyx":1812
+ *        _isymbols = isymbols._table
+ *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
+ *     if osymbols is not None:             # <<<<<<<<<<<<<<
+ *        _osymbols = osymbols._table
+ *     cdef fst.SymbolTable *_ssymbols = NULL
+ */
   }
 
-  /* "pywrapfst.pyx":1738
- *         self._fst.get().InputSymbols() if isymbols is None
- *         else isymbols._table,
- *         self._fst.get().OutputSymbols() if osymbols is None             # <<<<<<<<<<<<<<
- *         else osymbols._table,
- *         ssymbols_ptr, acceptor, show_weight_one, tostring(missing_sym))
- */
-  __pyx_t_11 = (((PyObject *)__pyx_v_osymbols) == Py_None);
-  if ((__pyx_t_11 != 0)) {
-    if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-      __PYX_ERR(0, 1738, __pyx_L1_error)
+  /* "pywrapfst.pyx":1814
+ *     if osymbols is not None:
+ *        _osymbols = osymbols._table
+ *     cdef fst.SymbolTable *_ssymbols = NULL             # <<<<<<<<<<<<<<
+ *     if ssymbols is not None:
+ *       _ssymbols = ssymbols._table
+ */
+  __pyx_v__ssymbols = NULL;
+
+  /* "pywrapfst.pyx":1815
+ *        _osymbols = osymbols._table
+ *     cdef fst.SymbolTable *_ssymbols = NULL
+ *     if ssymbols is not None:             # <<<<<<<<<<<<<<
+ *       _ssymbols = ssymbols._table
+ *     if ssymbols is not None:
+ */
+  __pyx_t_10 = (((PyObject *)__pyx_v_ssymbols) != Py_None);
+  __pyx_t_11 = (__pyx_t_10 != 0);
+  if (__pyx_t_11) {
+
+    /* "pywrapfst.pyx":1816
+ *     cdef fst.SymbolTable *_ssymbols = NULL
+ *     if ssymbols is not None:
+ *       _ssymbols = ssymbols._table             # <<<<<<<<<<<<<<
+ *     if ssymbols is not None:
+ *       _ssymbols = ssymbols._table
+ */
+    if (unlikely(((PyObject *)__pyx_v_ssymbols) == Py_None)) {
+      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
+      __PYX_ERR(0, 1816, __pyx_L1_error)
     }
-    __pyx_t_14 = __pyx_v_self->_fst.get()->OutputSymbols();
-  } else {
+    __pyx_t_12 = __pyx_v_ssymbols->_table;
+    __pyx_v__ssymbols = __pyx_t_12;
 
-    /* "pywrapfst.pyx":1739
- *         else isymbols._table,
- *         self._fst.get().OutputSymbols() if osymbols is None
- *         else osymbols._table,             # <<<<<<<<<<<<<<
- *         ssymbols_ptr, acceptor, show_weight_one, tostring(missing_sym))
- *     return sstrm.str()
+    /* "pywrapfst.pyx":1815
+ *        _osymbols = osymbols._table
+ *     cdef fst.SymbolTable *_ssymbols = NULL
+ *     if ssymbols is not None:             # <<<<<<<<<<<<<<
+ *       _ssymbols = ssymbols._table
+ *     if ssymbols is not None:
  */
-    if (unlikely(((PyObject *)__pyx_v_osymbols) == Py_None)) {
+  }
+
+  /* "pywrapfst.pyx":1817
+ *     if ssymbols is not None:
+ *       _ssymbols = ssymbols._table
+ *     if ssymbols is not None:             # <<<<<<<<<<<<<<
+ *       _ssymbols = ssymbols._table
+ *     cdef stringstream sstrm
+ */
+  __pyx_t_11 = (((PyObject *)__pyx_v_ssymbols) != Py_None);
+  __pyx_t_10 = (__pyx_t_11 != 0);
+  if (__pyx_t_10) {
+
+    /* "pywrapfst.pyx":1818
+ *       _ssymbols = ssymbols._table
+ *     if ssymbols is not None:
+ *       _ssymbols = ssymbols._table             # <<<<<<<<<<<<<<
+ *     cdef stringstream sstrm
+ *     fst.Print(deref(self._fst),
+ */
+    if (unlikely(((PyObject *)__pyx_v_ssymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 1739, __pyx_L1_error)
+      __PYX_ERR(0, 1818, __pyx_L1_error)
     }
-    __pyx_t_14 = __pyx_v_osymbols->_table;
+    __pyx_t_12 = __pyx_v_ssymbols->_table;
+    __pyx_v__ssymbols = __pyx_t_12;
+
+    /* "pywrapfst.pyx":1817
+ *     if ssymbols is not None:
+ *       _ssymbols = ssymbols._table
+ *     if ssymbols is not None:             # <<<<<<<<<<<<<<
+ *       _ssymbols = ssymbols._table
+ *     cdef stringstream sstrm
+ */
   }
 
-  /* "pywrapfst.pyx":1740
- *         self._fst.get().OutputSymbols() if osymbols is None
- *         else osymbols._table,
- *         ssymbols_ptr, acceptor, show_weight_one, tostring(missing_sym))             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":1820
+ *       _ssymbols = ssymbols._table
+ *     cdef stringstream sstrm
+ *     fst.Print(deref(self._fst),             # <<<<<<<<<<<<<<
+ *               sstrm,
+ *               b"<pywrapfst>",
+ */
+  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
+    __PYX_ERR(0, 1820, __pyx_L1_error)
+  }
+
+  /* "pywrapfst.pyx":1828
+ *               acceptor,
+ *               show_weight_one,
+ *               tostring(missing_sym))             # <<<<<<<<<<<<<<
  *     return sstrm.str()
  * 
  */
-  __pyx_t_9 = __pyx_f_9pywrapfst_tostring(__pyx_v_missing_sym); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1740, __pyx_L1_error)
+  __pyx_t_9 = __pyx_f_9pywrapfst_tostring(__pyx_v_missing_sym); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1828, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1735
- *       ssymbols_ptr = ssymbols._table
+  /* "pywrapfst.pyx":1820
+ *       _ssymbols = ssymbols._table
  *     cdef stringstream sstrm
- *     fst.PrintFst(deref(self._fst), sstrm, b"<pywrapfst>",             # <<<<<<<<<<<<<<
- *         self._fst.get().InputSymbols() if isymbols is None
- *         else isymbols._table,
+ *     fst.Print(deref(self._fst),             # <<<<<<<<<<<<<<
+ *               sstrm,
+ *               b"<pywrapfst>",
  */
-  fst::script::PrintFst((*__pyx_v_self->_fst), __pyx_v_sstrm, __pyx_k_pywrapfst, __pyx_t_13, __pyx_t_14, __pyx_v_ssymbols_ptr, __pyx_v_acceptor, __pyx_v_show_weight_one, __pyx_t_9);
+  fst::script::Print((*__pyx_v_self->_fst), __pyx_v_sstrm, __pyx_k_pywrapfst, __pyx_v__isymbols, __pyx_v__osymbols, __pyx_v__ssymbols, __pyx_v_acceptor, __pyx_v_show_weight_one, __pyx_t_9);
 
-  /* "pywrapfst.pyx":1741
- *         else osymbols._table,
- *         ssymbols_ptr, acceptor, show_weight_one, tostring(missing_sym))
+  /* "pywrapfst.pyx":1829
+ *               show_weight_one,
+ *               tostring(missing_sym))
  *     return sstrm.str()             # <<<<<<<<<<<<<<
  * 
  *   cpdef bool verify(self):
@@ -20649,7 +21598,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":1706
+  /* "pywrapfst.pyx":1783
  *     return StateIterator(self)
  * 
  *   cpdef string text(self, _SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
@@ -20691,7 +21640,7 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_39text(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":1707
+    /* "pywrapfst.pyx":1784
  * 
  *   cpdef string text(self, _SymbolTable isymbols=None,
  *       _SymbolTable osymbols=None, _SymbolTable ssymbols=None,             # <<<<<<<<<<<<<<
@@ -20700,7 +21649,7 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_39text(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__10);
+    values[5] = ((PyObject *)__pyx_kp_b__8);
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
       const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
@@ -20759,7 +21708,7 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_39text(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, 1706, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "text") < 0)) __PYX_ERR(0, 1783, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -20783,10 +21732,10 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_39text(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, 1708, __pyx_L3_error)
+      __pyx_v_acceptor = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_acceptor == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1785, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1708
+      /* "pywrapfst.pyx":1785
  *   cpdef string text(self, _SymbolTable isymbols=None,
  *       _SymbolTable osymbols=None, _SymbolTable ssymbols=None,
  *       bool acceptor=False, bool show_weight_one=False, missing_sym=b""):             # <<<<<<<<<<<<<<
@@ -20796,7 +21745,7 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_39text(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, 1708, __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, 1785, __pyx_L3_error)
     } else {
       __pyx_v_show_weight_one = ((bool)0);
     }
@@ -20804,18 +21753,18 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_39text(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, 1706, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("text", 0, 0, 6, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1783, __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, 1706, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_osymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "osymbols", 0))) __PYX_ERR(0, 1707, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ssymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "ssymbols", 0))) __PYX_ERR(0, 1707, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_isymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "isymbols", 0))) __PYX_ERR(0, 1783, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_osymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "osymbols", 0))) __PYX_ERR(0, 1784, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ssymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "ssymbols", 0))) __PYX_ERR(0, 1784, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_4_Fst_38text(((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":1706
+  /* "pywrapfst.pyx":1783
  *     return StateIterator(self)
  * 
  *   cpdef string text(self, _SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
@@ -20848,7 +21797,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_38text(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_PyUnicode_string_to_py_std__in_string(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1706, __pyx_L1_error)
+  __pyx_t_3 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1783, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -20865,7 +21814,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_38text(struct __pyx_obj_9pywrapfst__F
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1743
+/* "pywrapfst.pyx":1831
  *     return sstrm.str()
  * 
  *   cpdef bool verify(self):             # <<<<<<<<<<<<<<
@@ -20892,7 +21841,7 @@ static bool __pyx_f_9pywrapfst_4_Fst_verify(struct __pyx_obj_9pywrapfst__Fst *__
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_verify); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1743, __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, 1831, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_4_Fst_41verify)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -20908,10 +21857,10 @@ static bool __pyx_f_9pywrapfst_4_Fst_verify(struct __pyx_obj_9pywrapfst__Fst *__
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1743, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1831, __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, 1743, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1831, __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 +21879,7 @@ static bool __pyx_f_9pywrapfst_4_Fst_verify(struct __pyx_obj_9pywrapfst__Fst *__
     #endif
   }
 
-  /* "pywrapfst.pyx":1752
+  /* "pywrapfst.pyx":1840
  *       True if the contents are sane, False otherwise.
  *     """
  *     return fst.Verify(deref(self._fst))             # <<<<<<<<<<<<<<
@@ -20939,12 +21888,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 '%.30s'", "_fst");
-    __PYX_ERR(0, 1752, __pyx_L1_error)
+    __PYX_ERR(0, 1840, __pyx_L1_error)
   }
   __pyx_r = fst::script::Verify((*__pyx_v_self->_fst));
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1743
+  /* "pywrapfst.pyx":1831
  *     return sstrm.str()
  * 
  *   cpdef bool verify(self):             # <<<<<<<<<<<<<<
@@ -20985,7 +21934,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_40verify(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, 1743, __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, 1831, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -21002,7 +21951,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_40verify(struct __pyx_obj_9pywrapfst_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1754
+/* "pywrapfst.pyx":1842
  *     return fst.Verify(deref(self._fst))
  * 
  *   cpdef string weight_type(self):             # <<<<<<<<<<<<<<
@@ -21029,7 +21978,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_weight_type(struct __pyx_obj_9pywrap
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_weight_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1754, __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, 1842, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_4_Fst_43weight_type)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -21045,10 +21994,10 @@ static std::string __pyx_f_9pywrapfst_4_Fst_weight_type(struct __pyx_obj_9pywrap
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1754, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1842, __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, 1754, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1842, __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;
@@ -21067,21 +22016,21 @@ static std::string __pyx_f_9pywrapfst_4_Fst_weight_type(struct __pyx_obj_9pywrap
     #endif
   }
 
-  /* "pywrapfst.pyx":1763
+  /* "pywrapfst.pyx":1851
  *       A string representing the weight type.
  *     """
  *     return self._fst.get().WeightType()             # <<<<<<<<<<<<<<
  * 
- *   cpdef void write(self, filename) except *:
+ *   cpdef void write(self, source) except *:
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1763, __pyx_L1_error)
+    __PYX_ERR(0, 1851, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_fst.get()->WeightType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1754
+  /* "pywrapfst.pyx":1842
  *     return fst.Verify(deref(self._fst))
  * 
  *   cpdef string weight_type(self):             # <<<<<<<<<<<<<<
@@ -21122,7 +22071,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_42weight_type(struct __pyx_obj_9pywra
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("weight_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_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, 1754, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_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, 1842, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -21139,16 +22088,16 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_42weight_type(struct __pyx_obj_9pywra
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1765
+/* "pywrapfst.pyx":1853
  *     return self._fst.get().WeightType()
  * 
- *   cpdef void write(self, filename) except *:             # <<<<<<<<<<<<<<
+ *   cpdef void write(self, source) except *:             # <<<<<<<<<<<<<<
  *     """
- *     write(self, filename)
+ *     write(self, source)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_45write(PyObject *__pyx_v_self, PyObject *__pyx_v_filename); /*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) {
+static PyObject *__pyx_pw_9pywrapfst_4_Fst_45write(PyObject *__pyx_v_self, PyObject *__pyx_v_source); /*proto*/
+static void __pyx_f_9pywrapfst_4_Fst_write(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -21167,7 +22116,7 @@ static void __pyx_f_9pywrapfst_4_Fst_write(struct __pyx_obj_9pywrapfst__Fst *__p
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write); 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_write); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1853, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_4_Fst_45write)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -21181,9 +22130,9 @@ static void __pyx_f_9pywrapfst_4_Fst_write(struct __pyx_obj_9pywrapfst__Fst *__p
             __Pyx_DECREF_SET(__pyx_t_3, function);
           }
         }
-        __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_filename) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_filename);
+        __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_source);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1765, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1853, __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;
@@ -21203,31 +22152,31 @@ static void __pyx_f_9pywrapfst_4_Fst_write(struct __pyx_obj_9pywrapfst__Fst *__p
     #endif
   }
 
-  /* "pywrapfst.pyx":1779
+  /* "pywrapfst.pyx":1867
  *       FstIOError: Write failed.
  *     """
- *     if not self._fst.get().Write(tostring(filename)):             # <<<<<<<<<<<<<<
- *       raise FstIOError("Write failed: {!r}".format(filename))
+ *     if not self._fst.get().Write(tostring(source)):             # <<<<<<<<<<<<<<
+ *       raise FstIOError("Write failed: {!r}".format(source))
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1779, __pyx_L1_error)
+    __PYX_ERR(0, 1867, __pyx_L1_error)
   }
-  __pyx_t_5 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1779, __pyx_L1_error)
+  __pyx_t_5 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1867, __pyx_L1_error)
   __pyx_t_6 = ((!(__pyx_v_self->_fst.get()->Write(__pyx_t_5) != 0)) != 0);
   if (unlikely(__pyx_t_6)) {
 
-    /* "pywrapfst.pyx":1780
+    /* "pywrapfst.pyx":1868
  *     """
- *     if not self._fst.get().Write(tostring(filename)):
- *       raise FstIOError("Write failed: {!r}".format(filename))             # <<<<<<<<<<<<<<
+ *     if not self._fst.get().Write(tostring(source)):
+ *       raise FstIOError("Write failed: {!r}".format(source))             # <<<<<<<<<<<<<<
  * 
  *   cpdef bytes write_to_string(self):
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1780, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1868, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Write_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1780, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Write_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1868, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __pyx_t_7 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) {
@@ -21239,9 +22188,9 @@ static void __pyx_f_9pywrapfst_4_Fst_write(struct __pyx_obj_9pywrapfst__Fst *__p
         __Pyx_DECREF_SET(__pyx_t_4, function);
       }
     }
-    __pyx_t_3 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_7, __pyx_v_filename) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_filename);
+    __pyx_t_3 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_7, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_source);
     __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1780, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1868, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __pyx_t_4 = NULL;
@@ -21257,28 +22206,28 @@ static void __pyx_f_9pywrapfst_4_Fst_write(struct __pyx_obj_9pywrapfst__Fst *__p
     __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1780, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1868, __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, 1780, __pyx_L1_error)
+    __PYX_ERR(0, 1868, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1779
+    /* "pywrapfst.pyx":1867
  *       FstIOError: Write failed.
  *     """
- *     if not self._fst.get().Write(tostring(filename)):             # <<<<<<<<<<<<<<
- *       raise FstIOError("Write failed: {!r}".format(filename))
+ *     if not self._fst.get().Write(tostring(source)):             # <<<<<<<<<<<<<<
+ *       raise FstIOError("Write failed: {!r}".format(source))
  * 
  */
   }
 
-  /* "pywrapfst.pyx":1765
+  /* "pywrapfst.pyx":1853
  *     return self._fst.get().WeightType()
  * 
- *   cpdef void write(self, filename) except *:             # <<<<<<<<<<<<<<
+ *   cpdef void write(self, source) except *:             # <<<<<<<<<<<<<<
  *     """
- *     write(self, filename)
+ *     write(self, source)
  */
 
   /* function exit code */
@@ -21295,27 +22244,27 @@ static void __pyx_f_9pywrapfst_4_Fst_write(struct __pyx_obj_9pywrapfst__Fst *__p
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_45write(PyObject *__pyx_v_self, PyObject *__pyx_v_filename); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_44write[] = "\n    write(self, filename)\n\n    Serializes FST to a file.\n\n    This method writes the FST to a file in a binary format.\n\n    Args:\n      filename: The string location of the output file.\n\n    Raises:\n      FstIOError: Write failed.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_45write(PyObject *__pyx_v_self, PyObject *__pyx_v_filename) {
+static PyObject *__pyx_pw_9pywrapfst_4_Fst_45write(PyObject *__pyx_v_self, PyObject *__pyx_v_source); /*proto*/
+static char __pyx_doc_9pywrapfst_4_Fst_44write[] = "\n    write(self, source)\n\n    Serializes FST to a file.\n\n    This method writes the FST to a file in a binary format.\n\n    Args:\n      source: The string location of the output file.\n\n    Raises:\n      FstIOError: Write failed.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_4_Fst_45write(PyObject *__pyx_v_self, PyObject *__pyx_v_source) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("write (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_4_Fst_44write(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self), ((PyObject *)__pyx_v_filename));
+  __pyx_r = __pyx_pf_9pywrapfst_4_Fst_44write(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self), ((PyObject *)__pyx_v_source));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_44write(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, PyObject *__pyx_v_filename) {
+static PyObject *__pyx_pf_9pywrapfst_4_Fst_44write(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, PyObject *__pyx_v_source) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   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, 1765, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1765, __pyx_L1_error)
+  __pyx_f_9pywrapfst_4_Fst_write(__pyx_v_self, __pyx_v_source, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1853, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1853, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -21332,8 +22281,8 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_44write(struct __pyx_obj_9pywrapfst__
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1782
- *       raise FstIOError("Write failed: {!r}".format(filename))
+/* "pywrapfst.pyx":1870
+ *       raise FstIOError("Write failed: {!r}".format(source))
  * 
  *   cpdef bytes write_to_string(self):             # <<<<<<<<<<<<<<
  *     """
@@ -21360,7 +22309,7 @@ static PyObject *__pyx_f_9pywrapfst_4_Fst_write_to_string(struct __pyx_obj_9pywr
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write_to_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1782, __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, 1870, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_4_Fst_47write_to_string)) {
         __Pyx_XDECREF(__pyx_r);
@@ -21377,10 +22326,10 @@ static PyObject *__pyx_f_9pywrapfst_4_Fst_write_to_string(struct __pyx_obj_9pywr
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1782, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1870, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(PyBytes_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_2)->tp_name), 0))) __PYX_ERR(0, 1782, __pyx_L1_error)
+        if (!(likely(PyBytes_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_2)->tp_name), 0))) __PYX_ERR(0, 1870, __pyx_L1_error)
         __pyx_r = ((PyObject*)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -21399,7 +22348,7 @@ static PyObject *__pyx_f_9pywrapfst_4_Fst_write_to_string(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":1797
+  /* "pywrapfst.pyx":1883
  *     """
  *     cdef stringstream sstrm
  *     if not self._fst.get().Write(sstrm, b"<pywrapfst>"):             # <<<<<<<<<<<<<<
@@ -21408,19 +22357,19 @@ static PyObject *__pyx_f_9pywrapfst_4_Fst_write_to_string(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1797, __pyx_L1_error)
+    __PYX_ERR(0, 1883, __pyx_L1_error)
   }
   __pyx_t_5 = ((!(__pyx_v_self->_fst.get()->Write(__pyx_v_sstrm, __pyx_k_pywrapfst) != 0)) != 0);
   if (unlikely(__pyx_t_5)) {
 
-    /* "pywrapfst.pyx":1798
+    /* "pywrapfst.pyx":1884
  *     cdef stringstream sstrm
  *     if not self._fst.get().Write(sstrm, b"<pywrapfst>"):
  *       raise FstIOError("Write to string failed")             # <<<<<<<<<<<<<<
  *     return sstrm.str()
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1798, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1884, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_3 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -21434,14 +22383,14 @@ static PyObject *__pyx_f_9pywrapfst_4_Fst_write_to_string(struct __pyx_obj_9pywr
     }
     __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_kp_u_Write_to_string_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_Write_to_string_failed);
     __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1798, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1884, __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, 1798, __pyx_L1_error)
+    __PYX_ERR(0, 1884, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1797
+    /* "pywrapfst.pyx":1883
  *     """
  *     cdef stringstream sstrm
  *     if not self._fst.get().Write(sstrm, b"<pywrapfst>"):             # <<<<<<<<<<<<<<
@@ -21450,7 +22399,7 @@ static PyObject *__pyx_f_9pywrapfst_4_Fst_write_to_string(struct __pyx_obj_9pywr
  */
   }
 
-  /* "pywrapfst.pyx":1799
+  /* "pywrapfst.pyx":1885
  *     if not self._fst.get().Write(sstrm, b"<pywrapfst>"):
  *       raise FstIOError("Write to string failed")
  *     return sstrm.str()             # <<<<<<<<<<<<<<
@@ -21458,14 +22407,14 @@ static PyObject *__pyx_f_9pywrapfst_4_Fst_write_to_string(struct __pyx_obj_9pywr
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_sstrm.str()); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1799, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_sstrm.str()); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1885, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((PyObject*)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1782
- *       raise FstIOError("Write failed: {!r}".format(filename))
+  /* "pywrapfst.pyx":1870
+ *       raise FstIOError("Write failed: {!r}".format(source))
  * 
  *   cpdef bytes write_to_string(self):             # <<<<<<<<<<<<<<
  *     """
@@ -21488,7 +22437,7 @@ static PyObject *__pyx_f_9pywrapfst_4_Fst_write_to_string(struct __pyx_obj_9pywr
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_47write_to_string(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_46write_to_string[] = "\n    write_to_string(self)\n\n    Serializes FST to a string.\n\n    Returns:\n      A bytestring.\n\n    Raises:\n      FstIOError: Write to string failed.\n\n    See also: `read_from_string`.\n    ";
+static char __pyx_doc_9pywrapfst_4_Fst_46write_to_string[] = "\n    write_to_string(self)\n\n    Serializes FST to a string.\n\n    Returns:\n      A bytestring.\n\n    Raises:\n      FstIOError: Write to string failed.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_47write_to_string(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -21506,7 +22455,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_46write_to_string(struct __pyx_obj_9p
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("write_to_string", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_4_Fst_write_to_string(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1782, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_4_Fst_write_to_string(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1870, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -21523,7 +22472,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_46write_to_string(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1812
+/* "pywrapfst.pyx":1898
  *   """
  * 
  *   cdef void _check_mutating_imethod(self) except *:             # <<<<<<<<<<<<<<
@@ -21539,7 +22488,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__check_mutating_imethod(struct __py
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("_check_mutating_imethod", 0);
 
-  /* "pywrapfst.pyx":1817
+  /* "pywrapfst.pyx":1903
  *     This function is not visible to Python users.
  *     """
  *     if self._fst.get().Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
@@ -21548,19 +22497,19 @@ 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 '%.30s'", "_fst");
-    __PYX_ERR(0, 1817, __pyx_L1_error)
+    __PYX_ERR(0, 1903, __pyx_L1_error)
   }
   __pyx_t_1 = ((__pyx_v_self->__pyx_base._fst.get()->Properties(fst::kError, 1) == fst::kError) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":1818
+    /* "pywrapfst.pyx":1904
  *     """
  *     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_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1818, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1904, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -21574,14 +22523,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__check_mutating_imethod(struct __py
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_Operation_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_Operation_failed);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1818, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1904, __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, 1818, __pyx_L1_error)
+    __PYX_ERR(0, 1904, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1817
+    /* "pywrapfst.pyx":1903
  *     This function is not visible to Python users.
  *     """
  *     if self._fst.get().Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
@@ -21590,7 +22539,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__check_mutating_imethod(struct __py
  */
   }
 
-  /* "pywrapfst.pyx":1812
+  /* "pywrapfst.pyx":1898
  *   """
  * 
  *   cdef void _check_mutating_imethod(self) except *:             # <<<<<<<<<<<<<<
@@ -21609,7 +22558,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__check_mutating_imethod(struct __py
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1820
+/* "pywrapfst.pyx":1906
  *       raise FstOpError("Operation failed")
  * 
  *   cdef void _add_arc(self, int64 state, Arc arc) except *:             # <<<<<<<<<<<<<<
@@ -21625,7 +22574,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__add_arc(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("_add_arc", 0);
 
-  /* "pywrapfst.pyx":1821
+  /* "pywrapfst.pyx":1907
  * 
  *   cdef void _add_arc(self, int64 state, Arc arc) except *:
  *     if not self._fst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -21634,19 +22583,19 @@ 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 '%.30s'", "_fst");
-    __PYX_ERR(0, 1821, __pyx_L1_error)
+    __PYX_ERR(0, 1907, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_self->__pyx_base._fst.get()->ValidStateId(__pyx_v_state) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":1822
+    /* "pywrapfst.pyx":1908
  *   cdef void _add_arc(self, int64 state, Arc arc) except *:
  *     if not self._fst.get().ValidStateId(state):
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     if not self._mfst.get().AddArc(state, deref(arc._arc)):
  *       raise FstOpError("Incompatible or invalid weight type")
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1822, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1908, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -21660,14 +22609,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__add_arc(struct __pyx_obj_9pywrapfs
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1822, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1908, __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, 1822, __pyx_L1_error)
+    __PYX_ERR(0, 1908, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1821
+    /* "pywrapfst.pyx":1907
  * 
  *   cdef void _add_arc(self, int64 state, Arc arc) except *:
  *     if not self._fst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -21676,7 +22625,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__add_arc(struct __pyx_obj_9pywrapfs
  */
   }
 
-  /* "pywrapfst.pyx":1823
+  /* "pywrapfst.pyx":1909
  *     if not self._fst.get().ValidStateId(state):
  *       raise FstIndexError("State index out of range")
  *     if not self._mfst.get().AddArc(state, deref(arc._arc)):             # <<<<<<<<<<<<<<
@@ -21685,23 +22634,23 @@ 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 '%.30s'", "_mfst");
-    __PYX_ERR(0, 1823, __pyx_L1_error)
+    __PYX_ERR(0, 1909, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_arc) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 1823, __pyx_L1_error)
+    __PYX_ERR(0, 1909, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->AddArc(__pyx_v_state, (*__pyx_v_arc->_arc)) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":1824
+    /* "pywrapfst.pyx":1910
  *       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_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1824, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1910, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -21715,14 +22664,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__add_arc(struct __pyx_obj_9pywrapfs
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_Incompatible_or_invalid_weight_t) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_Incompatible_or_invalid_weight_t);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1824, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1910, __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, 1824, __pyx_L1_error)
+    __PYX_ERR(0, 1910, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1823
+    /* "pywrapfst.pyx":1909
  *     if not self._fst.get().ValidStateId(state):
  *       raise FstIndexError("State index out of range")
  *     if not self._mfst.get().AddArc(state, deref(arc._arc)):             # <<<<<<<<<<<<<<
@@ -21731,7 +22680,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__add_arc(struct __pyx_obj_9pywrapfs
  */
   }
 
-  /* "pywrapfst.pyx":1825
+  /* "pywrapfst.pyx":1911
  *     if not self._mfst.get().AddArc(state, deref(arc._arc)):
  *       raise FstOpError("Incompatible or invalid weight type")
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -21740,11 +22689,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 '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 1825, __pyx_L1_error)
+    __PYX_ERR(0, 1911, __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, 1825, __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, 1911, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1820
+  /* "pywrapfst.pyx":1906
  *       raise FstOpError("Operation failed")
  * 
  *   cdef void _add_arc(self, int64 state, Arc arc) except *:             # <<<<<<<<<<<<<<
@@ -21763,7 +22712,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__add_arc(struct __pyx_obj_9pywrapfs
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1827
+/* "pywrapfst.pyx":1913
  *     self._check_mutating_imethod()
  * 
  *   def add_arc(self, int64 state, Arc arc):             # <<<<<<<<<<<<<<
@@ -21773,7 +22722,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__add_arc(struct __pyx_obj_9pywrapfs
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_1add_arc(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_add_arc[] = "\n    add_arc(self, state, arc)\n\n    Adds a new arc to the FST and return self.\n\n    Args:\n      state: The integer index of the source state.\n      arc: The arc to add.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n      FstOpdexError: Incompatible or invalid weight type.\n\n    See also: `add_state`.\n    ";
+static char __pyx_doc_9pywrapfst_11_MutableFst_add_arc[] = "\n    add_arc(self, state, arc)\n\n    Adds a new arc to the FST and return self.\n\n    Args:\n      state: The integer index of the source state.\n      arc: The arc to add.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n      FstOpdexError: Incompatible or invalid weight type.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_1add_arc(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   __pyx_t_10basictypes_int64 __pyx_v_state;
   struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc = 0;
@@ -21803,11 +22752,11 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_1add_arc(PyObject *__pyx_v_se
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_arc)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("add_arc", 1, 2, 2, 1); __PYX_ERR(0, 1827, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("add_arc", 1, 2, 2, 1); __PYX_ERR(0, 1913, __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, 1827, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add_arc") < 0)) __PYX_ERR(0, 1913, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -21815,18 +22764,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, 1827, __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, 1913, __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, 1827, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("add_arc", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1913, __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, 1827, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_arc), __pyx_ptype_9pywrapfst_Arc, 1, "arc", 0))) __PYX_ERR(0, 1913, __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 */
@@ -21843,8 +22792,8 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_add_arc(struct __pyx_obj_9pyw
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("add_arc", 0);
 
-  /* "pywrapfst.pyx":1846
- *     See also: `add_state`.
+  /* "pywrapfst.pyx":1930
+ *       FstOpdexError: Incompatible or invalid weight type.
  *     """
  *     self._add_arc(state, arc)             # <<<<<<<<<<<<<<
  *     return self
@@ -21852,11 +22801,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 '%.30s'", "_add_arc");
-    __PYX_ERR(0, 1846, __pyx_L1_error)
+    __PYX_ERR(0, 1930, __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, 1846, __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, 1930, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1847
+  /* "pywrapfst.pyx":1931
  *     """
  *     self._add_arc(state, arc)
  *     return self             # <<<<<<<<<<<<<<
@@ -21868,7 +22817,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":1827
+  /* "pywrapfst.pyx":1913
  *     self._check_mutating_imethod()
  * 
  *   def add_arc(self, int64 state, Arc arc):             # <<<<<<<<<<<<<<
@@ -21886,7 +22835,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_add_arc(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1849
+/* "pywrapfst.pyx":1933
  *     return self
  * 
  *   cpdef int64 add_state(self) except *:             # <<<<<<<<<<<<<<
@@ -21914,7 +22863,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_add_state(str
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add_state); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1849, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add_state); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1933, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_11_MutableFst_3add_state)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -21930,10 +22879,10 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_add_state(str
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1849, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1933, __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, 1849, __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, 1933, __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;
@@ -21952,8 +22901,8 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_add_state(str
     #endif
   }
 
-  /* "pywrapfst.pyx":1860
- *     See also: `add_arc`, `set_start`, `set_final`.
+  /* "pywrapfst.pyx":1942
+ *       The integer index of the new state.
  *     """
  *     cdef int64 result = self._mfst.get().AddState()             # <<<<<<<<<<<<<<
  *     self._check_mutating_imethod()
@@ -21961,11 +22910,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 '%.30s'", "_mfst");
-    __PYX_ERR(0, 1860, __pyx_L1_error)
+    __PYX_ERR(0, 1942, __pyx_L1_error)
   }
   __pyx_v_result = __pyx_v_self->_mfst.get()->AddState();
 
-  /* "pywrapfst.pyx":1861
+  /* "pywrapfst.pyx":1943
  *     """
  *     cdef int64 result = self._mfst.get().AddState()
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -21974,11 +22923,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 '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 1861, __pyx_L1_error)
+    __PYX_ERR(0, 1943, __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, 1861, __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, 1943, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1862
+  /* "pywrapfst.pyx":1944
  *     cdef int64 result = self._mfst.get().AddState()
  *     self._check_mutating_imethod()
  *     return result             # <<<<<<<<<<<<<<
@@ -21988,7 +22937,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_add_state(str
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1849
+  /* "pywrapfst.pyx":1933
  *     return self
  * 
  *   cpdef int64 add_state(self) except *:             # <<<<<<<<<<<<<<
@@ -22011,7 +22960,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_add_state(str
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_3add_state(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_2add_state[] = "\n    add_state(self)\n\n    Adds a new state to the FST and returns the state ID.\n\n    Returns:\n      The integer index of the new state.\n\n    See also: `add_arc`, `set_start`, `set_final`.\n    ";
+static char __pyx_doc_9pywrapfst_11_MutableFst_2add_state[] = "\n    add_state(self)\n\n    Adds a new state to the FST and returns the state ID.\n\n    Returns:\n      The integer index of the new state.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_3add_state(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -22030,8 +22979,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, 1849, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1849, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_11_MutableFst_add_state(__pyx_v_self, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1933, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1933, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -22048,7 +22997,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_2add_state(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1864
+/* "pywrapfst.pyx":1946
  *     return result
  * 
  *   cpdef void add_states(self, size_t n) except *:             # <<<<<<<<<<<<<<
@@ -22074,10 +23023,10 @@ static void __pyx_f_9pywrapfst_11_MutableFst_add_states(struct __pyx_obj_9pywrap
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1864, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1946, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_11_MutableFst_5add_states)) {
-        __pyx_t_3 = __Pyx_PyInt_FromSize_t(__pyx_v_n); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1864, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_FromSize_t(__pyx_v_n); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1946, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -22093,7 +23042,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst_add_states(struct __pyx_obj_9pywrap
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1864, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1946, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -22113,7 +23062,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst_add_states(struct __pyx_obj_9pywrap
     #endif
   }
 
-  /* "pywrapfst.pyx":1873
+  /* "pywrapfst.pyx":1955
  *       n: The number of states to add.
  *     """
  *     self._mfst.get().AddStates(n)             # <<<<<<<<<<<<<<
@@ -22122,11 +23071,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst_add_states(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 1873, __pyx_L1_error)
+    __PYX_ERR(0, 1955, __pyx_L1_error)
   }
   __pyx_v_self->_mfst.get()->AddStates(__pyx_v_n);
 
-  /* "pywrapfst.pyx":1874
+  /* "pywrapfst.pyx":1956
  *     """
  *     self._mfst.get().AddStates(n)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -22135,11 +23084,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst_add_states(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 1874, __pyx_L1_error)
+    __PYX_ERR(0, 1956, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1874, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1956, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1864
+  /* "pywrapfst.pyx":1946
  *     return result
  * 
  *   cpdef void add_states(self, size_t n) except *:             # <<<<<<<<<<<<<<
@@ -22169,7 +23118,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_5add_states(PyObject *__pyx_v
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("add_states (wrapper)", 0);
   assert(__pyx_arg_n); {
-    __pyx_v_n = __Pyx_PyInt_As_size_t(__pyx_arg_n); if (unlikely((__pyx_v_n == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1864, __pyx_L3_error)
+    __pyx_v_n = __Pyx_PyInt_As_size_t(__pyx_arg_n); if (unlikely((__pyx_v_n == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1946, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -22190,8 +23139,8 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_4add_states(struct __pyx_obj_
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("add_states", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_f_9pywrapfst_11_MutableFst_add_states(__pyx_v_self, __pyx_v_n, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1864, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1864, __pyx_L1_error)
+  __pyx_f_9pywrapfst_11_MutableFst_add_states(__pyx_v_self, __pyx_v_n, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1946, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1946, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -22208,7 +23157,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_4add_states(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1876
+/* "pywrapfst.pyx":1958
  *     self._check_mutating_imethod()
  * 
  *   cdef void _arcsort(self, sort_type=b"ilabel") except *:             # <<<<<<<<<<<<<<
@@ -22234,27 +23183,27 @@ static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfs
     }
   }
 
-  /* "pywrapfst.pyx":1878
+  /* "pywrapfst.pyx":1960
  *   cdef void _arcsort(self, sort_type=b"ilabel") except *:
  *     cdef fst.ArcSortType sort_type_enum
  *     if not fst.GetArcSortType(tostring(sort_type), addr(sort_type_enum)):             # <<<<<<<<<<<<<<
  *       raise FstArgError("Unknown sort type {!r}".format(sort_type))
  *     fst.ArcSort(self._mfst.get(), sort_type_enum)
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_sort_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1878, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_sort_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1960, __pyx_L1_error)
   __pyx_t_2 = ((!(fst::script::GetArcSortType(__pyx_t_1, (&__pyx_v_sort_type_enum)) != 0)) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":1879
+    /* "pywrapfst.pyx":1961
  *     cdef fst.ArcSortType sort_type_enum
  *     if not fst.GetArcSortType(tostring(sort_type), addr(sort_type_enum)):
  *       raise FstArgError("Unknown sort type {!r}".format(sort_type))             # <<<<<<<<<<<<<<
  *     fst.ArcSort(self._mfst.get(), sort_type_enum)
  *     self._check_mutating_imethod()
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1879, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1961, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Unknown_sort_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1879, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Unknown_sort_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1961, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __pyx_t_7 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
@@ -22268,7 +23217,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfs
     }
     __pyx_t_5 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_v_sort_type) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_sort_type);
     __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1879, __pyx_L1_error)
+    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1961, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __pyx_t_6 = NULL;
@@ -22284,14 +23233,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfs
     __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5);
     __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1879, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1961, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 1879, __pyx_L1_error)
+    __PYX_ERR(0, 1961, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1878
+    /* "pywrapfst.pyx":1960
  *   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)):             # <<<<<<<<<<<<<<
@@ -22300,7 +23249,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfs
  */
   }
 
-  /* "pywrapfst.pyx":1880
+  /* "pywrapfst.pyx":1962
  *     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)             # <<<<<<<<<<<<<<
@@ -22309,11 +23258,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 1880, __pyx_L1_error)
+    __PYX_ERR(0, 1962, __pyx_L1_error)
   }
   fst::script::ArcSort(__pyx_v_self->_mfst.get(), __pyx_v_sort_type_enum);
 
-  /* "pywrapfst.pyx":1881
+  /* "pywrapfst.pyx":1963
  *       raise FstArgError("Unknown sort type {!r}".format(sort_type))
  *     fst.ArcSort(self._mfst.get(), sort_type_enum)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -22322,11 +23271,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 1881, __pyx_L1_error)
+    __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, 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, 1963, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1876
+  /* "pywrapfst.pyx":1958
  *     self._check_mutating_imethod()
  * 
  *   cdef void _arcsort(self, sort_type=b"ilabel") except *:             # <<<<<<<<<<<<<<
@@ -22347,7 +23296,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfs
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1883
+/* "pywrapfst.pyx":1965
  *     self._check_mutating_imethod()
  * 
  *   def arcsort(self, sort_type=b"ilabel"):             # <<<<<<<<<<<<<<
@@ -22385,7 +23334,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_7arcsort(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, 1883, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "arcsort") < 0)) __PYX_ERR(0, 1965, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -22399,7 +23348,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_7arcsort(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, 1883, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("arcsort", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1965, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.arcsort", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -22418,7 +23367,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_6arcsort(struct __pyx_obj_9py
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__arcsort __pyx_t_1;
   __Pyx_RefNannySetupContext("arcsort", 0);
 
-  /* "pywrapfst.pyx":1902
+  /* "pywrapfst.pyx":1984
  *       FstArgError: Unknown sort type.
  *     """
  *     self._arcsort(sort_type)             # <<<<<<<<<<<<<<
@@ -22427,13 +23376,13 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_6arcsort(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arcsort");
-    __PYX_ERR(0, 1902, __pyx_L1_error)
+    __PYX_ERR(0, 1984, __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, 1902, __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, 1984, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1903
+  /* "pywrapfst.pyx":1985
  *     """
  *     self._arcsort(sort_type)
  *     return self             # <<<<<<<<<<<<<<
@@ -22445,7 +23394,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_6arcsort(struct __pyx_obj_9py
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1883
+  /* "pywrapfst.pyx":1965
  *     self._check_mutating_imethod()
  * 
  *   def arcsort(self, sort_type=b"ilabel"):             # <<<<<<<<<<<<<<
@@ -22463,7 +23412,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_6arcsort(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1905
+/* "pywrapfst.pyx":1987
  *     return self
  * 
  *   cdef void _closure(self, bool closure_plus=False) except *:             # <<<<<<<<<<<<<<
@@ -22481,7 +23430,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__closure(struct __pyx_obj_9pywrapfs
     }
   }
 
-  /* "pywrapfst.pyx":1906
+  /* "pywrapfst.pyx":1988
  * 
  *   cdef void _closure(self, bool closure_plus=False) except *:
  *     fst.Closure(self._mfst.get(), fst.GetClosureType(closure_plus))             # <<<<<<<<<<<<<<
@@ -22490,11 +23439,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__closure(struct __pyx_obj_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 1906, __pyx_L1_error)
+    __PYX_ERR(0, 1988, __pyx_L1_error)
   }
   fst::script::Closure(__pyx_v_self->_mfst.get(), fst::script::GetClosureType(__pyx_v_closure_plus));
 
-  /* "pywrapfst.pyx":1907
+  /* "pywrapfst.pyx":1989
  *   cdef void _closure(self, bool closure_plus=False) except *:
  *     fst.Closure(self._mfst.get(), fst.GetClosureType(closure_plus))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -22503,11 +23452,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__closure(struct __pyx_obj_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 1907, __pyx_L1_error)
+    __PYX_ERR(0, 1989, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1907, __pyx_L1_error)
+  ((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, 1989, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1905
+  /* "pywrapfst.pyx":1987
  *     return self
  * 
  *   cdef void _closure(self, bool closure_plus=False) except *:             # <<<<<<<<<<<<<<
@@ -22523,7 +23472,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__closure(struct __pyx_obj_9pywrapfs
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1909
+/* "pywrapfst.pyx":1991
  *     self._check_mutating_imethod()
  * 
  *   def closure(self, bool closure_plus=False):             # <<<<<<<<<<<<<<
@@ -22560,7 +23509,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_9closure(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, 1909, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "closure") < 0)) __PYX_ERR(0, 1991, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -22571,14 +23520,14 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_9closure(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, 1909, __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, 1991, __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, 1909, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("closure", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1991, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.closure", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -22597,7 +23546,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_8closure(struct __pyx_obj_9py
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__closure __pyx_t_1;
   __Pyx_RefNannySetupContext("closure", 0);
 
-  /* "pywrapfst.pyx":1927
+  /* "pywrapfst.pyx":2009
  *       self.
  *     """
  *     self._closure(closure_plus)             # <<<<<<<<<<<<<<
@@ -22606,25 +23555,25 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_8closure(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_closure");
-    __PYX_ERR(0, 1927, __pyx_L1_error)
+    __PYX_ERR(0, 2009, __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, 1927, __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, 2009, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1928
+  /* "pywrapfst.pyx":2010
  *     """
  *     self._closure(closure_plus)
  *     return self             # <<<<<<<<<<<<<<
  * 
- *   cdef void _concat(self, _Fst ifst) except *:
+ *   cdef void _concat(self, _Fst fst2) except *:
  */
   __Pyx_XDECREF(__pyx_r);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1909
+  /* "pywrapfst.pyx":1991
  *     self._check_mutating_imethod()
  * 
  *   def closure(self, bool closure_plus=False):             # <<<<<<<<<<<<<<
@@ -22642,53 +23591,53 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_8closure(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1930
+/* "pywrapfst.pyx":2012
  *     return self
  * 
- *   cdef void _concat(self, _Fst ifst) except *:             # <<<<<<<<<<<<<<
- *     fst.Concat(self._mfst.get(), deref(ifst._fst))
+ *   cdef void _concat(self, _Fst fst2) except *:             # <<<<<<<<<<<<<<
+ *     fst.Concat(self._mfst.get(), deref(fst2._fst))
  *     self._check_mutating_imethod()
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__concat(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst) {
+static void __pyx_f_9pywrapfst_11_MutableFst__concat(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_fst2) {
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_concat", 0);
 
-  /* "pywrapfst.pyx":1931
+  /* "pywrapfst.pyx":2013
  * 
- *   cdef void _concat(self, _Fst ifst) except *:
- *     fst.Concat(self._mfst.get(), deref(ifst._fst))             # <<<<<<<<<<<<<<
+ *   cdef void _concat(self, _Fst fst2) except *:
+ *     fst.Concat(self._mfst.get(), deref(fst2._fst))             # <<<<<<<<<<<<<<
  *     self._check_mutating_imethod()
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 1931, __pyx_L1_error)
+    __PYX_ERR(0, 2013, __pyx_L1_error)
   }
-  if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v_fst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1931, __pyx_L1_error)
+    __PYX_ERR(0, 2013, __pyx_L1_error)
   }
-  fst::script::Concat(__pyx_v_self->_mfst.get(), (*__pyx_v_ifst->_fst));
+  fst::script::Concat(__pyx_v_self->_mfst.get(), (*__pyx_v_fst2->_fst));
 
-  /* "pywrapfst.pyx":1932
- *   cdef void _concat(self, _Fst ifst) except *:
- *     fst.Concat(self._mfst.get(), deref(ifst._fst))
+  /* "pywrapfst.pyx":2014
+ *   cdef void _concat(self, _Fst fst2) except *:
+ *     fst.Concat(self._mfst.get(), deref(fst2._fst))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
  * 
- *   def concat(self, _Fst ifst):
+ *   def concat(self, _Fst fst2):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 1932, __pyx_L1_error)
+    __PYX_ERR(0, 2014, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1932, __pyx_L1_error)
+  ((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, 2014, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1930
+  /* "pywrapfst.pyx":2012
  *     return self
  * 
- *   cdef void _concat(self, _Fst ifst) except *:             # <<<<<<<<<<<<<<
- *     fst.Concat(self._mfst.get(), deref(ifst._fst))
+ *   cdef void _concat(self, _Fst fst2) except *:             # <<<<<<<<<<<<<<
+ *     fst.Concat(self._mfst.get(), deref(fst2._fst))
  *     self._check_mutating_imethod()
  */
 
@@ -22700,23 +23649,23 @@ static void __pyx_f_9pywrapfst_11_MutableFst__concat(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1934
+/* "pywrapfst.pyx":2016
  *     self._check_mutating_imethod()
  * 
- *   def concat(self, _Fst ifst):             # <<<<<<<<<<<<<<
+ *   def concat(self, _Fst fst2):             # <<<<<<<<<<<<<<
  *     """
- *     concat(self, ifst)
+ *     concat(self, fst2)
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_11concat(PyObject *__pyx_v_self, PyObject *__pyx_v_ifst); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_10concat[] = "\n    concat(self, ifst)\n\n    Computes the concatenation (product) of two FSTs.\n\n    This operation destructively concatenates the FST with a second FST. If A\n    transduces string x to y with weight a and B transduces string w to v with\n    weight b, then their concatenation transduces string xw to yv with weight a\n    \\otimes b.\n\n    Args:\n      ifst: The second input FST.\n\n    Returns:\n      self.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_11concat(PyObject *__pyx_v_self, PyObject *__pyx_v_ifst) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_11concat(PyObject *__pyx_v_self, PyObject *__pyx_v_fst2); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_10concat[] = "\n    concat(self, fst2)\n\n    Computes the concatenation (product) of two FSTs.\n\n    This operation destructively concatenates the FST with a second FST. If A\n    transduces string x to y with weight a and B transduces string w to v with\n    weight b, then their concatenation transduces string xw to yv with weight a\n    \\otimes b.\n\n    Args:\n      fst2: The second input FST.\n\n    Returns:\n      self.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_11concat(PyObject *__pyx_v_self, PyObject *__pyx_v_fst2) {
   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, 1934, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_10concat(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_ifst));
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_fst2), __pyx_ptype_9pywrapfst__Fst, 1, "fst2", 0))) __PYX_ERR(0, 2016, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_10concat(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_fst2));
 
   /* function exit code */
   goto __pyx_L0;
@@ -22727,27 +23676,27 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_11concat(PyObject *__pyx_v_se
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_10concat(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_10concat(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_fst2) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("concat", 0);
 
-  /* "pywrapfst.pyx":1951
+  /* "pywrapfst.pyx":2033
  *       self.
  *     """
- *     self._concat(ifst)             # <<<<<<<<<<<<<<
+ *     self._concat(fst2)             # <<<<<<<<<<<<<<
  *     return self
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_concat");
-    __PYX_ERR(0, 1951, __pyx_L1_error)
+    __PYX_ERR(0, 2033, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_concat(__pyx_v_self, __pyx_v_ifst); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1951, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_concat(__pyx_v_self, __pyx_v_fst2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2033, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1952
+  /* "pywrapfst.pyx":2034
  *     """
- *     self._concat(ifst)
+ *     self._concat(fst2)
  *     return self             # <<<<<<<<<<<<<<
  * 
  *   cdef void _connect(self) except *:
@@ -22757,12 +23706,12 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_10concat(struct __pyx_obj_9py
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1934
+  /* "pywrapfst.pyx":2016
  *     self._check_mutating_imethod()
  * 
- *   def concat(self, _Fst ifst):             # <<<<<<<<<<<<<<
+ *   def concat(self, _Fst fst2):             # <<<<<<<<<<<<<<
  *     """
- *     concat(self, ifst)
+ *     concat(self, fst2)
  */
 
   /* function exit code */
@@ -22775,7 +23724,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_10concat(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1954
+/* "pywrapfst.pyx":2036
  *     return self
  * 
  *   cdef void _connect(self) except *:             # <<<<<<<<<<<<<<
@@ -22787,7 +23736,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__connect(struct __pyx_obj_9pywrapfs
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_connect", 0);
 
-  /* "pywrapfst.pyx":1955
+  /* "pywrapfst.pyx":2037
  * 
  *   cdef void _connect(self) except *:
  *     fst.Connect(self._mfst.get())             # <<<<<<<<<<<<<<
@@ -22796,11 +23745,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__connect(struct __pyx_obj_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 1955, __pyx_L1_error)
+    __PYX_ERR(0, 2037, __pyx_L1_error)
   }
   fst::script::Connect(__pyx_v_self->_mfst.get());
 
-  /* "pywrapfst.pyx":1956
+  /* "pywrapfst.pyx":2038
  *   cdef void _connect(self) except *:
  *     fst.Connect(self._mfst.get())
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -22809,11 +23758,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__connect(struct __pyx_obj_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 1956, __pyx_L1_error)
+    __PYX_ERR(0, 2038, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1956, __pyx_L1_error)
+  ((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, 2038, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1954
+  /* "pywrapfst.pyx":2036
  *     return self
  * 
  *   cdef void _connect(self) except *:             # <<<<<<<<<<<<<<
@@ -22829,7 +23778,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__connect(struct __pyx_obj_9pywrapfs
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1958
+/* "pywrapfst.pyx":2040
  *     self._check_mutating_imethod()
  * 
  *   def connect(self):             # <<<<<<<<<<<<<<
@@ -22856,7 +23805,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_12connect(struct __pyx_obj_9p
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("connect", 0);
 
-  /* "pywrapfst.pyx":1970
+  /* "pywrapfst.pyx":2052
  *       self.
  *     """
  *     self._connect()             # <<<<<<<<<<<<<<
@@ -22865,23 +23814,23 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_12connect(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_connect");
-    __PYX_ERR(0, 1970, __pyx_L1_error)
+    __PYX_ERR(0, 2052, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_connect(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1970, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_connect(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2052, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1971
+  /* "pywrapfst.pyx":2053
  *     """
  *     self._connect()
  *     return self             # <<<<<<<<<<<<<<
  * 
- *   cdef void _decode(self, EncodeMapper encoder) except *:
+ *   cdef void _decode(self, EncodeMapper mapper) except *:
  */
   __Pyx_XDECREF(__pyx_r);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1958
+  /* "pywrapfst.pyx":2040
  *     self._check_mutating_imethod()
  * 
  *   def connect(self):             # <<<<<<<<<<<<<<
@@ -22899,53 +23848,53 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_12connect(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1973
+/* "pywrapfst.pyx":2055
  *     return self
  * 
- *   cdef void _decode(self, EncodeMapper encoder) except *:             # <<<<<<<<<<<<<<
- *     fst.Decode(self._mfst.get(), deref(encoder._encoder))
+ *   cdef void _decode(self, EncodeMapper mapper) except *:             # <<<<<<<<<<<<<<
+ *     fst.Decode(self._mfst.get(), deref(mapper._mapper))
  *     self._check_mutating_imethod()
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__decode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_encoder) {
+static void __pyx_f_9pywrapfst_11_MutableFst__decode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_mapper) {
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_decode", 0);
 
-  /* "pywrapfst.pyx":1974
+  /* "pywrapfst.pyx":2056
  * 
- *   cdef void _decode(self, EncodeMapper encoder) except *:
- *     fst.Decode(self._mfst.get(), deref(encoder._encoder))             # <<<<<<<<<<<<<<
+ *   cdef void _decode(self, EncodeMapper mapper) except *:
+ *     fst.Decode(self._mfst.get(), deref(mapper._mapper))             # <<<<<<<<<<<<<<
  *     self._check_mutating_imethod()
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 1974, __pyx_L1_error)
+    __PYX_ERR(0, 2056, __pyx_L1_error)
   }
-  if (unlikely(((PyObject *)__pyx_v_encoder) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_encoder");
-    __PYX_ERR(0, 1974, __pyx_L1_error)
+  if (unlikely(((PyObject *)__pyx_v_mapper) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
+    __PYX_ERR(0, 2056, __pyx_L1_error)
   }
-  fst::script::Decode(__pyx_v_self->_mfst.get(), (*__pyx_v_encoder->_encoder));
+  fst::script::Decode(__pyx_v_self->_mfst.get(), (*__pyx_v_mapper->_mapper));
 
-  /* "pywrapfst.pyx":1975
- *   cdef void _decode(self, EncodeMapper encoder) except *:
- *     fst.Decode(self._mfst.get(), deref(encoder._encoder))
+  /* "pywrapfst.pyx":2057
+ *   cdef void _decode(self, EncodeMapper mapper) except *:
+ *     fst.Decode(self._mfst.get(), deref(mapper._mapper))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
  * 
- *   def decode(self, EncodeMapper encoder):
+ *   def decode(self, EncodeMapper mapper):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 1975, __pyx_L1_error)
+    __PYX_ERR(0, 2057, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1975, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2057, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1973
+  /* "pywrapfst.pyx":2055
  *     return self
  * 
- *   cdef void _decode(self, EncodeMapper encoder) except *:             # <<<<<<<<<<<<<<
- *     fst.Decode(self._mfst.get(), deref(encoder._encoder))
+ *   cdef void _decode(self, EncodeMapper mapper) except *:             # <<<<<<<<<<<<<<
+ *     fst.Decode(self._mfst.get(), deref(mapper._mapper))
  *     self._check_mutating_imethod()
  */
 
@@ -22957,23 +23906,23 @@ static void __pyx_f_9pywrapfst_11_MutableFst__decode(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1977
+/* "pywrapfst.pyx":2059
  *     self._check_mutating_imethod()
  * 
- *   def decode(self, EncodeMapper encoder):             # <<<<<<<<<<<<<<
+ *   def decode(self, EncodeMapper mapper):             # <<<<<<<<<<<<<<
  *     """
- *     decode(self, encoder)
+ *     decode(self, mapper)
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_15decode(PyObject *__pyx_v_self, PyObject *__pyx_v_encoder); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_14decode[] = "\n    decode(self, encoder)\n\n    Decodes encoded labels and/or weights.\n\n    This operation reverses the encoding performed by `encode`.\n\n    Args:\n      encoder: An EncodeMapper object used to encode the FST.\n\n    Returns:\n      self.\n\n    See also: `encode`.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_15decode(PyObject *__pyx_v_self, PyObject *__pyx_v_encoder) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_15decode(PyObject *__pyx_v_self, PyObject *__pyx_v_mapper); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_14decode[] = "\n    decode(self, mapper)\n\n    Decodes encoded labels and/or weights.\n\n    This operation reverses the encoding performed by `encode`.\n\n    Args:\n      mapper: An EncodeMapper object used to encode the FST.\n\n    Returns:\n      self.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_15decode(PyObject *__pyx_v_self, PyObject *__pyx_v_mapper) {
   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, 1977, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_14decode(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_encoder));
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_mapper), __pyx_ptype_9pywrapfst_EncodeMapper, 1, "mapper", 0))) __PYX_ERR(0, 2059, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_14decode(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_mapper));
 
   /* function exit code */
   goto __pyx_L0;
@@ -22984,27 +23933,27 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_15decode(PyObject *__pyx_v_se
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_14decode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_encoder) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_14decode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_mapper) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("decode", 0);
 
-  /* "pywrapfst.pyx":1993
- *     See also: `encode`.
+  /* "pywrapfst.pyx":2073
+ *       self.
  *     """
- *     self._decode(encoder)             # <<<<<<<<<<<<<<
+ *     self._decode(mapper)             # <<<<<<<<<<<<<<
  *     return self
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_decode");
-    __PYX_ERR(0, 1993, __pyx_L1_error)
+    __PYX_ERR(0, 2073, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_decode(__pyx_v_self, __pyx_v_encoder); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1993, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_decode(__pyx_v_self, __pyx_v_mapper); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2073, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1994
+  /* "pywrapfst.pyx":2074
  *     """
- *     self._decode(encoder)
+ *     self._decode(mapper)
  *     return self             # <<<<<<<<<<<<<<
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:
@@ -23014,12 +23963,12 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_14decode(struct __pyx_obj_9py
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1977
+  /* "pywrapfst.pyx":2059
  *     self._check_mutating_imethod()
  * 
- *   def decode(self, EncodeMapper encoder):             # <<<<<<<<<<<<<<
+ *   def decode(self, EncodeMapper mapper):             # <<<<<<<<<<<<<<
  *     """
- *     decode(self, encoder)
+ *     decode(self, mapper)
  */
 
   /* function exit code */
@@ -23032,7 +23981,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_14decode(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1996
+/* "pywrapfst.pyx":2076
  *     return self
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:             # <<<<<<<<<<<<<<
@@ -23055,7 +24004,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_arcs(struct __pyx_obj_9pywr
     }
   }
 
-  /* "pywrapfst.pyx":1997
+  /* "pywrapfst.pyx":2077
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:
  *     if not (self._mfst.get().DeleteArcs(state, n) if n else             # <<<<<<<<<<<<<<
@@ -23065,12 +24014,12 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_arcs(struct __pyx_obj_9pywr
   if ((__pyx_v_n != 0)) {
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-      __PYX_ERR(0, 1997, __pyx_L1_error)
+      __PYX_ERR(0, 2077, __pyx_L1_error)
     }
     __pyx_t_1 = __pyx_v_self->_mfst.get()->DeleteArcs(__pyx_v_state, __pyx_v_n);
   } else {
 
-    /* "pywrapfst.pyx":1998
+    /* "pywrapfst.pyx":2078
  *   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)):             # <<<<<<<<<<<<<<
@@ -23079,12 +24028,12 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_arcs(struct __pyx_obj_9pywr
  */
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-      __PYX_ERR(0, 1998, __pyx_L1_error)
+      __PYX_ERR(0, 2078, __pyx_L1_error)
     }
     __pyx_t_1 = __pyx_v_self->_mfst.get()->DeleteArcs(__pyx_v_state);
   }
 
-  /* "pywrapfst.pyx":1997
+  /* "pywrapfst.pyx":2077
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:
  *     if not (self._mfst.get().DeleteArcs(state, n) if n else             # <<<<<<<<<<<<<<
@@ -23094,14 +24043,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_arcs(struct __pyx_obj_9pywr
   __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":1999
+    /* "pywrapfst.pyx":2079
  *     if not (self._mfst.get().DeleteArcs(state, n) if n else
  *             self._mfst.get().DeleteArcs(state)):
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     self._check_mutating_imethod()
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1999, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2079, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __pyx_t_5 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
@@ -23115,14 +24064,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_arcs(struct __pyx_obj_9pywr
     }
     __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1999, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2079, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 1999, __pyx_L1_error)
+    __PYX_ERR(0, 2079, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1997
+    /* "pywrapfst.pyx":2077
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:
  *     if not (self._mfst.get().DeleteArcs(state, n) if n else             # <<<<<<<<<<<<<<
@@ -23131,7 +24080,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_arcs(struct __pyx_obj_9pywr
  */
   }
 
-  /* "pywrapfst.pyx":2000
+  /* "pywrapfst.pyx":2080
  *             self._mfst.get().DeleteArcs(state)):
  *       raise FstIndexError("State index out of range")
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -23140,11 +24089,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_arcs(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2000, __pyx_L1_error)
+    __PYX_ERR(0, 2080, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2000, __pyx_L1_error)
+  ((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, 2080, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1996
+  /* "pywrapfst.pyx":2076
  *     return self
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:             # <<<<<<<<<<<<<<
@@ -23163,7 +24112,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_arcs(struct __pyx_obj_9pywr
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2002
+/* "pywrapfst.pyx":2082
  *     self._check_mutating_imethod()
  * 
  *   def delete_arcs(self, int64 state, size_t n=0):             # <<<<<<<<<<<<<<
@@ -23173,7 +24122,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_arcs(struct __pyx_obj_9pywr
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_17delete_arcs(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_16delete_arcs[] = "\n    delete_arcs(self, state, n=0)\n\n    Deletes arcs leaving a particular state.\n\n    Args:\n      state: The integer index of a state.\n      n: An optional argument indicating how many arcs to be deleted. If this\n          argument is omitted or passed as zero, all arcs from this state are\n          deleted.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n\n    See also: `delete_states`.\n    ";
+static char __pyx_doc_9pywrapfst_11_MutableFst_16delete_arcs[] = "\n    delete_arcs(self, state, n=0)\n\n    Deletes arcs leaving a particular state.\n\n    Args:\n      state: The integer index of a state.\n      n: An optional argument indicating how many arcs to be deleted. If this\n          argument is omitted or passed as zero, all arcs from this state are\n          deleted.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_17delete_arcs(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   __pyx_t_10basictypes_int64 __pyx_v_state;
   size_t __pyx_v_n;
@@ -23207,7 +24156,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_17delete_arcs(PyObject *__pyx
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "delete_arcs") < 0)) __PYX_ERR(0, 2002, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "delete_arcs") < 0)) __PYX_ERR(0, 2082, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -23218,16 +24167,16 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_17delete_arcs(PyObject *__pyx
         default: goto __pyx_L5_argtuple_error;
       }
     }
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[0]); if (unlikely((__pyx_v_state == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2002, __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, 2082, __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, 2002, __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, 2082, __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, 2002, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("delete_arcs", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2082, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.delete_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -23246,8 +24195,8 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_16delete_arcs(struct __pyx_ob
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__delete_arcs __pyx_t_1;
   __Pyx_RefNannySetupContext("delete_arcs", 0);
 
-  /* "pywrapfst.pyx":2022
- *     See also: `delete_states`.
+  /* "pywrapfst.pyx":2100
+ *       FstIndexError: State index out of range.
  *     """
  *     self._delete_arcs(state, n)             # <<<<<<<<<<<<<<
  *     return self
@@ -23255,13 +24204,13 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_16delete_arcs(struct __pyx_ob
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_delete_arcs");
-    __PYX_ERR(0, 2022, __pyx_L1_error)
+    __PYX_ERR(0, 2100, __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, 2022, __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, 2100, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2023
+  /* "pywrapfst.pyx":2101
  *     """
  *     self._delete_arcs(state, n)
  *     return self             # <<<<<<<<<<<<<<
@@ -23273,7 +24222,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_16delete_arcs(struct __pyx_ob
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2002
+  /* "pywrapfst.pyx":2082
  *     self._check_mutating_imethod()
  * 
  *   def delete_arcs(self, int64 state, size_t n=0):             # <<<<<<<<<<<<<<
@@ -23291,7 +24240,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_16delete_arcs(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2025
+/* "pywrapfst.pyx":2103
  *     return self
  * 
  *   cdef void _delete_states(self, states=None) except *:             # <<<<<<<<<<<<<<
@@ -23314,17 +24263,17 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(struct __pyx_obj_9py
     }
   }
 
-  /* "pywrapfst.pyx":2027
+  /* "pywrapfst.pyx":2105
  *   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, 2027, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_states); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 2105, __pyx_L1_error)
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2028
+    /* "pywrapfst.pyx":2106
  *     # Only the former signature has a possible indexing failure.
  *     if states:
  *       if not self._mfst.get().DeleteStates(<const vector[int64]> states):             # <<<<<<<<<<<<<<
@@ -23333,20 +24282,20 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(struct __pyx_obj_9py
  */
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-      __PYX_ERR(0, 2028, __pyx_L1_error)
+      __PYX_ERR(0, 2106, __pyx_L1_error)
     }
-    __pyx_t_2 = __pyx_convert_vector_from_py___pyx_t_10basictypes_int64(__pyx_v_states); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2028, __pyx_L1_error)
+    __pyx_t_2 = __pyx_convert_vector_from_py___pyx_t_10basictypes_int64(__pyx_v_states); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2106, __pyx_L1_error)
     __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->DeleteStates(((std::vector<__pyx_t_10basictypes_int64>  const )__pyx_t_2)) != 0)) != 0);
     if (unlikely(__pyx_t_1)) {
 
-      /* "pywrapfst.pyx":2029
+      /* "pywrapfst.pyx":2107
  *     if states:
  *       if not self._mfst.get().DeleteStates(<const vector[int64]> states):
  *         raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     else:
  *       self._mfst.get().DeleteStates()
  */
-      __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2029, __pyx_L1_error)
+      __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2107, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_4);
       __pyx_t_5 = NULL;
       if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
@@ -23360,14 +24309,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(struct __pyx_obj_9py
       }
       __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_kp_u_State_index_out_of_range);
       __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-      if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2029, __pyx_L1_error)
+      if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2107, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_Raise(__pyx_t_3, 0, 0, 0);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __PYX_ERR(0, 2029, __pyx_L1_error)
+      __PYX_ERR(0, 2107, __pyx_L1_error)
 
-      /* "pywrapfst.pyx":2028
+      /* "pywrapfst.pyx":2106
  *     # Only the former signature has a possible indexing failure.
  *     if states:
  *       if not self._mfst.get().DeleteStates(<const vector[int64]> states):             # <<<<<<<<<<<<<<
@@ -23376,7 +24325,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(struct __pyx_obj_9py
  */
     }
 
-    /* "pywrapfst.pyx":2027
+    /* "pywrapfst.pyx":2105
  *   cdef void _delete_states(self, states=None) except *:
  *     # Only the former signature has a possible indexing failure.
  *     if states:             # <<<<<<<<<<<<<<
@@ -23386,7 +24335,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(struct __pyx_obj_9py
     goto __pyx_L3;
   }
 
-  /* "pywrapfst.pyx":2031
+  /* "pywrapfst.pyx":2109
  *         raise FstIndexError("State index out of range")
  *     else:
  *       self._mfst.get().DeleteStates()             # <<<<<<<<<<<<<<
@@ -23396,13 +24345,13 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(struct __pyx_obj_9py
   /*else*/ {
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-      __PYX_ERR(0, 2031, __pyx_L1_error)
+      __PYX_ERR(0, 2109, __pyx_L1_error)
     }
     __pyx_v_self->_mfst.get()->DeleteStates();
   }
   __pyx_L3:;
 
-  /* "pywrapfst.pyx":2032
+  /* "pywrapfst.pyx":2110
  *     else:
  *       self._mfst.get().DeleteStates()
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -23411,11 +24360,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2032, __pyx_L1_error)
+    __PYX_ERR(0, 2110, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2032, __pyx_L1_error)
+  ((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, 2110, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2025
+  /* "pywrapfst.pyx":2103
  *     return self
  * 
  *   cdef void _delete_states(self, states=None) except *:             # <<<<<<<<<<<<<<
@@ -23434,7 +24383,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(struct __pyx_obj_9py
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2034
+/* "pywrapfst.pyx":2112
  *     self._check_mutating_imethod()
  * 
  *   def delete_states(self, states=None):             # <<<<<<<<<<<<<<
@@ -23444,7 +24393,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(struct __pyx_obj_9py
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_19delete_states(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_18delete_states[] = "\n    delete_states(self, states=None)\n\n    Deletes states.\n\n    Args:\n      states: An optional iterable of integer indices of the states to be\n          deleted. If this argument is omitted, all states are deleted.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n\n    See also: `delete_arcs`.\n    ";
+static char __pyx_doc_9pywrapfst_11_MutableFst_18delete_states[] = "\n    delete_states(self, states=None)\n\n    Deletes states.\n\n    Args:\n      states: An optional iterable of integer indices of the states to be\n          deleted. If this argument is omitted, all states are deleted.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_19delete_states(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_states = 0;
   PyObject *__pyx_r = 0;
@@ -23472,7 +24421,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_19delete_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, 2034, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "delete_states") < 0)) __PYX_ERR(0, 2112, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -23486,7 +24435,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_19delete_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, 2034, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("delete_states", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2112, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.delete_states", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -23505,8 +24454,8 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_18delete_states(struct __pyx_
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__delete_states __pyx_t_1;
   __Pyx_RefNannySetupContext("delete_states", 0);
 
-  /* "pywrapfst.pyx":2052
- *     See also: `delete_arcs`.
+  /* "pywrapfst.pyx":2128
+ *       FstIndexError: State index out of range.
  *     """
  *     self._delete_states(states)             # <<<<<<<<<<<<<<
  *     return self
@@ -23514,25 +24463,25 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_18delete_states(struct __pyx_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_delete_states");
-    __PYX_ERR(0, 2052, __pyx_L1_error)
+    __PYX_ERR(0, 2128, __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, 2052, __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, 2128, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2053
+  /* "pywrapfst.pyx":2129
  *     """
  *     self._delete_states(states)
  *     return self             # <<<<<<<<<<<<<<
  * 
- *   cdef void _encode(self, EncodeMapper encoder) except *:
+ *   cdef void _encode(self, EncodeMapper mapper) except *:
  */
   __Pyx_XDECREF(__pyx_r);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2034
+  /* "pywrapfst.pyx":2112
  *     self._check_mutating_imethod()
  * 
  *   def delete_states(self, states=None):             # <<<<<<<<<<<<<<
@@ -23550,53 +24499,53 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_18delete_states(struct __pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2055
+/* "pywrapfst.pyx":2131
  *     return self
  * 
- *   cdef void _encode(self, EncodeMapper encoder) except *:             # <<<<<<<<<<<<<<
- *     fst.Encode(self._mfst.get(), encoder._encoder.get())
+ *   cdef void _encode(self, EncodeMapper mapper) except *:             # <<<<<<<<<<<<<<
+ *     fst.Encode(self._mfst.get(), mapper._mapper.get())
  *     self._check_mutating_imethod()
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__encode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_encoder) {
+static void __pyx_f_9pywrapfst_11_MutableFst__encode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_mapper) {
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_encode", 0);
 
-  /* "pywrapfst.pyx":2056
+  /* "pywrapfst.pyx":2132
  * 
- *   cdef void _encode(self, EncodeMapper encoder) except *:
- *     fst.Encode(self._mfst.get(), encoder._encoder.get())             # <<<<<<<<<<<<<<
+ *   cdef void _encode(self, EncodeMapper mapper) except *:
+ *     fst.Encode(self._mfst.get(), mapper._mapper.get())             # <<<<<<<<<<<<<<
  *     self._check_mutating_imethod()
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2056, __pyx_L1_error)
+    __PYX_ERR(0, 2132, __pyx_L1_error)
   }
-  if (unlikely(((PyObject *)__pyx_v_encoder) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_encoder");
-    __PYX_ERR(0, 2056, __pyx_L1_error)
+  if (unlikely(((PyObject *)__pyx_v_mapper) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
+    __PYX_ERR(0, 2132, __pyx_L1_error)
   }
-  fst::script::Encode(__pyx_v_self->_mfst.get(), __pyx_v_encoder->_encoder.get());
+  fst::script::Encode(__pyx_v_self->_mfst.get(), __pyx_v_mapper->_mapper.get());
 
-  /* "pywrapfst.pyx":2057
- *   cdef void _encode(self, EncodeMapper encoder) except *:
- *     fst.Encode(self._mfst.get(), encoder._encoder.get())
+  /* "pywrapfst.pyx":2133
+ *   cdef void _encode(self, EncodeMapper mapper) except *:
+ *     fst.Encode(self._mfst.get(), mapper._mapper.get())
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
  * 
- *   def encode(self, EncodeMapper encoder):
+ *   def encode(self, EncodeMapper mapper):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2057, __pyx_L1_error)
+    __PYX_ERR(0, 2133, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2057, __pyx_L1_error)
+  ((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, 2133, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2055
+  /* "pywrapfst.pyx":2131
  *     return self
  * 
- *   cdef void _encode(self, EncodeMapper encoder) except *:             # <<<<<<<<<<<<<<
- *     fst.Encode(self._mfst.get(), encoder._encoder.get())
+ *   cdef void _encode(self, EncodeMapper mapper) except *:             # <<<<<<<<<<<<<<
+ *     fst.Encode(self._mfst.get(), mapper._mapper.get())
  *     self._check_mutating_imethod()
  */
 
@@ -23608,23 +24557,23 @@ static void __pyx_f_9pywrapfst_11_MutableFst__encode(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2059
+/* "pywrapfst.pyx":2135
  *     self._check_mutating_imethod()
  * 
- *   def encode(self, EncodeMapper encoder):             # <<<<<<<<<<<<<<
+ *   def encode(self, EncodeMapper mapper):             # <<<<<<<<<<<<<<
  *     """
- *     encode(self, encoder)
+ *     encode(self, mapper)
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_21encode(PyObject *__pyx_v_self, PyObject *__pyx_v_encoder); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_20encode[] = "\n    encode(self, encoder)\n\n    Encodes labels and/or weights.\n\n    This operation allows for the representation of a weighted transducer as a\n    weighted acceptor, an unweighted transducer, or an unweighted acceptor by\n    considering the pair (input label, output label), the pair (input label,\n    weight), or the triple (input label, output label, weight) as a single\n    label. Applying this operation mutates the EncodeMapper argument, which\n    can then be used to decode.\n\n    Args:\n      encoder: An EncodeMapper object to be used as the encoder.\n\n    Returns:\n      self.\n\n    See also: `decode`.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_21encode(PyObject *__pyx_v_self, PyObject *__pyx_v_encoder) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_21encode(PyObject *__pyx_v_self, PyObject *__pyx_v_mapper); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_20encode[] = "\n    encode(self, mapper)\n\n    Encodes labels and/or weights.\n\n    This operation allows for the representation of a weighted transducer as a\n    weighted acceptor, an unweighted transducer, or an unweighted acceptor by\n    considering the pair (input label, output label), the pair (input label,\n    weight), or the triple (input label, output label, weight) as a single\n    label. Applying this operation mutates the EncodeMapper argument, which\n    can then be used to decode.\n\n    Args:\n      mapper: An EncodeMapper object to be used as the mapper.\n\n    Returns:\n      self.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_21encode(PyObject *__pyx_v_self, PyObject *__pyx_v_mapper) {
   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, 2059, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_20encode(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_encoder));
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_mapper), __pyx_ptype_9pywrapfst_EncodeMapper, 1, "mapper", 0))) __PYX_ERR(0, 2135, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_20encode(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_mapper));
 
   /* function exit code */
   goto __pyx_L0;
@@ -23635,27 +24584,27 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_21encode(PyObject *__pyx_v_se
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_20encode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_encoder) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_20encode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_mapper) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("encode", 0);
 
-  /* "pywrapfst.pyx":2080
- *     See also: `decode`.
+  /* "pywrapfst.pyx":2154
+ *       self.
  *     """
- *     self._encode(encoder)             # <<<<<<<<<<<<<<
+ *     self._encode(mapper)             # <<<<<<<<<<<<<<
  *     return self
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_encode");
-    __PYX_ERR(0, 2080, __pyx_L1_error)
+    __PYX_ERR(0, 2154, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_encode(__pyx_v_self, __pyx_v_encoder); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2080, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_encode(__pyx_v_self, __pyx_v_mapper); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2154, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2081
+  /* "pywrapfst.pyx":2155
  *     """
- *     self._encode(encoder)
+ *     self._encode(mapper)
  *     return self             # <<<<<<<<<<<<<<
  * 
  *   cdef void _invert(self) except *:
@@ -23665,12 +24614,12 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_20encode(struct __pyx_obj_9py
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2059
+  /* "pywrapfst.pyx":2135
  *     self._check_mutating_imethod()
  * 
- *   def encode(self, EncodeMapper encoder):             # <<<<<<<<<<<<<<
+ *   def encode(self, EncodeMapper mapper):             # <<<<<<<<<<<<<<
  *     """
- *     encode(self, encoder)
+ *     encode(self, mapper)
  */
 
   /* function exit code */
@@ -23683,7 +24632,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_20encode(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2083
+/* "pywrapfst.pyx":2157
  *     return self
  * 
  *   cdef void _invert(self) except *:             # <<<<<<<<<<<<<<
@@ -23695,7 +24644,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__invert(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_invert", 0);
 
-  /* "pywrapfst.pyx":2084
+  /* "pywrapfst.pyx":2158
  * 
  *   cdef void _invert(self) except *:
  *     fst.Invert(self._mfst.get())             # <<<<<<<<<<<<<<
@@ -23704,11 +24653,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__invert(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2084, __pyx_L1_error)
+    __PYX_ERR(0, 2158, __pyx_L1_error)
   }
   fst::script::Invert(__pyx_v_self->_mfst.get());
 
-  /* "pywrapfst.pyx":2085
+  /* "pywrapfst.pyx":2159
  *   cdef void _invert(self) except *:
  *     fst.Invert(self._mfst.get())
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -23717,11 +24666,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__invert(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2085, __pyx_L1_error)
+    __PYX_ERR(0, 2159, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2085, __pyx_L1_error)
+  ((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, 2159, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2083
+  /* "pywrapfst.pyx":2157
  *     return self
  * 
  *   cdef void _invert(self) except *:             # <<<<<<<<<<<<<<
@@ -23737,7 +24686,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__invert(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2087
+/* "pywrapfst.pyx":2161
  *     self._check_mutating_imethod()
  * 
  *   def invert(self):             # <<<<<<<<<<<<<<
@@ -23764,7 +24713,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_22invert(struct __pyx_obj_9py
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("invert", 0);
 
-  /* "pywrapfst.pyx":2099
+  /* "pywrapfst.pyx":2173
  *       self.
  *     """
  *     self._invert()             # <<<<<<<<<<<<<<
@@ -23773,11 +24722,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_22invert(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_invert");
-    __PYX_ERR(0, 2099, __pyx_L1_error)
+    __PYX_ERR(0, 2173, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_invert(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2099, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_invert(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2173, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2100
+  /* "pywrapfst.pyx":2174
  *     """
  *     self._invert()
  *     return self             # <<<<<<<<<<<<<<
@@ -23789,7 +24738,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_22invert(struct __pyx_obj_9py
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2087
+  /* "pywrapfst.pyx":2161
  *     self._check_mutating_imethod()
  * 
  *   def invert(self):             # <<<<<<<<<<<<<<
@@ -23807,7 +24756,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_22invert(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2102
+/* "pywrapfst.pyx":2176
  *     return self
  * 
  *   cdef void _minimize(self, float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
@@ -23816,9 +24765,9 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_22invert(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__9;
 
-  /* "pywrapfst.pyx":2103
+  /* "pywrapfst.pyx":2177
  * 
  *   cdef void _minimize(self, float delta=fst.kShortestDelta,
  *                       bool allow_nondet=False) except *:             # <<<<<<<<<<<<<<
@@ -23837,7 +24786,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__minimize(struct __pyx_obj_9pywrapf
     }
   }
 
-  /* "pywrapfst.pyx":2105
+  /* "pywrapfst.pyx":2179
  *                       bool allow_nondet=False) except *:
  *     # This runs in-place when the second argument is null.
  *     fst.Minimize(self._mfst.get(), NULL, delta, allow_nondet)             # <<<<<<<<<<<<<<
@@ -23846,11 +24795,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__minimize(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2105, __pyx_L1_error)
+    __PYX_ERR(0, 2179, __pyx_L1_error)
   }
   fst::script::Minimize(__pyx_v_self->_mfst.get(), NULL, __pyx_v_delta, __pyx_v_allow_nondet);
 
-  /* "pywrapfst.pyx":2106
+  /* "pywrapfst.pyx":2180
  *     # This runs in-place when the second argument is null.
  *     fst.Minimize(self._mfst.get(), NULL, delta, allow_nondet)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -23859,11 +24808,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__minimize(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 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":2102
+  /* "pywrapfst.pyx":2176
  *     return self
  * 
  *   cdef void _minimize(self, float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
@@ -23879,7 +24828,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__minimize(struct __pyx_obj_9pywrapf
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2108
+/* "pywrapfst.pyx":2182
  *     self._check_mutating_imethod()
  * 
  *   def minimize(self, float delta=fst.kShortestDelta, bool allow_nondet=False):             # <<<<<<<<<<<<<<
@@ -23925,7 +24874,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_25minimize(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, 2108, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "minimize") < 0)) __PYX_ERR(0, 2182, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -23938,19 +24887,19 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_25minimize(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, 2108, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2182, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__12;
+      __pyx_v_delta = __pyx_k__10;
     }
     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, 2108, __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, 2182, __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, 2108, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("minimize", 0, 0, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2182, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.minimize", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -23969,7 +24918,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_24minimize(struct __pyx_obj_9
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__minimize __pyx_t_1;
   __Pyx_RefNannySetupContext("minimize", 0);
 
-  /* "pywrapfst.pyx":2134
+  /* "pywrapfst.pyx":2208
  *       self.
  *     """
  *     self._minimize(delta, allow_nondet)             # <<<<<<<<<<<<<<
@@ -23978,14 +24927,14 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_24minimize(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_minimize");
-    __PYX_ERR(0, 2134, __pyx_L1_error)
+    __PYX_ERR(0, 2208, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 2;
   __pyx_t_1.delta = __pyx_v_delta;
   __pyx_t_1.allow_nondet = __pyx_v_allow_nondet;
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_minimize(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2134, __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, 2208, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2135
+  /* "pywrapfst.pyx":2209
  *     """
  *     self._minimize(delta, allow_nondet)
  *     return self             # <<<<<<<<<<<<<<
@@ -23997,7 +24946,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_24minimize(struct __pyx_obj_9
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2108
+  /* "pywrapfst.pyx":2182
  *     self._check_mutating_imethod()
  * 
  *   def minimize(self, float delta=fst.kShortestDelta, bool allow_nondet=False):             # <<<<<<<<<<<<<<
@@ -24015,7 +24964,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_24minimize(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2137
+/* "pywrapfst.pyx":2211
  *     return self
  * 
  *   cpdef MutableArcIterator mutable_arcs(self, int64 state):             # <<<<<<<<<<<<<<
@@ -24042,11 +24991,11 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_11_Mut
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_mutable_arcs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2137, __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, 2211, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_11_MutableFst_27mutable_arcs)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
-        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2137, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2211, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -24062,10 +25011,10 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_11_Mut
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2137, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2211, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_MutableArcIterator))))) __PYX_ERR(0, 2137, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_MutableArcIterator))))) __PYX_ERR(0, 2211, __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;
@@ -24084,17 +25033,17 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_11_Mut
     #endif
   }
 
-  /* "pywrapfst.pyx":2151
- *     See also: `arcs`, `states`.
+  /* "pywrapfst.pyx":2223
+ *       A MutableArcIterator.
  *     """
  *     return MutableArcIterator(self, state)             # <<<<<<<<<<<<<<
  * 
  *   def mutable_input_symbols(self):
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2151, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2223, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2151, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2223, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
@@ -24102,14 +25051,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, 2151, __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, 2223, __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":2137
+  /* "pywrapfst.pyx":2211
  *     return self
  * 
  *   cpdef MutableArcIterator mutable_arcs(self, int64 state):             # <<<<<<<<<<<<<<
@@ -24134,14 +25083,14 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_11_Mut
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_27mutable_arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_26mutable_arcs[] = "\n    mutable_arcs(self, state)\n\n    Returns a mutable iterator over arcs leaving the specified state.\n\n    Args:\n      state: The source state ID.\n\n    Returns:\n      A MutableArcIterator.\n\n    See also: `arcs`, `states`.\n    ";
+static char __pyx_doc_9pywrapfst_11_MutableFst_26mutable_arcs[] = "\n    mutable_arcs(self, state)\n\n    Returns a mutable iterator over arcs leaving the specified state.\n\n    Args:\n      state: The source state ID.\n\n    Returns:\n      A MutableArcIterator.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_27mutable_arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state) {
   __pyx_t_10basictypes_int64 __pyx_v_state;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("mutable_arcs (wrapper)", 0);
   assert(__pyx_arg_state); {
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2137, __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, 2211, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -24162,7 +25111,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_26mutable_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, 2137, __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, 2211, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -24179,7 +25128,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_26mutable_arcs(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2153
+/* "pywrapfst.pyx":2225
  *     return MutableArcIterator(self, state)
  * 
  *   def mutable_input_symbols(self):             # <<<<<<<<<<<<<<
@@ -24209,7 +25158,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_input_symbols(struc
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("mutable_input_symbols", 0);
 
-  /* "pywrapfst.pyx":2159
+  /* "pywrapfst.pyx":2231
  *     Returns the FST's (mutable) input symbol table, or None if none is present.
  *     """
  *     cdef fst.SymbolTable *syms = self._mfst.get().MutableInputSymbols()             # <<<<<<<<<<<<<<
@@ -24218,11 +25167,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_input_symbols(struc
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2159, __pyx_L1_error)
+    __PYX_ERR(0, 2231, __pyx_L1_error)
   }
   __pyx_v_syms = __pyx_v_self->_mfst.get()->MutableInputSymbols();
 
-  /* "pywrapfst.pyx":2160
+  /* "pywrapfst.pyx":2232
  *     """
  *     cdef fst.SymbolTable *syms = self._mfst.get().MutableInputSymbols()
  *     if syms == NULL:             # <<<<<<<<<<<<<<
@@ -24232,7 +25181,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_input_symbols(struc
   __pyx_t_1 = ((__pyx_v_syms == NULL) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2161
+    /* "pywrapfst.pyx":2233
  *     cdef fst.SymbolTable *syms = self._mfst.get().MutableInputSymbols()
  *     if syms == NULL:
  *       return             # <<<<<<<<<<<<<<
@@ -24243,7 +25192,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_input_symbols(struc
     __pyx_r = Py_None; __Pyx_INCREF(Py_None);
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":2160
+    /* "pywrapfst.pyx":2232
  *     """
  *     cdef fst.SymbolTable *syms = self._mfst.get().MutableInputSymbols()
  *     if syms == NULL:             # <<<<<<<<<<<<<<
@@ -24252,7 +25201,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_input_symbols(struc
  */
   }
 
-  /* "pywrapfst.pyx":2162
+  /* "pywrapfst.pyx":2234
  *     if syms == NULL:
  *       return
  *     return _init_MutableFstSymbolTable(syms, self._mfst)             # <<<<<<<<<<<<<<
@@ -24262,15 +25211,15 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_input_symbols(struc
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2162, __pyx_L1_error)
+    __PYX_ERR(0, 2234, __pyx_L1_error)
   }
-  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFstSymbolTable(__pyx_v_syms, __pyx_v_self->_mfst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2162, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFstSymbolTable(__pyx_v_syms, __pyx_v_self->_mfst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2234, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2153
+  /* "pywrapfst.pyx":2225
  *     return MutableArcIterator(self, state)
  * 
  *   def mutable_input_symbols(self):             # <<<<<<<<<<<<<<
@@ -24289,7 +25238,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_input_symbols(struc
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2164
+/* "pywrapfst.pyx":2236
  *     return _init_MutableFstSymbolTable(syms, self._mfst)
  * 
  *   def mutable_output_symbols(self):             # <<<<<<<<<<<<<<
@@ -24319,7 +25268,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_30mutable_output_symbols(stru
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("mutable_output_symbols", 0);
 
-  /* "pywrapfst.pyx":2170
+  /* "pywrapfst.pyx":2242
  *     Returns the FST's (mutable) output symbol table, or None if none is present.
  *     """
  *     cdef fst.SymbolTable *syms = self._mfst.get().MutableOutputSymbols()             # <<<<<<<<<<<<<<
@@ -24328,11 +25277,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_30mutable_output_symbols(stru
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2170, __pyx_L1_error)
+    __PYX_ERR(0, 2242, __pyx_L1_error)
   }
   __pyx_v_syms = __pyx_v_self->_mfst.get()->MutableOutputSymbols();
 
-  /* "pywrapfst.pyx":2171
+  /* "pywrapfst.pyx":2243
  *     """
  *     cdef fst.SymbolTable *syms = self._mfst.get().MutableOutputSymbols()
  *     if syms == NULL:             # <<<<<<<<<<<<<<
@@ -24342,7 +25291,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_30mutable_output_symbols(stru
   __pyx_t_1 = ((__pyx_v_syms == NULL) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2172
+    /* "pywrapfst.pyx":2244
  *     cdef fst.SymbolTable *syms = self._mfst.get().MutableOutputSymbols()
  *     if syms == NULL:
  *       return             # <<<<<<<<<<<<<<
@@ -24353,7 +25302,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_30mutable_output_symbols(stru
     __pyx_r = Py_None; __Pyx_INCREF(Py_None);
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":2171
+    /* "pywrapfst.pyx":2243
  *     """
  *     cdef fst.SymbolTable *syms = self._mfst.get().MutableOutputSymbols()
  *     if syms == NULL:             # <<<<<<<<<<<<<<
@@ -24362,7 +25311,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_30mutable_output_symbols(stru
  */
   }
 
-  /* "pywrapfst.pyx":2173
+  /* "pywrapfst.pyx":2245
  *     if syms == NULL:
  *       return
  *     return _init_MutableFstSymbolTable(syms, self._mfst)             # <<<<<<<<<<<<<<
@@ -24372,15 +25321,15 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_30mutable_output_symbols(stru
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2173, __pyx_L1_error)
+    __PYX_ERR(0, 2245, __pyx_L1_error)
   }
-  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFstSymbolTable(__pyx_v_syms, __pyx_v_self->_mfst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2173, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFstSymbolTable(__pyx_v_syms, __pyx_v_self->_mfst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2245, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2164
+  /* "pywrapfst.pyx":2236
  *     return _init_MutableFstSymbolTable(syms, self._mfst)
  * 
  *   def mutable_output_symbols(self):             # <<<<<<<<<<<<<<
@@ -24399,7 +25348,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_30mutable_output_symbols(stru
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2175
+/* "pywrapfst.pyx":2247
  *     return _init_MutableFstSymbolTable(syms, self._mfst)
  * 
  *   cpdef int64 num_states(self):             # <<<<<<<<<<<<<<
@@ -24426,7 +25375,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_num_states(st
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2175, __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, 2247, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_11_MutableFst_33num_states)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -24442,10 +25391,10 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_num_states(st
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2175, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2247, __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, 2175, __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, 2247, __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;
@@ -24464,7 +25413,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_num_states(st
     #endif
   }
 
-  /* "pywrapfst.pyx":2181
+  /* "pywrapfst.pyx":2253
  *     Returns the number of states.
  *     """
  *     return self._mfst.get().NumStates()             # <<<<<<<<<<<<<<
@@ -24473,12 +25422,12 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_num_states(st
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2181, __pyx_L1_error)
+    __PYX_ERR(0, 2253, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_mfst.get()->NumStates();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2175
+  /* "pywrapfst.pyx":2247
  *     return _init_MutableFstSymbolTable(syms, self._mfst)
  * 
  *   cpdef int64 num_states(self):             # <<<<<<<<<<<<<<
@@ -24519,7 +25468,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_32num_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, 2175, __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, 2247, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -24536,7 +25485,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_32num_states(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2183
+/* "pywrapfst.pyx":2255
  *     return self._mfst.get().NumStates()
  * 
  *   cdef void _project(self, bool project_output=False) except *:             # <<<<<<<<<<<<<<
@@ -24554,7 +25503,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__project(struct __pyx_obj_9pywrapfs
     }
   }
 
-  /* "pywrapfst.pyx":2184
+  /* "pywrapfst.pyx":2256
  * 
  *   cdef void _project(self, bool project_output=False) except *:
  *     fst.Project(self._mfst.get(), fst.GetProjectType(project_output))             # <<<<<<<<<<<<<<
@@ -24563,11 +25512,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__project(struct __pyx_obj_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2184, __pyx_L1_error)
+    __PYX_ERR(0, 2256, __pyx_L1_error)
   }
   fst::script::Project(__pyx_v_self->_mfst.get(), fst::script::GetProjectType(__pyx_v_project_output));
 
-  /* "pywrapfst.pyx":2185
+  /* "pywrapfst.pyx":2257
  *   cdef void _project(self, bool project_output=False) except *:
  *     fst.Project(self._mfst.get(), fst.GetProjectType(project_output))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -24576,11 +25525,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__project(struct __pyx_obj_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2185, __pyx_L1_error)
+    __PYX_ERR(0, 2257, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2185, __pyx_L1_error)
+  ((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, 2257, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2183
+  /* "pywrapfst.pyx":2255
  *     return self._mfst.get().NumStates()
  * 
  *   cdef void _project(self, bool project_output=False) except *:             # <<<<<<<<<<<<<<
@@ -24596,7 +25545,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__project(struct __pyx_obj_9pywrapfs
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2187
+/* "pywrapfst.pyx":2259
  *     self._check_mutating_imethod()
  * 
  *   def project(self, bool project_output=False):             # <<<<<<<<<<<<<<
@@ -24606,7 +25555,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__project(struct __pyx_obj_9pywrapfs
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_35project(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_34project[] = "\n    project(self, project_output=False)\n\n    Converts the FST to an acceptor using input or output labels.\n\n    This operation destructively projects an FST onto its domain or range by\n    either copying each arc's input label to its output label (the default) or\n    vice versa.\n\n    Args:\n      project_output: Should the output labels be projected?\n\n    Returns:\n      self.\n\n    See also: `decode`, `encode`, `relabel_pairs`, `relabel_symbols`.\n    ";
+static char __pyx_doc_9pywrapfst_11_MutableFst_34project[] = "\n    project(self, project_output=False)\n\n    Converts the FST to an acceptor using input or output labels.\n\n    This operation destructively projects an FST onto its domain or range by\n    either copying each arc's input label to its output label (the default) or\n    vice versa.\n\n    Args:\n      project_output: Should the output labels be projected?\n\n    Returns:\n      self.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_35project(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   bool __pyx_v_project_output;
   PyObject *__pyx_r = 0;
@@ -24633,7 +25582,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_35project(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, 2187, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "project") < 0)) __PYX_ERR(0, 2259, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -24644,14 +25593,14 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_35project(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, 2187, __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, 2259, __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, 2187, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("project", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2259, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.project", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -24670,8 +25619,8 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_34project(struct __pyx_obj_9p
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__project __pyx_t_1;
   __Pyx_RefNannySetupContext("project", 0);
 
-  /* "pywrapfst.pyx":2205
- *     See also: `decode`, `encode`, `relabel_pairs`, `relabel_symbols`.
+  /* "pywrapfst.pyx":2275
+ *       self.
  *     """
  *     self._project(project_output)             # <<<<<<<<<<<<<<
  *     return self
@@ -24679,13 +25628,13 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_34project(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_project");
-    __PYX_ERR(0, 2205, __pyx_L1_error)
+    __PYX_ERR(0, 2275, __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, 2205, __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, 2275, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2206
+  /* "pywrapfst.pyx":2276
  *     """
  *     self._project(project_output)
  *     return self             # <<<<<<<<<<<<<<
@@ -24697,7 +25646,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_34project(struct __pyx_obj_9p
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2187
+  /* "pywrapfst.pyx":2259
  *     self._check_mutating_imethod()
  * 
  *   def project(self, bool project_output=False):             # <<<<<<<<<<<<<<
@@ -24715,7 +25664,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_34project(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2208
+/* "pywrapfst.pyx":2278
  *     return self
  * 
  *   cdef void _prune(self, float delta=fst.kDelta, int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -24724,10 +25673,10 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_34project(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__11;
+  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__12;
 
-  /* "pywrapfst.pyx":2209
+  /* "pywrapfst.pyx":2279
  * 
  *   cdef void _prune(self, float delta=fst.kDelta, int64 nstate=fst.kNoStateId,
  *                    weight=None) except *:             # <<<<<<<<<<<<<<
@@ -24751,7 +25700,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__prune(struct __pyx_obj_9pywrapfst_
     }
   }
 
-  /* "pywrapfst.pyx":2211
+  /* "pywrapfst.pyx":2281
  *                    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(),             # <<<<<<<<<<<<<<
@@ -24760,20 +25709,20 @@ static void __pyx_f_9pywrapfst_11_MutableFst__prune(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 2211, __pyx_L1_error)
+    __PYX_ERR(0, 2281, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2212
+  /* "pywrapfst.pyx":2282
  *     # 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, 2211, __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, 2281, __pyx_L1_error)
   __pyx_v_wc = __pyx_t_1;
 
-  /* "pywrapfst.pyx":2213
+  /* "pywrapfst.pyx":2283
  *     cdef fst.WeightClass wc = _get_WeightClass_or_Zero(self.weight_type(),
  *                                                        weight)
  *     fst.Prune(self._mfst.get(), wc, nstate, delta)             # <<<<<<<<<<<<<<
@@ -24782,11 +25731,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__prune(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2213, __pyx_L1_error)
+    __PYX_ERR(0, 2283, __pyx_L1_error)
   }
   fst::script::Prune(__pyx_v_self->_mfst.get(), __pyx_v_wc, __pyx_v_nstate, __pyx_v_delta);
 
-  /* "pywrapfst.pyx":2214
+  /* "pywrapfst.pyx":2284
  *                                                        weight)
  *     fst.Prune(self._mfst.get(), wc, nstate, delta)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -24795,11 +25744,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__prune(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2214, __pyx_L1_error)
+    __PYX_ERR(0, 2284, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2214, __pyx_L1_error)
+  ((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, 2284, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2208
+  /* "pywrapfst.pyx":2278
  *     return self
  * 
  *   cdef void _prune(self, float delta=fst.kDelta, int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -24815,7 +25764,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__prune(struct __pyx_obj_9pywrapfst_
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2216
+/* "pywrapfst.pyx":2286
  *     self._check_mutating_imethod()
  * 
  *   def prune(self,             # <<<<<<<<<<<<<<
@@ -24825,7 +25774,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__prune(struct __pyx_obj_9pywrapfst_
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_37prune(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_36prune[] = "\n    prune(self, delta=0.0009765625, nstate=NO_STATE_ID, weight=None)\n\n    Removes paths with weights below a certain threshold.\n\n    This operation deletes states and arcs in the input FST that do not belong\n    to a successful path whose weight is no more (w.r.t the natural semiring\n    order) than the threshold t \\otimes-times the weight of the shortest path in\n    the input FST. Weights must be commutative and have the path property.\n\n    Args:\n      delta: Comparison/quantization delta.\n      nstate: State number threshold.\n      weight: A Weight or weight string indicating the desired weight threshold\n          below which paths are pruned; if omitted, no paths are pruned.\n\n    Returns:\n      self.\n\n    See also: The constructive variant.\n    ";
+static char __pyx_doc_9pywrapfst_11_MutableFst_36prune[] = "\n    prune(self, delta=0.0009765625, nstate=NO_STATE_ID, weight=None)\n\n    Removes paths with weights below a certain threshold.\n\n    This operation deletes states and arcs in the input FST that do not belong\n    to a successful path whose weight is no more (w.r.t the natural semiring\n    order) than the threshold t \\otimes-times the weight of the shortest path in\n    the input FST. Weights must be commutative and have the path property.\n\n    Args:\n      delta: Comparison/quantization delta.\n      nstate: State number threshold.\n      weight: A Weight or weight string indicating the desired weight threshold\n          below which paths are pruned; if omitted, no paths are pruned.\n\n    Returns:\n      self.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_37prune(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   float __pyx_v_delta;
   __pyx_t_10basictypes_int64 __pyx_v_nstate;
@@ -24837,7 +25786,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_37prune(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":2219
+    /* "pywrapfst.pyx":2289
  *             float delta=fst.kDelta,
  *             int64 nstate=fst.kNoStateId,
  *             weight=None):             # <<<<<<<<<<<<<<
@@ -24879,7 +25828,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_37prune(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, 2216, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "prune") < 0)) __PYX_ERR(0, 2286, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -24894,20 +25843,20 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_37prune(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, 2217, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2287, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__15;
+      __pyx_v_delta = __pyx_k__13;
     }
     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, 2218, __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, 2288, __pyx_L3_error)
     } else {
-      __pyx_v_nstate = __pyx_k__16;
+      __pyx_v_nstate = __pyx_k__14;
     }
     __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, 2216, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("prune", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2286, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.prune", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -24915,7 +25864,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_37prune(PyObject *__pyx_v_sel
   __pyx_L4_argument_unpacking_done:;
   __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_36prune(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_delta, __pyx_v_nstate, __pyx_v_weight);
 
-  /* "pywrapfst.pyx":2216
+  /* "pywrapfst.pyx":2286
  *     self._check_mutating_imethod()
  * 
  *   def prune(self,             # <<<<<<<<<<<<<<
@@ -24934,8 +25883,8 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_36prune(struct __pyx_obj_9pyw
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__prune __pyx_t_1;
   __Pyx_RefNannySetupContext("prune", 0);
 
-  /* "pywrapfst.pyx":2241
- *     See also: The constructive variant.
+  /* "pywrapfst.pyx":2309
+ *       self.
  *     """
  *     self._prune(delta, nstate, weight)             # <<<<<<<<<<<<<<
  *     return self
@@ -24943,15 +25892,15 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_36prune(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_prune");
-    __PYX_ERR(0, 2241, __pyx_L1_error)
+    __PYX_ERR(0, 2309, __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, 2241, __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, 2309, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2242
+  /* "pywrapfst.pyx":2310
  *     """
  *     self._prune(delta, nstate, weight)
  *     return self             # <<<<<<<<<<<<<<
@@ -24963,7 +25912,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_36prune(struct __pyx_obj_9pyw
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2216
+  /* "pywrapfst.pyx":2286
  *     self._check_mutating_imethod()
  * 
  *   def prune(self,             # <<<<<<<<<<<<<<
@@ -24981,28 +25930,28 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_36prune(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2244
+/* "pywrapfst.pyx":2312
  *     return self
  * 
  *   cdef void _push(self,             # <<<<<<<<<<<<<<
- *                   float delta=fst.kDelta,
+ *                   float delta=fst.kShortestDelta,
  *                   bool remove_total_weight=False,
  */
 
 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__15;
 
-  /* "pywrapfst.pyx":2246
+  /* "pywrapfst.pyx":2314
  *   cdef void _push(self,
- *                   float delta=fst.kDelta,
+ *                   float delta=fst.kShortestDelta,
  *                   bool remove_total_weight=False,             # <<<<<<<<<<<<<<
  *                   bool to_final=False) except *:
  *     fst.Push(self._mfst.get(), fst.GetReweightType(to_final), delta,
  */
   bool __pyx_v_remove_total_weight = ((bool)0);
 
-  /* "pywrapfst.pyx":2247
- *                   float delta=fst.kDelta,
+  /* "pywrapfst.pyx":2315
+ *                   float delta=fst.kShortestDelta,
  *                   bool remove_total_weight=False,
  *                   bool to_final=False) except *:             # <<<<<<<<<<<<<<
  *     fst.Push(self._mfst.get(), fst.GetReweightType(to_final), delta,
@@ -25023,7 +25972,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__push(struct __pyx_obj_9pywrapfst__
     }
   }
 
-  /* "pywrapfst.pyx":2248
+  /* "pywrapfst.pyx":2316
  *                   bool remove_total_weight=False,
  *                   bool to_final=False) except *:
  *     fst.Push(self._mfst.get(), fst.GetReweightType(to_final), delta,             # <<<<<<<<<<<<<<
@@ -25032,10 +25981,10 @@ static void __pyx_f_9pywrapfst_11_MutableFst__push(struct __pyx_obj_9pywrapfst__
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2248, __pyx_L1_error)
+    __PYX_ERR(0, 2316, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2249
+  /* "pywrapfst.pyx":2317
  *                   bool to_final=False) except *:
  *     fst.Push(self._mfst.get(), fst.GetReweightType(to_final), delta,
  *              remove_total_weight)             # <<<<<<<<<<<<<<
@@ -25044,7 +25993,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":2250
+  /* "pywrapfst.pyx":2318
  *     fst.Push(self._mfst.get(), fst.GetReweightType(to_final), delta,
  *              remove_total_weight)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -25053,15 +26002,15 @@ static void __pyx_f_9pywrapfst_11_MutableFst__push(struct __pyx_obj_9pywrapfst__
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2250, __pyx_L1_error)
+    __PYX_ERR(0, 2318, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2250, __pyx_L1_error)
+  ((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, 2318, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2244
+  /* "pywrapfst.pyx":2312
  *     return self
  * 
  *   cdef void _push(self,             # <<<<<<<<<<<<<<
- *                   float delta=fst.kDelta,
+ *                   float delta=fst.kShortestDelta,
  *                   bool remove_total_weight=False,
  */
 
@@ -25073,17 +26022,17 @@ static void __pyx_f_9pywrapfst_11_MutableFst__push(struct __pyx_obj_9pywrapfst__
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2252
+/* "pywrapfst.pyx":2320
  *     self._check_mutating_imethod()
  * 
  *   def push(self,             # <<<<<<<<<<<<<<
- *            float delta=fst.kDelta,
+ *            float delta=fst.kShortestDelta,
  *            bool remove_total_weight=False,
  */
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_39push(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_38push[] = "\n    push(self, delta=0.0009765625, remove_total_weight=False, to_final=False)\n\n    Pushes weights towards the initial or final states.\n\n    This operation destructively produces an equivalent transducer by pushing\n    the weights towards the initial state or toward the final states. When\n    pushing weights towards the initial state, the sum of the weight of the\n    outgoing transitions and final weight at any non-initial state is equal to\n    one in the resulting machine. When pushing weights towards the final states,\n    the sum of the weight of the incoming transitions at any state is equal to\n    one. Weights need to be left distributive when pushing towards the initial\n    state and right distributive when pushing towards the final states.\n\n    Args:\n      delta: Comparison/quantization delta.\n      remove_total_weight: If pushing weights, should the total weight be\n          removed?\n      to_final: Push towards final states?\n\n    Returns:\n      self.\n\n    See also: The constructive variant, which also supports label pushing.\n    ";
+static char __pyx_doc_9pywrapfst_11_MutableFst_38push[] = "\n    push(self, delta=1-e6, remove_total_weight=False, to_final=False)\n\n    Pushes weights towards the initial or final states.\n\n    This operation destructively produces an equivalent transducer by pushing\n    the weights towards the initial state or toward the final states. When\n    pushing weights towards the initial state, the sum of the weight of the\n    outgoing transitions and final weight at any non-initial state is equal to\n    one in the resulting machine. When pushing weights towards the final states,\n    the sum of the weight of the incoming transitions at any state is equal to\n    one. Weights need to be left distributive when pushing towards the initial\n    state and right distributive when pushing towards the final states.\n\n    Args:\n      delta: Comparison/quantization delta.\n      remove_total_weight: If pushing weights, should the total weight be\n          removed?\n      to_final: Push towards final states?\n\n    Returns:\n      self.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_39push(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   float __pyx_v_delta;
   bool __pyx_v_remove_total_weight;
@@ -25128,7 +26077,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_39push(PyObject *__pyx_v_self
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "push") < 0)) __PYX_ERR(0, 2252, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "push") < 0)) __PYX_ERR(0, 2320, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -25143,17 +26092,17 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_39push(PyObject *__pyx_v_self
       }
     }
     if (values[0]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2253, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2321, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__18;
+      __pyx_v_delta = __pyx_k__16;
     }
     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, 2254, __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, 2322, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":2254
+      /* "pywrapfst.pyx":2322
  *   def push(self,
- *            float delta=fst.kDelta,
+ *            float delta=fst.kShortestDelta,
  *            bool remove_total_weight=False,             # <<<<<<<<<<<<<<
  *            bool to_final=False):
  *     """
@@ -25161,22 +26110,22 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_39push(PyObject *__pyx_v_self
       __pyx_v_remove_total_weight = ((bool)0);
     }
     if (values[2]) {
-      __pyx_v_to_final = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_to_final == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2255, __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, 2323, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":2255
- *            float delta=fst.kDelta,
+      /* "pywrapfst.pyx":2323
+ *            float delta=fst.kShortestDelta,
  *            bool remove_total_weight=False,
  *            bool to_final=False):             # <<<<<<<<<<<<<<
  *     """
- *     push(self, delta=0.0009765625, remove_total_weight=False, to_final=False)
+ *     push(self, delta=1-e6, remove_total_weight=False, to_final=False)
  */
       __pyx_v_to_final = ((bool)0);
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("push", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2252, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("push", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2320, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.push", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -25184,11 +26133,11 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_39push(PyObject *__pyx_v_self
   __pyx_L4_argument_unpacking_done:;
   __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_38push(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_delta, __pyx_v_remove_total_weight, __pyx_v_to_final);
 
-  /* "pywrapfst.pyx":2252
+  /* "pywrapfst.pyx":2320
  *     self._check_mutating_imethod()
  * 
  *   def push(self,             # <<<<<<<<<<<<<<
- *            float delta=fst.kDelta,
+ *            float delta=fst.kShortestDelta,
  *            bool remove_total_weight=False,
  */
 
@@ -25203,8 +26152,8 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_38push(struct __pyx_obj_9pywr
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__push __pyx_t_1;
   __Pyx_RefNannySetupContext("push", 0);
 
-  /* "pywrapfst.pyx":2281
- *     See also: The constructive variant, which also supports label pushing.
+  /* "pywrapfst.pyx":2347
+ *       self.
  *     """
  *     self._push(delta, remove_total_weight, to_final)             # <<<<<<<<<<<<<<
  *     return self
@@ -25212,15 +26161,15 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_38push(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_push");
-    __PYX_ERR(0, 2281, __pyx_L1_error)
+    __PYX_ERR(0, 2347, __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, 2281, __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, 2347, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2282
+  /* "pywrapfst.pyx":2348
  *     """
  *     self._push(delta, remove_total_weight, to_final)
  *     return self             # <<<<<<<<<<<<<<
@@ -25232,11 +26181,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_38push(struct __pyx_obj_9pywr
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2252
+  /* "pywrapfst.pyx":2320
  *     self._check_mutating_imethod()
  * 
  *   def push(self,             # <<<<<<<<<<<<<<
- *            float delta=fst.kDelta,
+ *            float delta=fst.kShortestDelta,
  *            bool remove_total_weight=False,
  */
 
@@ -25250,7 +26199,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_38push(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2284
+/* "pywrapfst.pyx":2350
  *     return self
  * 
  *   cdef void _relabel_pairs(self, ipairs=None, opairs=None) except *:             # <<<<<<<<<<<<<<
@@ -25290,7 +26239,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
     }
   }
 
-  /* "pywrapfst.pyx":2286
+  /* "pywrapfst.pyx":2352
  *   cdef void _relabel_pairs(self, ipairs=None, opairs=None) except *:
  *     cdef unique_ptr[vector[fst.LabelPair]] _ipairs
  *     _ipairs.reset(new vector[fst.LabelPair]())             # <<<<<<<<<<<<<<
@@ -25301,11 +26250,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, 2286, __pyx_L1_error)
+    __PYX_ERR(0, 2352, __pyx_L1_error)
   }
   __pyx_v__ipairs.reset(__pyx_t_1);
 
-  /* "pywrapfst.pyx":2288
+  /* "pywrapfst.pyx":2354
  *     _ipairs.reset(new vector[fst.LabelPair]())
  *     cdef unique_ptr[vector[fst.LabelPair]] _opairs
  *     _opairs.reset(new vector[fst.LabelPair]())             # <<<<<<<<<<<<<<
@@ -25316,21 +26265,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, 2288, __pyx_L1_error)
+    __PYX_ERR(0, 2354, __pyx_L1_error)
   }
   __pyx_v__opairs.reset(__pyx_t_1);
 
-  /* "pywrapfst.pyx":2291
+  /* "pywrapfst.pyx":2357
  *     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, 2291, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_ipairs); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 2357, __pyx_L1_error)
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":2292
+    /* "pywrapfst.pyx":2358
  *     cdef int64 after
  *     if ipairs:
  *       for (before, after) in ipairs:             # <<<<<<<<<<<<<<
@@ -25341,26 +26290,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, 2292, __pyx_L1_error)
+      __pyx_t_4 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_ipairs); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2358, __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, 2292, __pyx_L1_error)
+      __pyx_t_5 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2358, __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, 2292, __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, 2358, __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, 2292, __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, 2358, __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, 2292, __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, 2358, __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, 2292, __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, 2358, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_6);
           #endif
         }
@@ -25370,7 +26319,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
           PyObject* exc_type = PyErr_Occurred();
           if (exc_type) {
             if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
-            else __PYX_ERR(0, 2292, __pyx_L1_error)
+            else __PYX_ERR(0, 2358, __pyx_L1_error)
           }
           break;
         }
@@ -25382,7 +26331,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, 2292, __pyx_L1_error)
+          __PYX_ERR(0, 2358, __pyx_L1_error)
         }
         #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
         if (likely(PyTuple_CheckExact(sequence))) {
@@ -25395,15 +26344,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, 2292, __pyx_L1_error)
+        __pyx_t_7 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 2358, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_7);
-        __pyx_t_8 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2292, __pyx_L1_error)
+        __pyx_t_8 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2358, __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, 2292, __pyx_L1_error)
+        __pyx_t_9 = PyObject_GetIter(__pyx_t_6); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 2358, __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;
@@ -25411,7 +26360,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, 2292, __pyx_L1_error)
+        if (__Pyx_IternextUnpackEndCheck(__pyx_t_10(__pyx_t_9), 2) < 0) __PYX_ERR(0, 2358, __pyx_L1_error)
         __pyx_t_10 = NULL;
         __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
         goto __pyx_L7_unpacking_done;
@@ -25419,17 +26368,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, 2292, __pyx_L1_error)
+        __PYX_ERR(0, 2358, __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, 2292, __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, 2358, __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, 2292, __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, 2358, __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":2293
+      /* "pywrapfst.pyx":2359
  *     if ipairs:
  *       for (before, after) in ipairs:
  *         _ipairs.get().push_back(fst.LabelPair(before, after))             # <<<<<<<<<<<<<<
@@ -25440,16 +26389,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, 2293, __pyx_L1_error)
+        __PYX_ERR(0, 2359, __pyx_L1_error)
       }
       try {
         __pyx_v__ipairs.get()->push_back(__pyx_t_13);
       } catch(...) {
         __Pyx_CppExn2PyErr();
-        __PYX_ERR(0, 2293, __pyx_L1_error)
+        __PYX_ERR(0, 2359, __pyx_L1_error)
       }
 
-      /* "pywrapfst.pyx":2292
+      /* "pywrapfst.pyx":2358
  *     cdef int64 after
  *     if ipairs:
  *       for (before, after) in ipairs:             # <<<<<<<<<<<<<<
@@ -25459,7 +26408,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":2291
+    /* "pywrapfst.pyx":2357
  *     cdef int64 before
  *     cdef int64 after
  *     if ipairs:             # <<<<<<<<<<<<<<
@@ -25468,17 +26417,17 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
  */
   }
 
-  /* "pywrapfst.pyx":2294
+  /* "pywrapfst.pyx":2360
  *       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, 2294, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_opairs); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 2360, __pyx_L1_error)
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":2295
+    /* "pywrapfst.pyx":2361
  *         _ipairs.get().push_back(fst.LabelPair(before, after))
  *     if opairs:
  *       for (before, after) in opairs:             # <<<<<<<<<<<<<<
@@ -25489,26 +26438,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, 2295, __pyx_L1_error)
+      __pyx_t_4 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_opairs); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2361, __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, 2295, __pyx_L1_error)
+      __pyx_t_5 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2361, __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, 2295, __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, 2361, __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, 2295, __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, 2361, __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, 2295, __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, 2361, __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, 2295, __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, 2361, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_6);
           #endif
         }
@@ -25518,7 +26467,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
           PyObject* exc_type = PyErr_Occurred();
           if (exc_type) {
             if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
-            else __PYX_ERR(0, 2295, __pyx_L1_error)
+            else __PYX_ERR(0, 2361, __pyx_L1_error)
           }
           break;
         }
@@ -25530,7 +26479,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, 2295, __pyx_L1_error)
+          __PYX_ERR(0, 2361, __pyx_L1_error)
         }
         #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
         if (likely(PyTuple_CheckExact(sequence))) {
@@ -25543,15 +26492,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, 2295, __pyx_L1_error)
+        __pyx_t_8 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2361, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
-        __pyx_t_7 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 2295, __pyx_L1_error)
+        __pyx_t_7 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 2361, __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, 2295, __pyx_L1_error)
+        __pyx_t_9 = PyObject_GetIter(__pyx_t_6); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 2361, __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;
@@ -25559,7 +26508,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, 2295, __pyx_L1_error)
+        if (__Pyx_IternextUnpackEndCheck(__pyx_t_10(__pyx_t_9), 2) < 0) __PYX_ERR(0, 2361, __pyx_L1_error)
         __pyx_t_10 = NULL;
         __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
         goto __pyx_L12_unpacking_done;
@@ -25567,37 +26516,37 @@ 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, 2295, __pyx_L1_error)
+        __PYX_ERR(0, 2361, __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, 2295, __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, 2361, __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, 2295, __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, 2361, __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":2296
+      /* "pywrapfst.pyx":2362
  *     if opairs:
  *       for (before, after) in opairs:
  *         _opairs.get().push_back(fst.LabelPair(before, after))             # <<<<<<<<<<<<<<
  *     if _ipairs.get().empty() and _opairs.get().empty():
- *       raise FstArgError("No relabeling pairs specified.")
+ *       raise FstArgError("No relabeling pairs specified")
  */
       try {
         __pyx_t_13 = __pyx_t_3fst_LabelPair(__pyx_v_before, __pyx_v_after);
       } catch(...) {
         __Pyx_CppExn2PyErr();
-        __PYX_ERR(0, 2296, __pyx_L1_error)
+        __PYX_ERR(0, 2362, __pyx_L1_error)
       }
       try {
         __pyx_v__opairs.get()->push_back(__pyx_t_13);
       } catch(...) {
         __Pyx_CppExn2PyErr();
-        __PYX_ERR(0, 2296, __pyx_L1_error)
+        __PYX_ERR(0, 2362, __pyx_L1_error)
       }
 
-      /* "pywrapfst.pyx":2295
+      /* "pywrapfst.pyx":2361
  *         _ipairs.get().push_back(fst.LabelPair(before, after))
  *     if opairs:
  *       for (before, after) in opairs:             # <<<<<<<<<<<<<<
@@ -25607,7 +26556,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":2294
+    /* "pywrapfst.pyx":2360
  *       for (before, after) in ipairs:
  *         _ipairs.get().push_back(fst.LabelPair(before, after))
  *     if opairs:             # <<<<<<<<<<<<<<
@@ -25616,11 +26565,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
  */
   }
 
-  /* "pywrapfst.pyx":2297
+  /* "pywrapfst.pyx":2363
  *       for (before, after) in opairs:
  *         _opairs.get().push_back(fst.LabelPair(before, after))
  *     if _ipairs.get().empty() and _opairs.get().empty():             # <<<<<<<<<<<<<<
- *       raise FstArgError("No relabeling pairs specified.")
+ *       raise FstArgError("No relabeling pairs specified")
  *     fst.Relabel(self._mfst.get(), deref(_ipairs), deref(_opairs))
  */
   __pyx_t_14 = (__pyx_v__ipairs.get()->empty() != 0);
@@ -25634,14 +26583,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
   __pyx_L14_bool_binop_done:;
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":2298
+    /* "pywrapfst.pyx":2364
  *         _opairs.get().push_back(fst.LabelPair(before, after))
  *     if _ipairs.get().empty() and _opairs.get().empty():
- *       raise FstArgError("No relabeling pairs specified.")             # <<<<<<<<<<<<<<
+ *       raise FstArgError("No relabeling pairs specified")             # <<<<<<<<<<<<<<
  *     fst.Relabel(self._mfst.get(), deref(_ipairs), deref(_opairs))
  *     self._check_mutating_imethod()
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2298, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2364, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __pyx_t_7 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_6))) {
@@ -25655,37 +26604,37 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
     }
     __pyx_t_3 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_kp_u_No_relabeling_pairs_specified) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_kp_u_No_relabeling_pairs_specified);
     __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2298, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2364, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 2298, __pyx_L1_error)
+    __PYX_ERR(0, 2364, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2297
+    /* "pywrapfst.pyx":2363
  *       for (before, after) in opairs:
  *         _opairs.get().push_back(fst.LabelPair(before, after))
  *     if _ipairs.get().empty() and _opairs.get().empty():             # <<<<<<<<<<<<<<
- *       raise FstArgError("No relabeling pairs specified.")
+ *       raise FstArgError("No relabeling pairs specified")
  *     fst.Relabel(self._mfst.get(), deref(_ipairs), deref(_opairs))
  */
   }
 
-  /* "pywrapfst.pyx":2299
+  /* "pywrapfst.pyx":2365
  *     if _ipairs.get().empty() and _opairs.get().empty():
- *       raise FstArgError("No relabeling pairs specified.")
+ *       raise FstArgError("No relabeling pairs specified")
  *     fst.Relabel(self._mfst.get(), deref(_ipairs), deref(_opairs))             # <<<<<<<<<<<<<<
  *     self._check_mutating_imethod()
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2299, __pyx_L1_error)
+    __PYX_ERR(0, 2365, __pyx_L1_error)
   }
   fst::script::Relabel(__pyx_v_self->_mfst.get(), (*__pyx_v__ipairs), (*__pyx_v__opairs));
 
-  /* "pywrapfst.pyx":2300
- *       raise FstArgError("No relabeling pairs specified.")
+  /* "pywrapfst.pyx":2366
+ *       raise FstArgError("No relabeling pairs specified")
  *     fst.Relabel(self._mfst.get(), deref(_ipairs), deref(_opairs))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
  * 
@@ -25693,11 +26642,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2300, __pyx_L1_error)
+    __PYX_ERR(0, 2366, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2300, __pyx_L1_error)
+  ((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, 2366, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2284
+  /* "pywrapfst.pyx":2350
  *     return self
  * 
  *   cdef void _relabel_pairs(self, ipairs=None, opairs=None) except *:             # <<<<<<<<<<<<<<
@@ -25718,7 +26667,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2302
+/* "pywrapfst.pyx":2368
  *     self._check_mutating_imethod()
  * 
  *   def relabel_pairs(self, ipairs=None, opairs=None):             # <<<<<<<<<<<<<<
@@ -25728,7 +26677,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_41relabel_pairs(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_40relabel_pairs[] = "\n    relabel_pairs(self, ipairs=None, opairs=None)\n\n    Replaces input and/or output labels using pairs of labels.\n\n    This operation destructively relabels the input and/or output labels of the\n    FST using pairs of the form (old_ID, new_ID); omitted indices are\n    identity-mapped.\n\n    Args:\n      ipairs: An iterable containing (older index, newer index) integer pairs.\n      opairs: An iterable containing (older index, newer index) integer pairs.\n\n    Returns:\n      self.\n\n    Raises:\n      FstArgError: No relabeling pairs specified.\n\n    See also: `decode`, `encode`, `project`, `relabel_tables`.\n    ";
+static char __pyx_doc_9pywrapfst_11_MutableFst_40relabel_pairs[] = "\n    relabel_pairs(self, ipairs=None, opairs=None)\n\n    Replaces input and/or output labels using pairs of labels.\n\n    This operation destructively relabels the input and/or output labels of the\n    FST using pairs of the form (old_ID, new_ID); omitted indices are\n    identity-mapped.\n\n    Args:\n      ipairs: An iterable containing (older index, newer index) integer pairs.\n      opairs: An iterable containing (older index, newer index) integer pairs.\n\n    Returns:\n      self.\n\n    Raises:\n      FstArgError: No relabeling pairs specified.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_41relabel_pairs(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_ipairs = 0;
   PyObject *__pyx_v_opairs = 0;
@@ -25766,7 +26715,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_41relabel_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, 2302, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "relabel_pairs") < 0)) __PYX_ERR(0, 2368, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -25783,7 +26732,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_41relabel_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, 2302, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("relabel_pairs", 0, 0, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2368, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.relabel_pairs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -25802,8 +26751,8 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_40relabel_pairs(struct __pyx_
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__relabel_pairs __pyx_t_1;
   __Pyx_RefNannySetupContext("relabel_pairs", 0);
 
-  /* "pywrapfst.pyx":2324
- *     See also: `decode`, `encode`, `project`, `relabel_tables`.
+  /* "pywrapfst.pyx":2388
+ *       FstArgError: No relabeling pairs specified.
  *     """
  *     self._relabel_pairs(ipairs, opairs)             # <<<<<<<<<<<<<<
  *     return self
@@ -25811,14 +26760,14 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_40relabel_pairs(struct __pyx_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_relabel_pairs");
-    __PYX_ERR(0, 2324, __pyx_L1_error)
+    __PYX_ERR(0, 2388, __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, 2324, __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, 2388, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2325
+  /* "pywrapfst.pyx":2389
  *     """
  *     self._relabel_pairs(ipairs, opairs)
  *     return self             # <<<<<<<<<<<<<<
@@ -25830,7 +26779,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_40relabel_pairs(struct __pyx_
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2302
+  /* "pywrapfst.pyx":2368
  *     self._check_mutating_imethod()
  * 
  *   def relabel_pairs(self, ipairs=None, opairs=None):             # <<<<<<<<<<<<<<
@@ -25848,7 +26797,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_40relabel_pairs(struct __pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2327
+/* "pywrapfst.pyx":2391
  *     return self
  * 
  *   cdef void _relabel_tables(self,             # <<<<<<<<<<<<<<
@@ -25858,7 +26807,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_40relabel_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":2328
+  /* "pywrapfst.pyx":2392
  * 
  *   cdef void _relabel_tables(self,
  *                             _SymbolTable old_isymbols=None,             # <<<<<<<<<<<<<<
@@ -25867,7 +26816,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":2329
+  /* "pywrapfst.pyx":2393
  *   cdef void _relabel_tables(self,
  *                             _SymbolTable old_isymbols=None,
  *                             _SymbolTable new_isymbols=None,             # <<<<<<<<<<<<<<
@@ -25875,9 +26824,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__10);
+  PyObject *__pyx_v_unknown_isymbol = ((PyObject *)__pyx_kp_b__8);
 
-  /* "pywrapfst.pyx":2331
+  /* "pywrapfst.pyx":2395
  *                             _SymbolTable new_isymbols=None,
  *                             unknown_isymbol=b"",
  *                             bool attach_new_isymbols=True,             # <<<<<<<<<<<<<<
@@ -25886,7 +26835,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
   bool __pyx_v_attach_new_isymbols = ((bool)1);
 
-  /* "pywrapfst.pyx":2332
+  /* "pywrapfst.pyx":2396
  *                             unknown_isymbol=b"",
  *                             bool attach_new_isymbols=True,
  *                             _SymbolTable old_osymbols=None,             # <<<<<<<<<<<<<<
@@ -25895,7 +26844,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":2333
+  /* "pywrapfst.pyx":2397
  *                             bool attach_new_isymbols=True,
  *                             _SymbolTable old_osymbols=None,
  *                             _SymbolTable new_osymbols=None,             # <<<<<<<<<<<<<<
@@ -25903,9 +26852,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__10);
+  PyObject *__pyx_v_unknown_osymbol = ((PyObject *)__pyx_kp_b__8);
 
-  /* "pywrapfst.pyx":2335
+  /* "pywrapfst.pyx":2399
  *                             _SymbolTable new_osymbols=None,
  *                             unknown_osymbol=b"",
  *                             bool attach_new_osymbols=True) except *:             # <<<<<<<<<<<<<<
@@ -25913,8 +26862,10 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  *       raise FstArgError("No new SymbolTables specified")
  */
   bool __pyx_v_attach_new_osymbols = ((bool)1);
-  fst::SymbolTable *__pyx_v_new_isymbols_ptr;
-  fst::SymbolTable *__pyx_v_new_osymbols_ptr;
+  fst::SymbolTable const *__pyx_v__old_isymbols;
+  fst::SymbolTable const *__pyx_v__old_osymbols;
+  fst::SymbolTable const *__pyx_v__new_isymbols;
+  fst::SymbolTable const *__pyx_v__new_osymbols;
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
   int __pyx_t_2;
@@ -25923,10 +26874,8 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
   PyObject *__pyx_t_5 = NULL;
   PyObject *__pyx_t_6 = NULL;
   fst::SymbolTable *__pyx_t_7;
-  fst::SymbolTable const *__pyx_t_8;
+  std::string __pyx_t_8;
   std::string __pyx_t_9;
-  fst::SymbolTable const *__pyx_t_10;
-  std::string __pyx_t_11;
   __Pyx_RefNannySetupContext("_relabel_tables", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -25955,12 +26904,12 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
     }
   }
 
-  /* "pywrapfst.pyx":2336
+  /* "pywrapfst.pyx":2400
  *                             unknown_osymbol=b"",
  *                             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
+ *     cdef const fst.SymbolTable *_old_isymbols = self._fst.get().InputSymbols()
  */
   __pyx_t_2 = (((PyObject *)__pyx_v_new_isymbols) == Py_None);
   __pyx_t_3 = (__pyx_t_2 != 0);
@@ -25975,14 +26924,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
   __pyx_L4_bool_binop_done:;
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2337
+    /* "pywrapfst.pyx":2401
  *                             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:
+ *     cdef const fst.SymbolTable *_old_isymbols = self._fst.get().InputSymbols()
+ *     if old_isymbols is not None:
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2337, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2401, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __pyx_t_6 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
@@ -25996,193 +26945,243 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
     }
     __pyx_t_4 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_6, __pyx_kp_u_No_new_SymbolTables_specified) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_kp_u_No_new_SymbolTables_specified);
     __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2337, __pyx_L1_error)
+    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2401, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_Raise(__pyx_t_4, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __PYX_ERR(0, 2337, __pyx_L1_error)
+    __PYX_ERR(0, 2401, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2336
+    /* "pywrapfst.pyx":2400
  *                             unknown_osymbol=b"",
  *                             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
+ *     cdef const fst.SymbolTable *_old_isymbols = self._fst.get().InputSymbols()
  */
   }
 
-  /* "pywrapfst.pyx":2338
+  /* "pywrapfst.pyx":2402
  *     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:
- *       new_isymbols_ptr = new_isymbols._table
+ *     cdef const fst.SymbolTable *_old_isymbols = self._fst.get().InputSymbols()             # <<<<<<<<<<<<<<
+ *     if old_isymbols is not None:
+ *       _old_isymbols = old_isymbols._table
  */
-  __pyx_v_new_isymbols_ptr = NULL;
+  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
+    __PYX_ERR(0, 2402, __pyx_L1_error)
+  }
+  __pyx_v__old_isymbols = __pyx_v_self->__pyx_base._fst.get()->InputSymbols();
 
-  /* "pywrapfst.pyx":2339
+  /* "pywrapfst.pyx":2403
  *       raise FstArgError("No new SymbolTables specified")
- *     cdef fst.SymbolTable *new_isymbols_ptr = NULL
+ *     cdef const fst.SymbolTable *_old_isymbols = self._fst.get().InputSymbols()
+ *     if old_isymbols is not None:             # <<<<<<<<<<<<<<
+ *       _old_isymbols = old_isymbols._table
+ *     cdef const fst.SymbolTable *_old_osymbols = self._fst.get().OutputSymbols()
+ */
+  __pyx_t_1 = (((PyObject *)__pyx_v_old_isymbols) != Py_None);
+  __pyx_t_2 = (__pyx_t_1 != 0);
+  if (__pyx_t_2) {
+
+    /* "pywrapfst.pyx":2404
+ *     cdef const fst.SymbolTable *_old_isymbols = self._fst.get().InputSymbols()
+ *     if old_isymbols is not None:
+ *       _old_isymbols = old_isymbols._table             # <<<<<<<<<<<<<<
+ *     cdef const fst.SymbolTable *_old_osymbols = self._fst.get().OutputSymbols()
+ *     if old_osymbols is not None:
+ */
+    if (unlikely(((PyObject *)__pyx_v_old_isymbols) == Py_None)) {
+      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
+      __PYX_ERR(0, 2404, __pyx_L1_error)
+    }
+    __pyx_t_7 = __pyx_v_old_isymbols->_table;
+    __pyx_v__old_isymbols = __pyx_t_7;
+
+    /* "pywrapfst.pyx":2403
+ *       raise FstArgError("No new SymbolTables specified")
+ *     cdef const fst.SymbolTable *_old_isymbols = self._fst.get().InputSymbols()
+ *     if old_isymbols is not None:             # <<<<<<<<<<<<<<
+ *       _old_isymbols = old_isymbols._table
+ *     cdef const fst.SymbolTable *_old_osymbols = self._fst.get().OutputSymbols()
+ */
+  }
+
+  /* "pywrapfst.pyx":2405
+ *     if old_isymbols is not None:
+ *       _old_isymbols = old_isymbols._table
+ *     cdef const fst.SymbolTable *_old_osymbols = self._fst.get().OutputSymbols()             # <<<<<<<<<<<<<<
+ *     if old_osymbols is not None:
+ *        _old_osymbols = old_osymbols._table
+ */
+  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
+    __PYX_ERR(0, 2405, __pyx_L1_error)
+  }
+  __pyx_v__old_osymbols = __pyx_v_self->__pyx_base._fst.get()->OutputSymbols();
+
+  /* "pywrapfst.pyx":2406
+ *       _old_isymbols = old_isymbols._table
+ *     cdef const fst.SymbolTable *_old_osymbols = self._fst.get().OutputSymbols()
+ *     if old_osymbols is not None:             # <<<<<<<<<<<<<<
+ *        _old_osymbols = old_osymbols._table
+ *     cdef const fst.SymbolTable *_new_isymbols = NULL
+ */
+  __pyx_t_2 = (((PyObject *)__pyx_v_old_osymbols) != Py_None);
+  __pyx_t_1 = (__pyx_t_2 != 0);
+  if (__pyx_t_1) {
+
+    /* "pywrapfst.pyx":2407
+ *     cdef const fst.SymbolTable *_old_osymbols = self._fst.get().OutputSymbols()
+ *     if old_osymbols is not None:
+ *        _old_osymbols = old_osymbols._table             # <<<<<<<<<<<<<<
+ *     cdef const fst.SymbolTable *_new_isymbols = NULL
+ *     if new_isymbols is not None:
+ */
+    if (unlikely(((PyObject *)__pyx_v_old_osymbols) == Py_None)) {
+      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
+      __PYX_ERR(0, 2407, __pyx_L1_error)
+    }
+    __pyx_t_7 = __pyx_v_old_osymbols->_table;
+    __pyx_v__old_osymbols = __pyx_t_7;
+
+    /* "pywrapfst.pyx":2406
+ *       _old_isymbols = old_isymbols._table
+ *     cdef const fst.SymbolTable *_old_osymbols = self._fst.get().OutputSymbols()
+ *     if old_osymbols is not None:             # <<<<<<<<<<<<<<
+ *        _old_osymbols = old_osymbols._table
+ *     cdef const fst.SymbolTable *_new_isymbols = NULL
+ */
+  }
+
+  /* "pywrapfst.pyx":2408
+ *     if old_osymbols is not None:
+ *        _old_osymbols = old_osymbols._table
+ *     cdef const fst.SymbolTable *_new_isymbols = NULL             # <<<<<<<<<<<<<<
+ *     if new_isymbols is not None:
+ *       _new_isymbols = new_isymbols._table
+ */
+  __pyx_v__new_isymbols = NULL;
+
+  /* "pywrapfst.pyx":2409
+ *        _old_osymbols = old_osymbols._table
+ *     cdef const fst.SymbolTable *_new_isymbols = NULL
  *     if new_isymbols is not None:             # <<<<<<<<<<<<<<
- *       new_isymbols_ptr = new_isymbols._table
- *     cdef fst.SymbolTable *new_osymbols_ptr = NULL
+ *       _new_isymbols = new_isymbols._table
+ *     cdef const fst.SymbolTable *_new_osymbols = NULL
  */
   __pyx_t_1 = (((PyObject *)__pyx_v_new_isymbols) != Py_None);
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":2340
- *     cdef fst.SymbolTable *new_isymbols_ptr = NULL
+    /* "pywrapfst.pyx":2410
+ *     cdef const fst.SymbolTable *_new_isymbols = NULL
  *     if new_isymbols is not None:
- *       new_isymbols_ptr = new_isymbols._table             # <<<<<<<<<<<<<<
- *     cdef fst.SymbolTable *new_osymbols_ptr = NULL
+ *       _new_isymbols = new_isymbols._table             # <<<<<<<<<<<<<<
+ *     cdef const fst.SymbolTable *_new_osymbols = NULL
  *     if new_osymbols is not None:
  */
     if (unlikely(((PyObject *)__pyx_v_new_isymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 2340, __pyx_L1_error)
+      __PYX_ERR(0, 2410, __pyx_L1_error)
     }
     __pyx_t_7 = __pyx_v_new_isymbols->_table;
-    __pyx_v_new_isymbols_ptr = __pyx_t_7;
+    __pyx_v__new_isymbols = __pyx_t_7;
 
-    /* "pywrapfst.pyx":2339
- *       raise FstArgError("No new SymbolTables specified")
- *     cdef fst.SymbolTable *new_isymbols_ptr = NULL
+    /* "pywrapfst.pyx":2409
+ *        _old_osymbols = old_osymbols._table
+ *     cdef const fst.SymbolTable *_new_isymbols = NULL
  *     if new_isymbols is not None:             # <<<<<<<<<<<<<<
- *       new_isymbols_ptr = new_isymbols._table
- *     cdef fst.SymbolTable *new_osymbols_ptr = NULL
+ *       _new_isymbols = new_isymbols._table
+ *     cdef const fst.SymbolTable *_new_osymbols = NULL
  */
   }
 
-  /* "pywrapfst.pyx":2341
+  /* "pywrapfst.pyx":2411
  *     if new_isymbols is not None:
- *       new_isymbols_ptr = new_isymbols._table
- *     cdef fst.SymbolTable *new_osymbols_ptr = NULL             # <<<<<<<<<<<<<<
+ *       _new_isymbols = new_isymbols._table
+ *     cdef const fst.SymbolTable *_new_osymbols = NULL             # <<<<<<<<<<<<<<
  *     if new_osymbols is not None:
- *       new_osymbols_ptr = new_osymbols._table
+ *       _new_osymbols = new_osymbols._table
  */
-  __pyx_v_new_osymbols_ptr = NULL;
+  __pyx_v__new_osymbols = NULL;
 
-  /* "pywrapfst.pyx":2342
- *       new_isymbols_ptr = new_isymbols._table
- *     cdef fst.SymbolTable *new_osymbols_ptr = NULL
+  /* "pywrapfst.pyx":2412
+ *       _new_isymbols = new_isymbols._table
+ *     cdef const fst.SymbolTable *_new_osymbols = NULL
  *     if new_osymbols is not None:             # <<<<<<<<<<<<<<
- *       new_osymbols_ptr = new_osymbols._table
+ *       _new_osymbols = new_osymbols._table
  *     fst.Relabel(self._mfst.get(),
  */
   __pyx_t_2 = (((PyObject *)__pyx_v_new_osymbols) != Py_None);
   __pyx_t_1 = (__pyx_t_2 != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2343
- *     cdef fst.SymbolTable *new_osymbols_ptr = NULL
+    /* "pywrapfst.pyx":2413
+ *     cdef const fst.SymbolTable *_new_osymbols = NULL
  *     if new_osymbols is not None:
- *       new_osymbols_ptr = new_osymbols._table             # <<<<<<<<<<<<<<
+ *       _new_osymbols = new_osymbols._table             # <<<<<<<<<<<<<<
  *     fst.Relabel(self._mfst.get(),
- *         self._fst.get().InputSymbols() if old_isymbols is None else
+ *         _old_isymbols,
  */
     if (unlikely(((PyObject *)__pyx_v_new_osymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 2343, __pyx_L1_error)
+      __PYX_ERR(0, 2413, __pyx_L1_error)
     }
     __pyx_t_7 = __pyx_v_new_osymbols->_table;
-    __pyx_v_new_osymbols_ptr = __pyx_t_7;
+    __pyx_v__new_osymbols = __pyx_t_7;
 
-    /* "pywrapfst.pyx":2342
- *       new_isymbols_ptr = new_isymbols._table
- *     cdef fst.SymbolTable *new_osymbols_ptr = NULL
+    /* "pywrapfst.pyx":2412
+ *       _new_isymbols = new_isymbols._table
+ *     cdef const fst.SymbolTable *_new_osymbols = NULL
  *     if new_osymbols is not None:             # <<<<<<<<<<<<<<
- *       new_osymbols_ptr = new_osymbols._table
+ *       _new_osymbols = new_osymbols._table
  *     fst.Relabel(self._mfst.get(),
  */
   }
 
-  /* "pywrapfst.pyx":2344
+  /* "pywrapfst.pyx":2414
  *     if new_osymbols is not None:
- *       new_osymbols_ptr = new_osymbols._table
+ *       _new_osymbols = new_osymbols._table
  *     fst.Relabel(self._mfst.get(),             # <<<<<<<<<<<<<<
- *         self._fst.get().InputSymbols() if old_isymbols is None else
- *         old_isymbols._table, new_isymbols_ptr, tostring(unknown_isymbol),
+ *         _old_isymbols,
+ *         _new_isymbols,
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2344, __pyx_L1_error)
+    __PYX_ERR(0, 2414, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2345
- *       new_osymbols_ptr = new_osymbols._table
- *     fst.Relabel(self._mfst.get(),
- *         self._fst.get().InputSymbols() if old_isymbols is None else             # <<<<<<<<<<<<<<
- *         old_isymbols._table, new_isymbols_ptr, tostring(unknown_isymbol),
+  /* "pywrapfst.pyx":2417
+ *         _old_isymbols,
+ *         _new_isymbols,
+ *         tostring(unknown_isymbol),             # <<<<<<<<<<<<<<
  *         attach_new_isymbols,
+ *         _old_osymbols,
  */
-  __pyx_t_1 = (((PyObject *)__pyx_v_old_isymbols) == Py_None);
-  if ((__pyx_t_1 != 0)) {
-    if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-      __PYX_ERR(0, 2345, __pyx_L1_error)
-    }
-    __pyx_t_8 = __pyx_v_self->__pyx_base._fst.get()->InputSymbols();
-  } else {
-
-    /* "pywrapfst.pyx":2346
- *     fst.Relabel(self._mfst.get(),
- *         self._fst.get().InputSymbols() if old_isymbols is None else
- *         old_isymbols._table, new_isymbols_ptr, tostring(unknown_isymbol),             # <<<<<<<<<<<<<<
- *         attach_new_isymbols,
- *         self._fst.get().OutputSymbols() if old_osymbols is None else
- */
-    if (unlikely(((PyObject *)__pyx_v_old_isymbols) == Py_None)) {
-      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 2346, __pyx_L1_error)
-    }
-    __pyx_t_8 = __pyx_v_old_isymbols->_table;
-  }
-  __pyx_t_9 = __pyx_f_9pywrapfst_tostring(__pyx_v_unknown_isymbol); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2346, __pyx_L1_error)
-
-  /* "pywrapfst.pyx":2348
- *         old_isymbols._table, new_isymbols_ptr, tostring(unknown_isymbol),
- *         attach_new_isymbols,
- *         self._fst.get().OutputSymbols() if old_osymbols is None else             # <<<<<<<<<<<<<<
- *         old_osymbols._table, new_osymbols_ptr, tostring(unknown_osymbol),
- *         attach_new_osymbols)
- */
-  __pyx_t_1 = (((PyObject *)__pyx_v_old_osymbols) == Py_None);
-  if ((__pyx_t_1 != 0)) {
-    if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-      __PYX_ERR(0, 2348, __pyx_L1_error)
-    }
-    __pyx_t_10 = __pyx_v_self->__pyx_base._fst.get()->OutputSymbols();
-  } else {
+  __pyx_t_8 = __pyx_f_9pywrapfst_tostring(__pyx_v_unknown_isymbol); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2417, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2349
- *         attach_new_isymbols,
- *         self._fst.get().OutputSymbols() if old_osymbols is None else
- *         old_osymbols._table, new_osymbols_ptr, tostring(unknown_osymbol),             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":2421
+ *         _old_osymbols,
+ *         _new_osymbols,
+ *         tostring(unknown_osymbol),             # <<<<<<<<<<<<<<
  *         attach_new_osymbols)
  *     self._check_mutating_imethod()
  */
-    if (unlikely(((PyObject *)__pyx_v_old_osymbols) == Py_None)) {
-      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 2349, __pyx_L1_error)
-    }
-    __pyx_t_10 = __pyx_v_old_osymbols->_table;
-  }
-  __pyx_t_11 = __pyx_f_9pywrapfst_tostring(__pyx_v_unknown_osymbol); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2349, __pyx_L1_error)
+  __pyx_t_9 = __pyx_f_9pywrapfst_tostring(__pyx_v_unknown_osymbol); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2421, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2344
+  /* "pywrapfst.pyx":2414
  *     if new_osymbols is not None:
- *       new_osymbols_ptr = new_osymbols._table
+ *       _new_osymbols = new_osymbols._table
  *     fst.Relabel(self._mfst.get(),             # <<<<<<<<<<<<<<
- *         self._fst.get().InputSymbols() if old_isymbols is None else
- *         old_isymbols._table, new_isymbols_ptr, tostring(unknown_isymbol),
+ *         _old_isymbols,
+ *         _new_isymbols,
  */
-  fst::script::Relabel(__pyx_v_self->_mfst.get(), __pyx_t_8, __pyx_v_new_isymbols_ptr, __pyx_t_9, __pyx_v_attach_new_isymbols, __pyx_t_10, __pyx_v_new_osymbols_ptr, __pyx_t_11, __pyx_v_attach_new_osymbols);
+  fst::script::Relabel(__pyx_v_self->_mfst.get(), __pyx_v__old_isymbols, __pyx_v__new_isymbols, __pyx_t_8, __pyx_v_attach_new_isymbols, __pyx_v__old_osymbols, __pyx_v__new_osymbols, __pyx_t_9, __pyx_v_attach_new_osymbols);
 
-  /* "pywrapfst.pyx":2351
- *         old_osymbols._table, new_osymbols_ptr, tostring(unknown_osymbol),
+  /* "pywrapfst.pyx":2423
+ *         tostring(unknown_osymbol),
  *         attach_new_osymbols)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
  * 
@@ -26190,11 +27189,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2351, __pyx_L1_error)
+    __PYX_ERR(0, 2423, __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, 2423, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2327
+  /* "pywrapfst.pyx":2391
  *     return self
  * 
  *   cdef void _relabel_tables(self,             # <<<<<<<<<<<<<<
@@ -26213,7 +27212,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2353
+/* "pywrapfst.pyx":2425
  *     self._check_mutating_imethod()
  * 
  *   def relabel_tables(self,             # <<<<<<<<<<<<<<
@@ -26223,7 +27222,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_43relabel_tables(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_42relabel_tables[] = "\n    relabel_tables(self, old_isymbols=None, new_isymbols=None,\n                   unknown_isymbol=\"\", attach_new_isymbols=True,\n                   old_osymbols=None, new_osymbols=None,\n                   unknown_osymbol=\"\", attach_new_osymbols=True)\n\n    Replaces input and/or output labels using SymbolTables.\n\n    This operation destructively relabels the input and/or output labels of the\n    FST using user-specified symbol tables; omitted symbols are identity-mapped.\n\n    Args:\n       old_isymbols: The old SymbolTable for input labels, defaulting to the\n          FST's input symbol table.\n       new_isymbols: A SymbolTable used to relabel the input labels\n       unknown_isymbol: Input symbol to use to relabel OOVs (if empty,\n          OOVs raise an exception)\n       attach_new_isymbols: Should new_isymbols be made the FST's input symbol\n          table?\n       old_osymbols: The old SymbolTable for output labels, defaulting to the\n          FST's output symbol table.\n       new_osymbols: A SymbolTable used to relabel the output labels.\n       unknown_osymbol: Outnput symbol to use to relabel OOVs (if empty,\n          OOVs raise an exception)\n       attach_new_isymbols: Should new_osymbols be made the FST's output symbol\n          table?\n\n    Returns:\n      self.\n\n    Raises:\n      FstArgError: No SymbolTable specified.\n\n    See also: `decode`, `encode`, `project`, `relabel_pairs`.\n    ";
+static char __pyx_doc_9pywrapfst_11_MutableFst_42relabel_tables[] = "\n    relabel_tables(self, old_isymbols=None, new_isymbols=None,\n                   unknown_isymbol=\"\", attach_new_isymbols=True,\n                   old_osymbols=None, new_osymbols=None,\n                   unknown_osymbol=\"\", attach_new_osymbols=True)\n\n    Replaces input and/or output labels using SymbolTables.\n\n    This operation destructively relabels the input and/or output labels of the\n    FST using user-specified symbol tables; omitted symbols are identity-mapped.\n\n    Args:\n       old_isymbols: The old SymbolTable for input labels, defaulting to the\n          FST's input symbol table.\n       new_isymbols: A SymbolTable used to relabel the input labels\n       unknown_isymbol: Input symbol to use to relabel OOVs (if empty,\n          OOVs raise an exception)\n       attach_new_isymbols: Should new_isymbols be made the FST's input symbol\n          table?\n       old_osymbols: The old SymbolTable for output labels, defaulting to the\n          FST's output symbol table.\n       new_osymbols: A SymbolTable used to relabel the output labels.\n       unknown_osymbol: Outnput symbol to use to relabel OOVs (if empty,\n          OOVs raise an exception)\n       attach_new_isymbols: Should new_osymbols be made the FST's output symbol\n          table?\n\n    Returns:\n      self.\n\n    Raises:\n      FstArgError: No SymbolTable specified.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_43relabel_tables(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_old_isymbols = 0;
   struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_new_isymbols = 0;
@@ -26240,7 +27239,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_43relabel_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":2354
+    /* "pywrapfst.pyx":2426
  * 
  *   def relabel_tables(self,
  *                      _SymbolTable old_isymbols=None,             # <<<<<<<<<<<<<<
@@ -26249,7 +27248,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_43relabel_tables(PyObject *__
  */
     values[0] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
 
-    /* "pywrapfst.pyx":2355
+    /* "pywrapfst.pyx":2427
  *   def relabel_tables(self,
  *                      _SymbolTable old_isymbols=None,
  *                      _SymbolTable new_isymbols=None,             # <<<<<<<<<<<<<<
@@ -26257,9 +27256,9 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_43relabel_tables(PyObject *__
  *                      bool attach_new_isymbols=True,
  */
     values[1] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
-    values[2] = ((PyObject *)__pyx_kp_b__10);
+    values[2] = ((PyObject *)__pyx_kp_b__8);
 
-    /* "pywrapfst.pyx":2358
+    /* "pywrapfst.pyx":2430
  *                      unknown_isymbol=b"",
  *                      bool attach_new_isymbols=True,
  *                      _SymbolTable old_osymbols=None,             # <<<<<<<<<<<<<<
@@ -26268,7 +27267,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_43relabel_tables(PyObject *__
  */
     values[4] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
 
-    /* "pywrapfst.pyx":2359
+    /* "pywrapfst.pyx":2431
  *                      bool attach_new_isymbols=True,
  *                      _SymbolTable old_osymbols=None,
  *                      _SymbolTable new_osymbols=None,             # <<<<<<<<<<<<<<
@@ -26276,7 +27275,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_43relabel_tables(PyObject *__
  *                      bool attach_new_osymbols=True):
  */
     values[5] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
-    values[6] = ((PyObject *)__pyx_kp_b__10);
+    values[6] = ((PyObject *)__pyx_kp_b__8);
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
       const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
@@ -26351,7 +27350,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_43relabel_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, 2353, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "relabel_tables") < 0)) __PYX_ERR(0, 2425, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -26379,10 +27378,10 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_43relabel_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, 2357, __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, 2429, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":2357
+      /* "pywrapfst.pyx":2429
  *                      _SymbolTable new_isymbols=None,
  *                      unknown_isymbol=b"",
  *                      bool attach_new_isymbols=True,             # <<<<<<<<<<<<<<
@@ -26395,10 +27394,10 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_43relabel_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, 2361, __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, 2433, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":2361
+      /* "pywrapfst.pyx":2433
  *                      _SymbolTable new_osymbols=None,
  *                      unknown_osymbol=b"",
  *                      bool attach_new_osymbols=True):             # <<<<<<<<<<<<<<
@@ -26410,19 +27409,19 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_43relabel_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, 2353, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("relabel_tables", 0, 0, 8, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2425, __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, 2354, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_new_isymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "new_isymbols", 0))) __PYX_ERR(0, 2355, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_old_osymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "old_osymbols", 0))) __PYX_ERR(0, 2358, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_new_osymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "new_osymbols", 0))) __PYX_ERR(0, 2359, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_old_isymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "old_isymbols", 0))) __PYX_ERR(0, 2426, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_new_isymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "new_isymbols", 0))) __PYX_ERR(0, 2427, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_old_osymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "old_osymbols", 0))) __PYX_ERR(0, 2430, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_new_osymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "new_osymbols", 0))) __PYX_ERR(0, 2431, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_42relabel_tables(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_old_isymbols, __pyx_v_new_isymbols, __pyx_v_unknown_isymbol, __pyx_v_attach_new_isymbols, __pyx_v_old_osymbols, __pyx_v_new_osymbols, __pyx_v_unknown_osymbol, __pyx_v_attach_new_osymbols);
 
-  /* "pywrapfst.pyx":2353
+  /* "pywrapfst.pyx":2425
  *     self._check_mutating_imethod()
  * 
  *   def relabel_tables(self,             # <<<<<<<<<<<<<<
@@ -26445,22 +27444,22 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_42relabel_tables(struct __pyx
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__relabel_tables __pyx_t_1;
   __Pyx_RefNannySetupContext("relabel_tables", 0);
 
-  /* "pywrapfst.pyx":2397
- *     See also: `decode`, `encode`, `project`, `relabel_pairs`.
+  /* "pywrapfst.pyx":2467
+ *       FstArgError: No SymbolTable specified.
  *     """
- *     self._relabel_tables(old_isymbols, new_isymbols,             # <<<<<<<<<<<<<<
- *                          unknown_isymbol, attach_new_isymbols,
- *                          old_osymbols, new_osymbols,
+ *     self._relabel_tables(old_isymbols,             # <<<<<<<<<<<<<<
+ *                          new_isymbols,
+ *                          unknown_isymbol,
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_relabel_tables");
-    __PYX_ERR(0, 2397, __pyx_L1_error)
+    __PYX_ERR(0, 2467, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2400
- *                          unknown_isymbol, attach_new_isymbols,
- *                          old_osymbols, new_osymbols,
- *                          unknown_osymbol, attach_new_osymbols)             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":2474
+ *                          new_osymbols,
+ *                          unknown_osymbol,
+ *                          attach_new_osymbols)             # <<<<<<<<<<<<<<
  *     return self
  * 
  */
@@ -26473,11 +27472,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_42relabel_tables(struct __pyx
   __pyx_t_1.new_osymbols = __pyx_v_new_osymbols;
   __pyx_t_1.unknown_osymbol = __pyx_v_unknown_osymbol;
   __pyx_t_1.attach_new_osymbols = __pyx_v_attach_new_osymbols;
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_relabel_tables(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2397, __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, 2467, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2401
- *                          old_osymbols, new_osymbols,
- *                          unknown_osymbol, attach_new_osymbols)
+  /* "pywrapfst.pyx":2475
+ *                          unknown_osymbol,
+ *                          attach_new_osymbols)
  *     return self             # <<<<<<<<<<<<<<
  * 
  *   cdef void _reserve_arcs(self, int64 state, size_t n) except *:
@@ -26487,7 +27486,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_42relabel_tables(struct __pyx
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2353
+  /* "pywrapfst.pyx":2425
  *     self._check_mutating_imethod()
  * 
  *   def relabel_tables(self,             # <<<<<<<<<<<<<<
@@ -26505,7 +27504,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_42relabel_tables(struct __pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2403
+/* "pywrapfst.pyx":2477
  *     return self
  * 
  *   cdef void _reserve_arcs(self, int64 state, size_t n) except *:             # <<<<<<<<<<<<<<
@@ -26521,7 +27520,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_arcs(struct __pyx_obj_9pyw
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("_reserve_arcs", 0);
 
-  /* "pywrapfst.pyx":2404
+  /* "pywrapfst.pyx":2478
  * 
  *   cdef void _reserve_arcs(self, int64 state, size_t n) except *:
  *     if not self._mfst.get().ReserveArcs(state, n):             # <<<<<<<<<<<<<<
@@ -26530,19 +27529,19 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_arcs(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2404, __pyx_L1_error)
+    __PYX_ERR(0, 2478, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->ReserveArcs(__pyx_v_state, __pyx_v_n) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2405
+    /* "pywrapfst.pyx":2479
  *   cdef void _reserve_arcs(self, int64 state, size_t n) except *:
  *     if not self._mfst.get().ReserveArcs(state, n):
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     self._check_mutating_imethod()
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2405, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2479, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -26556,14 +27555,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_arcs(struct __pyx_obj_9pyw
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2405, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2479, __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, 2405, __pyx_L1_error)
+    __PYX_ERR(0, 2479, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2404
+    /* "pywrapfst.pyx":2478
  * 
  *   cdef void _reserve_arcs(self, int64 state, size_t n) except *:
  *     if not self._mfst.get().ReserveArcs(state, n):             # <<<<<<<<<<<<<<
@@ -26572,7 +27571,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_arcs(struct __pyx_obj_9pyw
  */
   }
 
-  /* "pywrapfst.pyx":2406
+  /* "pywrapfst.pyx":2480
  *     if not self._mfst.get().ReserveArcs(state, n):
  *       raise FstIndexError("State index out of range")
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -26581,11 +27580,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_arcs(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2406, __pyx_L1_error)
+    __PYX_ERR(0, 2480, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2406, __pyx_L1_error)
+  ((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, 2480, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2403
+  /* "pywrapfst.pyx":2477
  *     return self
  * 
  *   cdef void _reserve_arcs(self, int64 state, size_t n) except *:             # <<<<<<<<<<<<<<
@@ -26604,7 +27603,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_arcs(struct __pyx_obj_9pyw
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2408
+/* "pywrapfst.pyx":2482
  *     self._check_mutating_imethod()
  * 
  *   def reserve_arcs(self, int64 state, size_t n):             # <<<<<<<<<<<<<<
@@ -26614,7 +27613,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_arcs(struct __pyx_obj_9pyw
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_45reserve_arcs(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_44reserve_arcs[] = "\n    reserve_arcs(self, state, n)\n\n    Reserve n arcs at a particular state (best effort).\n\n    Args:\n      state: The integer index of a state.\n      n: The number of arcs to reserve.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n\n    See also: `reserve_states`.\n    ";
+static char __pyx_doc_9pywrapfst_11_MutableFst_44reserve_arcs[] = "\n    reserve_arcs(self, state, n)\n\n    Reserve n arcs at a particular state (best effort).\n\n    Args:\n      state: The integer index of a state.\n      n: The number of arcs to reserve.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_45reserve_arcs(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   __pyx_t_10basictypes_int64 __pyx_v_state;
   size_t __pyx_v_n;
@@ -26644,11 +27643,11 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_45reserve_arcs(PyObject *__py
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_n)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("reserve_arcs", 1, 2, 2, 1); __PYX_ERR(0, 2408, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("reserve_arcs", 1, 2, 2, 1); __PYX_ERR(0, 2482, __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, 2408, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reserve_arcs") < 0)) __PYX_ERR(0, 2482, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -26656,12 +27655,12 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_45reserve_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, 2408, __pyx_L3_error)
-    __pyx_v_n = __Pyx_PyInt_As_size_t(values[1]); if (unlikely((__pyx_v_n == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 2408, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[0]); if (unlikely((__pyx_v_state == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2482, __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, 2482, __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, 2408, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("reserve_arcs", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2482, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.reserve_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -26679,8 +27678,8 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_44reserve_arcs(struct __pyx_o
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("reserve_arcs", 0);
 
-  /* "pywrapfst.pyx":2426
- *     See also: `reserve_states`.
+  /* "pywrapfst.pyx":2498
+ *       FstIndexError: State index out of range.
  *     """
  *     self._reserve_arcs(state, n)             # <<<<<<<<<<<<<<
  *     return self
@@ -26688,11 +27687,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_44reserve_arcs(struct __pyx_o
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reserve_arcs");
-    __PYX_ERR(0, 2426, __pyx_L1_error)
+    __PYX_ERR(0, 2498, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_reserve_arcs(__pyx_v_self, __pyx_v_state, __pyx_v_n); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2426, __pyx_L1_error)
+  ((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, 2498, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2427
+  /* "pywrapfst.pyx":2499
  *     """
  *     self._reserve_arcs(state, n)
  *     return self             # <<<<<<<<<<<<<<
@@ -26704,7 +27703,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_44reserve_arcs(struct __pyx_o
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2408
+  /* "pywrapfst.pyx":2482
  *     self._check_mutating_imethod()
  * 
  *   def reserve_arcs(self, int64 state, size_t n):             # <<<<<<<<<<<<<<
@@ -26722,7 +27721,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_44reserve_arcs(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2429
+/* "pywrapfst.pyx":2501
  *     return self
  * 
  *   cdef void _reserve_states(self, int64 n) except *:             # <<<<<<<<<<<<<<
@@ -26734,7 +27733,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_states(struct __pyx_obj_9p
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_reserve_states", 0);
 
-  /* "pywrapfst.pyx":2430
+  /* "pywrapfst.pyx":2502
  * 
  *   cdef void _reserve_states(self, int64 n) except *:
  *     self._mfst.get().ReserveStates(n)             # <<<<<<<<<<<<<<
@@ -26743,11 +27742,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_states(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2430, __pyx_L1_error)
+    __PYX_ERR(0, 2502, __pyx_L1_error)
   }
   __pyx_v_self->_mfst.get()->ReserveStates(__pyx_v_n);
 
-  /* "pywrapfst.pyx":2431
+  /* "pywrapfst.pyx":2503
  *   cdef void _reserve_states(self, int64 n) except *:
  *     self._mfst.get().ReserveStates(n)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -26756,11 +27755,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_states(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2431, __pyx_L1_error)
+    __PYX_ERR(0, 2503, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2431, __pyx_L1_error)
+  ((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, 2503, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2429
+  /* "pywrapfst.pyx":2501
  *     return self
  * 
  *   cdef void _reserve_states(self, int64 n) except *:             # <<<<<<<<<<<<<<
@@ -26776,7 +27775,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_states(struct __pyx_obj_9p
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2433
+/* "pywrapfst.pyx":2505
  *     self._check_mutating_imethod()
  * 
  *   def reserve_states(self, int64 n):             # <<<<<<<<<<<<<<
@@ -26786,14 +27785,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_states(struct __pyx_obj_9p
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_47reserve_states(PyObject *__pyx_v_self, PyObject *__pyx_arg_n); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_46reserve_states[] = "\n    reserve_states(self, n)\n\n    Reserve n states (best effort).\n\n    Args:\n      n: The number of states to reserve.\n\n    Returns:\n      self.\n\n    See also: `reserve_arcs`.\n    ";
+static char __pyx_doc_9pywrapfst_11_MutableFst_46reserve_states[] = "\n    reserve_states(self, n)\n\n    Reserve n states (best effort).\n\n    Args:\n      n: The number of states to reserve.\n\n    Returns:\n      self.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_47reserve_states(PyObject *__pyx_v_self, PyObject *__pyx_arg_n) {
   __pyx_t_10basictypes_int64 __pyx_v_n;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("reserve_states (wrapper)", 0);
   assert(__pyx_arg_n); {
-    __pyx_v_n = __Pyx_PyInt_As_int64_t(__pyx_arg_n); if (unlikely((__pyx_v_n == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2433, __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, 2505, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -26813,8 +27812,8 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_46reserve_states(struct __pyx
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("reserve_states", 0);
 
-  /* "pywrapfst.pyx":2447
- *     See also: `reserve_arcs`.
+  /* "pywrapfst.pyx":2517
+ *       self.
  *     """
  *     self._reserve_states(n)             # <<<<<<<<<<<<<<
  *     return self
@@ -26822,11 +27821,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_46reserve_states(struct __pyx
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reserve_states");
-    __PYX_ERR(0, 2447, __pyx_L1_error)
+    __PYX_ERR(0, 2517, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_reserve_states(__pyx_v_self, __pyx_v_n); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2447, __pyx_L1_error)
+  ((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, 2517, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2448
+  /* "pywrapfst.pyx":2518
  *     """
  *     self._reserve_states(n)
  *     return self             # <<<<<<<<<<<<<<
@@ -26838,7 +27837,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_46reserve_states(struct __pyx
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2433
+  /* "pywrapfst.pyx":2505
  *     self._check_mutating_imethod()
  * 
  *   def reserve_states(self, int64 n):             # <<<<<<<<<<<<<<
@@ -26856,7 +27855,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_46reserve_states(struct __pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2450
+/* "pywrapfst.pyx":2520
  *     return self
  * 
  *   cdef void _reweight(self, potentials, bool to_final=False) except *:             # <<<<<<<<<<<<<<
@@ -26883,7 +27882,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
     }
   }
 
-  /* "pywrapfst.pyx":2452
+  /* "pywrapfst.pyx":2522
  *   cdef void _reweight(self, potentials, bool to_final=False) except *:
  *     cdef unique_ptr[vector[fst.WeightClass]] _potentials
  *     _potentials.reset(new vector[fst.WeightClass]())             # <<<<<<<<<<<<<<
@@ -26894,11 +27893,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, 2452, __pyx_L1_error)
+    __PYX_ERR(0, 2522, __pyx_L1_error)
   }
   __pyx_v__potentials.reset(__pyx_t_1);
 
-  /* "pywrapfst.pyx":2453
+  /* "pywrapfst.pyx":2523
  *     cdef unique_ptr[vector[fst.WeightClass]] _potentials
  *     _potentials.reset(new vector[fst.WeightClass]())
  *     cdef string weight_type = self.weight_type()             # <<<<<<<<<<<<<<
@@ -26907,11 +27906,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 2453, __pyx_L1_error)
+    __PYX_ERR(0, 2523, __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":2454
+  /* "pywrapfst.pyx":2524
  *     _potentials.reset(new vector[fst.WeightClass]())
  *     cdef string weight_type = self.weight_type()
  *     for weight in potentials:             # <<<<<<<<<<<<<<
@@ -26922,26 +27921,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, 2454, __pyx_L1_error)
+    __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_potentials); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2524, __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, 2454, __pyx_L1_error)
+    __pyx_t_4 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2524, __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, 2454, __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, 2524, __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, 2454, __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, 2524, __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, 2454, __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, 2524, __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, 2454, __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, 2524, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_5);
         #endif
       }
@@ -26951,7 +27950,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
         PyObject* exc_type = PyErr_Occurred();
         if (exc_type) {
           if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
-          else __PYX_ERR(0, 2454, __pyx_L1_error)
+          else __PYX_ERR(0, 2524, __pyx_L1_error)
         }
         break;
       }
@@ -26960,7 +27959,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":2455
+    /* "pywrapfst.pyx":2525
  *     cdef string weight_type = self.weight_type()
  *     for weight in potentials:
  *         _potentials.get().push_back(_get_WeightClass_or_One(self.weight_type(),             # <<<<<<<<<<<<<<
@@ -26969,19 +27968,19 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
  */
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-      __PYX_ERR(0, 2455, __pyx_L1_error)
+      __PYX_ERR(0, 2525, __pyx_L1_error)
     }
 
-    /* "pywrapfst.pyx":2456
+    /* "pywrapfst.pyx":2526
  *     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, 2455, __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, 2525, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2455
+    /* "pywrapfst.pyx":2525
  *     cdef string weight_type = self.weight_type()
  *     for weight in potentials:
  *         _potentials.get().push_back(_get_WeightClass_or_One(self.weight_type(),             # <<<<<<<<<<<<<<
@@ -26992,10 +27991,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, 2455, __pyx_L1_error)
+      __PYX_ERR(0, 2525, __pyx_L1_error)
     }
 
-    /* "pywrapfst.pyx":2454
+    /* "pywrapfst.pyx":2524
  *     _potentials.reset(new vector[fst.WeightClass]())
  *     cdef string weight_type = self.weight_type()
  *     for weight in potentials:             # <<<<<<<<<<<<<<
@@ -27005,7 +28004,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
   }
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2457
+  /* "pywrapfst.pyx":2527
  *         _potentials.get().push_back(_get_WeightClass_or_One(self.weight_type(),
  *                                                             weight))
  *     fst.Reweight(self._mfst.get(), deref(_potentials),             # <<<<<<<<<<<<<<
@@ -27014,10 +28013,10 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2457, __pyx_L1_error)
+    __PYX_ERR(0, 2527, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2458
+  /* "pywrapfst.pyx":2528
  *                                                             weight))
  *     fst.Reweight(self._mfst.get(), deref(_potentials),
  *                  fst.GetReweightType(to_final))             # <<<<<<<<<<<<<<
@@ -27026,7 +28025,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":2459
+  /* "pywrapfst.pyx":2529
  *     fst.Reweight(self._mfst.get(), deref(_potentials),
  *                  fst.GetReweightType(to_final))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -27035,11 +28034,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2459, __pyx_L1_error)
+    __PYX_ERR(0, 2529, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2459, __pyx_L1_error)
+  ((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, 2529, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2450
+  /* "pywrapfst.pyx":2520
  *     return self
  * 
  *   cdef void _reweight(self, potentials, bool to_final=False) except *:             # <<<<<<<<<<<<<<
@@ -27058,7 +28057,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2461
+/* "pywrapfst.pyx":2531
  *     self._check_mutating_imethod()
  * 
  *   def reweight(self, potentials, bool to_final=False):             # <<<<<<<<<<<<<<
@@ -27102,7 +28101,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_49reweight(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, 2461, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reweight") < 0)) __PYX_ERR(0, 2531, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -27115,14 +28114,14 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_49reweight(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, 2461, __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, 2531, __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, 2461, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("reweight", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2531, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.reweight", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -27141,7 +28140,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_48reweight(struct __pyx_obj_9
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__reweight __pyx_t_1;
   __Pyx_RefNannySetupContext("reweight", 0);
 
-  /* "pywrapfst.pyx":2483
+  /* "pywrapfst.pyx":2553
  *       self.
  *     """
  *     self._reweight(potentials, to_final)             # <<<<<<<<<<<<<<
@@ -27150,13 +28149,13 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_48reweight(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reweight");
-    __PYX_ERR(0, 2483, __pyx_L1_error)
+    __PYX_ERR(0, 2553, __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, 2483, __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, 2553, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2484
+  /* "pywrapfst.pyx":2554
  *     """
  *     self._reweight(potentials, to_final)
  *     return self             # <<<<<<<<<<<<<<
@@ -27168,7 +28167,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_48reweight(struct __pyx_obj_9
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2461
+  /* "pywrapfst.pyx":2531
  *     self._check_mutating_imethod()
  * 
  *   def reweight(self, potentials, bool to_final=False):             # <<<<<<<<<<<<<<
@@ -27186,7 +28185,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_48reweight(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2486
+/* "pywrapfst.pyx":2556
  *     return self
  * 
  *   cdef void _rmepsilon(self,             # <<<<<<<<<<<<<<
@@ -27197,7 +28196,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_48reweight(struct __pyx_obj_9
 static void __pyx_f_9pywrapfst_11_MutableFst__rmepsilon(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__rmepsilon *__pyx_optional_args) {
   PyObject *__pyx_v_queue_type = ((PyObject *)__pyx_n_b_auto);
 
-  /* "pywrapfst.pyx":2488
+  /* "pywrapfst.pyx":2558
  *   cdef void _rmepsilon(self,
  *                        queue_type=b"auto",
  *                        bool connect=True,             # <<<<<<<<<<<<<<
@@ -27206,7 +28205,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__rmepsilon(struct __pyx_obj_9pywrap
  */
   bool __pyx_v_connect = ((bool)1);
 
-  /* "pywrapfst.pyx":2489
+  /* "pywrapfst.pyx":2559
  *                        queue_type=b"auto",
  *                        bool connect=True,
  *                        weight=None,             # <<<<<<<<<<<<<<
@@ -27214,8 +28213,8 @@ static void __pyx_f_9pywrapfst_11_MutableFst__rmepsilon(struct __pyx_obj_9pywrap
  *                        float delta=fst.kShortestDelta) except *:
  */
   PyObject *__pyx_v_weight = ((PyObject *)Py_None);
-  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__19;
-  float __pyx_v_delta = __pyx_k__20;
+  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__17;
+  float __pyx_v_delta = __pyx_k__18;
   fst::script::WeightClass __pyx_v_wc;
   std::unique_ptr<fst::script::RmEpsilonOptions>  __pyx_v_opts;
   __Pyx_RefNannyDeclarations
@@ -27241,7 +28240,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__rmepsilon(struct __pyx_obj_9pywrap
     }
   }
 
-  /* "pywrapfst.pyx":2492
+  /* "pywrapfst.pyx":2562
  *                        int64 nstate=fst.kNoStateId,
  *                        float delta=fst.kShortestDelta) except *:
  *     cdef fst.WeightClass wc = _get_WeightClass_or_Zero(self.weight_type(),             # <<<<<<<<<<<<<<
@@ -27250,53 +28249,53 @@ static void __pyx_f_9pywrapfst_11_MutableFst__rmepsilon(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 2492, __pyx_L1_error)
+    __PYX_ERR(0, 2562, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2493
+  /* "pywrapfst.pyx":2563
  *                        float delta=fst.kShortestDelta) except *:
  *     cdef fst.WeightClass wc = _get_WeightClass_or_Zero(self.weight_type(),
  *                                                        weight)             # <<<<<<<<<<<<<<
  *     cdef unique_ptr[fst.RmEpsilonOptions] opts
  *     opts.reset(new fst.RmEpsilonOptions(_get_queue_type(tostring(queue_type)),
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_Zero(((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.weight_type(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self), 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2492, __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, 2562, __pyx_L1_error)
   __pyx_v_wc = __pyx_t_1;
 
-  /* "pywrapfst.pyx":2495
+  /* "pywrapfst.pyx":2565
  *                                                        weight)
  *     cdef unique_ptr[fst.RmEpsilonOptions] opts
  *     opts.reset(new fst.RmEpsilonOptions(_get_queue_type(tostring(queue_type)),             # <<<<<<<<<<<<<<
- *                                         connect, wc, nstate, delta))
- *     fst.RmEpsilon(self._mfst.get(), deref(opts))
+ *                                         connect,
+ *                                         wc,
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_queue_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2495, __pyx_L1_error)
-  __pyx_t_3 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2495, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_queue_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2565, __pyx_L1_error)
+  __pyx_t_3 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2565, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2496
- *     cdef unique_ptr[fst.RmEpsilonOptions] opts
- *     opts.reset(new fst.RmEpsilonOptions(_get_queue_type(tostring(queue_type)),
- *                                         connect, wc, nstate, delta))             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":2569
+ *                                         wc,
+ *                                         nstate,
+ *                                         delta))             # <<<<<<<<<<<<<<
  *     fst.RmEpsilon(self._mfst.get(), deref(opts))
  *     self._check_mutating_imethod()
  */
   __pyx_v_opts.reset(new fst::script::RmEpsilonOptions(__pyx_t_3, __pyx_v_connect, __pyx_v_wc, __pyx_v_nstate, __pyx_v_delta));
 
-  /* "pywrapfst.pyx":2497
- *     opts.reset(new fst.RmEpsilonOptions(_get_queue_type(tostring(queue_type)),
- *                                         connect, wc, nstate, delta))
+  /* "pywrapfst.pyx":2570
+ *                                         nstate,
+ *                                         delta))
  *     fst.RmEpsilon(self._mfst.get(), deref(opts))             # <<<<<<<<<<<<<<
  *     self._check_mutating_imethod()
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2497, __pyx_L1_error)
+    __PYX_ERR(0, 2570, __pyx_L1_error)
   }
   fst::script::RmEpsilon(__pyx_v_self->_mfst.get(), (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":2498
- *                                         connect, wc, nstate, delta))
+  /* "pywrapfst.pyx":2571
+ *                                         delta))
  *     fst.RmEpsilon(self._mfst.get(), deref(opts))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
  * 
@@ -27304,11 +28303,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__rmepsilon(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2498, __pyx_L1_error)
+    __PYX_ERR(0, 2571, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2498, __pyx_L1_error)
+  ((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, 2571, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2486
+  /* "pywrapfst.pyx":2556
  *     return self
  * 
  *   cdef void _rmepsilon(self,             # <<<<<<<<<<<<<<
@@ -27324,7 +28323,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__rmepsilon(struct __pyx_obj_9pywrap
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2500
+/* "pywrapfst.pyx":2573
  *     self._check_mutating_imethod()
  * 
  *   def rmepsilon(self,             # <<<<<<<<<<<<<<
@@ -27349,7 +28348,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_51rmepsilon(PyObject *__pyx_v
     PyObject* values[5] = {0,0,0,0,0};
     values[0] = ((PyObject *)__pyx_n_b_auto);
 
-    /* "pywrapfst.pyx":2503
+    /* "pywrapfst.pyx":2576
  *                 queue_type=b"auto",
  *                 bool connect=True,
  *                 weight=None,             # <<<<<<<<<<<<<<
@@ -27407,7 +28406,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_51rmepsilon(PyObject *__pyx_v
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "rmepsilon") < 0)) __PYX_ERR(0, 2500, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "rmepsilon") < 0)) __PYX_ERR(0, 2573, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -27427,10 +28426,10 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_51rmepsilon(PyObject *__pyx_v
     }
     __pyx_v_queue_type = values[0];
     if (values[1]) {
-      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2502, __pyx_L3_error)
+      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2575, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":2502
+      /* "pywrapfst.pyx":2575
  *   def rmepsilon(self,
  *                 queue_type=b"auto",
  *                 bool connect=True,             # <<<<<<<<<<<<<<
@@ -27441,19 +28440,19 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_51rmepsilon(PyObject *__pyx_v
     }
     __pyx_v_weight = values[2];
     if (values[3]) {
-      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_nstate == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2504, __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, 2577, __pyx_L3_error)
     } else {
-      __pyx_v_nstate = __pyx_k__21;
+      __pyx_v_nstate = __pyx_k__19;
     }
     if (values[4]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[4]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2505, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[4]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2578, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__22;
+      __pyx_v_delta = __pyx_k__20;
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("rmepsilon", 0, 0, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2500, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("rmepsilon", 0, 0, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2573, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.rmepsilon", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -27461,7 +28460,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_51rmepsilon(PyObject *__pyx_v
   __pyx_L4_argument_unpacking_done:;
   __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_50rmepsilon(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_queue_type, __pyx_v_connect, __pyx_v_weight, __pyx_v_nstate, __pyx_v_delta);
 
-  /* "pywrapfst.pyx":2500
+  /* "pywrapfst.pyx":2573
  *     self._check_mutating_imethod()
  * 
  *   def rmepsilon(self,             # <<<<<<<<<<<<<<
@@ -27480,7 +28479,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_50rmepsilon(struct __pyx_obj_
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__rmepsilon __pyx_t_1;
   __Pyx_RefNannySetupContext("rmepsilon", 0);
 
-  /* "pywrapfst.pyx":2527
+  /* "pywrapfst.pyx":2600
  *       self.
  *     """
  *     self._rmepsilon(queue_type, connect, weight, nstate, delta)             # <<<<<<<<<<<<<<
@@ -27489,7 +28488,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_50rmepsilon(struct __pyx_obj_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_rmepsilon");
-    __PYX_ERR(0, 2527, __pyx_L1_error)
+    __PYX_ERR(0, 2600, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 5;
   __pyx_t_1.queue_type = __pyx_v_queue_type;
@@ -27497,9 +28496,9 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_50rmepsilon(struct __pyx_obj_
   __pyx_t_1.weight = __pyx_v_weight;
   __pyx_t_1.nstate = __pyx_v_nstate;
   __pyx_t_1.delta = __pyx_v_delta;
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_rmepsilon(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2527, __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, 2600, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2528
+  /* "pywrapfst.pyx":2601
  *     """
  *     self._rmepsilon(queue_type, connect, weight, nstate, delta)
  *     return self             # <<<<<<<<<<<<<<
@@ -27511,7 +28510,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_50rmepsilon(struct __pyx_obj_
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2500
+  /* "pywrapfst.pyx":2573
  *     self._check_mutating_imethod()
  * 
  *   def rmepsilon(self,             # <<<<<<<<<<<<<<
@@ -27529,7 +28528,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_50rmepsilon(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2530
+/* "pywrapfst.pyx":2603
  *     return self
  * 
  *   cdef void _set_final(self, int64 state, weight=None) except *:             # <<<<<<<<<<<<<<
@@ -27553,7 +28552,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
     }
   }
 
-  /* "pywrapfst.pyx":2531
+  /* "pywrapfst.pyx":2604
  * 
  *   cdef void _set_final(self, int64 state, weight=None) except *:
  *     if not self._mfst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -27562,19 +28561,19 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2531, __pyx_L1_error)
+    __PYX_ERR(0, 2604, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->ValidStateId(__pyx_v_state) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2532
+    /* "pywrapfst.pyx":2605
  *   cdef void _set_final(self, int64 state, weight=None) except *:
  *     if not self._mfst.get().ValidStateId(state):
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     cdef fst.WeightClass wc = _get_WeightClass_or_One(self.weight_type(),
  *                                                       weight)
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2532, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2605, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -27588,14 +28587,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2532, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2605, __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, 2532, __pyx_L1_error)
+    __PYX_ERR(0, 2605, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2531
+    /* "pywrapfst.pyx":2604
  * 
  *   cdef void _set_final(self, int64 state, weight=None) except *:
  *     if not self._mfst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -27604,7 +28603,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
  */
   }
 
-  /* "pywrapfst.pyx":2533
+  /* "pywrapfst.pyx":2606
  *     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(),             # <<<<<<<<<<<<<<
@@ -27613,20 +28612,20 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 2533, __pyx_L1_error)
+    __PYX_ERR(0, 2606, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2534
+  /* "pywrapfst.pyx":2607
  *       raise FstIndexError("State index out of range")
  *     cdef fst.WeightClass wc = _get_WeightClass_or_One(self.weight_type(),
  *                                                       weight)             # <<<<<<<<<<<<<<
  *     if not self._mfst.get().SetFinal(state, wc):
  *       raise FstOpError("Incompatible or invalid weight")
  */
-  __pyx_t_5 = __pyx_f_9pywrapfst__get_WeightClass_or_One(((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.weight_type(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self), 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2533, __pyx_L1_error)
+  __pyx_t_5 = __pyx_f_9pywrapfst__get_WeightClass_or_One(((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.weight_type(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self), 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2606, __pyx_L1_error)
   __pyx_v_wc = __pyx_t_5;
 
-  /* "pywrapfst.pyx":2535
+  /* "pywrapfst.pyx":2608
  *     cdef fst.WeightClass wc = _get_WeightClass_or_One(self.weight_type(),
  *                                                       weight)
  *     if not self._mfst.get().SetFinal(state, wc):             # <<<<<<<<<<<<<<
@@ -27635,19 +28634,19 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2535, __pyx_L1_error)
+    __PYX_ERR(0, 2608, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->SetFinal(__pyx_v_state, __pyx_v_wc) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2536
+    /* "pywrapfst.pyx":2609
  *                                                       weight)
  *     if not self._mfst.get().SetFinal(state, wc):
  *       raise FstOpError("Incompatible or invalid weight")             # <<<<<<<<<<<<<<
  *     self._check_mutating_imethod()
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2536, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2609, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -27661,14 +28660,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_Incompatible_or_invalid_weight) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_Incompatible_or_invalid_weight);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2536, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2609, __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, 2536, __pyx_L1_error)
+    __PYX_ERR(0, 2609, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2535
+    /* "pywrapfst.pyx":2608
  *     cdef fst.WeightClass wc = _get_WeightClass_or_One(self.weight_type(),
  *                                                       weight)
  *     if not self._mfst.get().SetFinal(state, wc):             # <<<<<<<<<<<<<<
@@ -27677,7 +28676,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
  */
   }
 
-  /* "pywrapfst.pyx":2537
+  /* "pywrapfst.pyx":2610
  *     if not self._mfst.get().SetFinal(state, wc):
  *       raise FstOpError("Incompatible or invalid weight")
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -27686,11 +28685,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2537, __pyx_L1_error)
+    __PYX_ERR(0, 2610, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2537, __pyx_L1_error)
+  ((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, 2610, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2530
+  /* "pywrapfst.pyx":2603
  *     return self
  * 
  *   cdef void _set_final(self, int64 state, weight=None) except *:             # <<<<<<<<<<<<<<
@@ -27709,7 +28708,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2539
+/* "pywrapfst.pyx":2612
  *     self._check_mutating_imethod()
  * 
  *   def set_final(self, int64 state, weight=None):             # <<<<<<<<<<<<<<
@@ -27719,7 +28718,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_53set_final(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_52set_final[] = "\n    set_final(self, state, weight)\n\n    Sets the final weight for a state.\n\n    Args:\n      state: The integer index of a state.\n      weight: A Weight or weight string indicating the desired final weight; if\n          omitted, it is set to semiring One.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n      FstOpError: Incompatible or invalid weight.\n\n    See also: `set_start`.\n    ";
+static char __pyx_doc_9pywrapfst_11_MutableFst_52set_final[] = "\n    set_final(self, state, weight)\n\n    Sets the final weight for a state.\n\n    Args:\n      state: The integer index of a state.\n      weight: A Weight or weight string indicating the desired final weight; if\n          omitted, it is set to semiring One.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n      FstOpError: Incompatible or invalid weight.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_53set_final(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   __pyx_t_10basictypes_int64 __pyx_v_state;
   PyObject *__pyx_v_weight = 0;
@@ -27754,7 +28753,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_53set_final(PyObject *__pyx_v
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_final") < 0)) __PYX_ERR(0, 2539, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_final") < 0)) __PYX_ERR(0, 2612, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -27765,12 +28764,12 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_53set_final(PyObject *__pyx_v
         default: goto __pyx_L5_argtuple_error;
       }
     }
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[0]); if (unlikely((__pyx_v_state == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2539, __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, 2612, __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, 2539, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("set_final", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2612, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.set_final", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -27789,8 +28788,8 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_52set_final(struct __pyx_obj_
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__set_final __pyx_t_1;
   __Pyx_RefNannySetupContext("set_final", 0);
 
-  /* "pywrapfst.pyx":2559
- *     See also: `set_start`.
+  /* "pywrapfst.pyx":2630
+ *       FstOpError: Incompatible or invalid weight.
  *     """
  *     self._set_final(state, weight)             # <<<<<<<<<<<<<<
  *     return self
@@ -27798,13 +28797,13 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_52set_final(struct __pyx_obj_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_set_final");
-    __PYX_ERR(0, 2559, __pyx_L1_error)
+    __PYX_ERR(0, 2630, __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, 2559, __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, 2630, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2560
+  /* "pywrapfst.pyx":2631
  *     """
  *     self._set_final(state, weight)
  *     return self             # <<<<<<<<<<<<<<
@@ -27816,7 +28815,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_52set_final(struct __pyx_obj_
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2539
+  /* "pywrapfst.pyx":2612
  *     self._check_mutating_imethod()
  * 
  *   def set_final(self, int64 state, weight=None):             # <<<<<<<<<<<<<<
@@ -27834,7 +28833,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_52set_final(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2562
+/* "pywrapfst.pyx":2633
  *     return self
  * 
  *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
@@ -27848,7 +28847,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_input_symbols(struct __pyx_obj
   int __pyx_t_2;
   __Pyx_RefNannySetupContext("_set_input_symbols", 0);
 
-  /* "pywrapfst.pyx":2563
+  /* "pywrapfst.pyx":2634
  * 
  *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:
  *     if syms is None:             # <<<<<<<<<<<<<<
@@ -27859,7 +28858,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_input_symbols(struct __pyx_obj
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":2564
+    /* "pywrapfst.pyx":2635
  *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:
  *     if syms is None:
  *       self._mfst.get().SetInputSymbols(NULL)             # <<<<<<<<<<<<<<
@@ -27868,11 +28867,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_input_symbols(struct __pyx_obj
  */
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-      __PYX_ERR(0, 2564, __pyx_L1_error)
+      __PYX_ERR(0, 2635, __pyx_L1_error)
     }
     __pyx_v_self->_mfst.get()->SetInputSymbols(NULL);
 
-    /* "pywrapfst.pyx":2565
+    /* "pywrapfst.pyx":2636
  *     if syms is None:
  *       self._mfst.get().SetInputSymbols(NULL)
  *       return             # <<<<<<<<<<<<<<
@@ -27881,7 +28880,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_input_symbols(struct __pyx_obj
  */
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":2563
+    /* "pywrapfst.pyx":2634
  * 
  *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:
  *     if syms is None:             # <<<<<<<<<<<<<<
@@ -27890,7 +28889,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_input_symbols(struct __pyx_obj
  */
   }
 
-  /* "pywrapfst.pyx":2566
+  /* "pywrapfst.pyx":2637
  *       self._mfst.get().SetInputSymbols(NULL)
  *       return
  *     self._mfst.get().SetInputSymbols(syms._table)             # <<<<<<<<<<<<<<
@@ -27899,15 +28898,15 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_input_symbols(struct __pyx_obj
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2566, __pyx_L1_error)
+    __PYX_ERR(0, 2637, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_syms) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 2566, __pyx_L1_error)
+    __PYX_ERR(0, 2637, __pyx_L1_error)
   }
   __pyx_v_self->_mfst.get()->SetInputSymbols(__pyx_v_syms->_table);
 
-  /* "pywrapfst.pyx":2567
+  /* "pywrapfst.pyx":2638
  *       return
  *     self._mfst.get().SetInputSymbols(syms._table)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -27916,11 +28915,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_input_symbols(struct __pyx_obj
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2567, __pyx_L1_error)
+    __PYX_ERR(0, 2638, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2567, __pyx_L1_error)
+  ((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, 2638, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2562
+  /* "pywrapfst.pyx":2633
  *     return self
  * 
  *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
@@ -27936,7 +28935,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_input_symbols(struct __pyx_obj
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2569
+/* "pywrapfst.pyx":2640
  *     self._check_mutating_imethod()
  * 
  *   def set_input_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
@@ -27946,12 +28945,12 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_input_symbols(struct __pyx_obj
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_55set_input_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_54set_input_symbols[] = "\n    set_input_symbols(self, syms)\n\n    Sets the input symbol table.\n\n    Passing None as a value will delete the input symbol table.\n\n    Args:\n      syms: A SymbolTable.\n\n    Returns:\n      self.\n\n    See also: `set_output_symbols`.\n    ";
+static char __pyx_doc_9pywrapfst_11_MutableFst_54set_input_symbols[] = "\n    set_input_symbols(self, syms)\n\n    Sets the input symbol table.\n\n    Passing None as a value will delete the input symbol table.\n\n    Args:\n      syms: A SymbolTable.\n\n    Returns:\n      self.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_55set_input_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_input_symbols (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_syms), __pyx_ptype_9pywrapfst__SymbolTable, 1, "syms", 0))) __PYX_ERR(0, 2569, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_syms), __pyx_ptype_9pywrapfst__SymbolTable, 1, "syms", 0))) __PYX_ERR(0, 2640, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_54set_input_symbols(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_syms));
 
   /* function exit code */
@@ -27968,8 +28967,8 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_54set_input_symbols(struct __
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_input_symbols", 0);
 
-  /* "pywrapfst.pyx":2585
- *     See also: `set_output_symbols`.
+  /* "pywrapfst.pyx":2654
+ *       self.
  *     """
  *     self._set_input_symbols(syms)             # <<<<<<<<<<<<<<
  *     return self
@@ -27977,11 +28976,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_54set_input_symbols(struct __
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_set_input_symbols");
-    __PYX_ERR(0, 2585, __pyx_L1_error)
+    __PYX_ERR(0, 2654, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_set_input_symbols(__pyx_v_self, __pyx_v_syms); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2585, __pyx_L1_error)
+  ((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, 2654, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2586
+  /* "pywrapfst.pyx":2655
  *     """
  *     self._set_input_symbols(syms)
  *     return self             # <<<<<<<<<<<<<<
@@ -27993,7 +28992,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_54set_input_symbols(struct __
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2569
+  /* "pywrapfst.pyx":2640
  *     self._check_mutating_imethod()
  * 
  *   def set_input_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
@@ -28011,7 +29010,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_54set_input_symbols(struct __
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2588
+/* "pywrapfst.pyx":2657
  *     return self
  * 
  *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
@@ -28025,7 +29024,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_output_symbols(struct __pyx_ob
   int __pyx_t_2;
   __Pyx_RefNannySetupContext("_set_output_symbols", 0);
 
-  /* "pywrapfst.pyx":2589
+  /* "pywrapfst.pyx":2658
  * 
  *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:
  *     if syms is None:             # <<<<<<<<<<<<<<
@@ -28036,7 +29035,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_output_symbols(struct __pyx_ob
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":2590
+    /* "pywrapfst.pyx":2659
  *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:
  *     if syms is None:
  *       self._mfst.get().SetOutputSymbols(NULL)             # <<<<<<<<<<<<<<
@@ -28045,11 +29044,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_output_symbols(struct __pyx_ob
  */
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-      __PYX_ERR(0, 2590, __pyx_L1_error)
+      __PYX_ERR(0, 2659, __pyx_L1_error)
     }
     __pyx_v_self->_mfst.get()->SetOutputSymbols(NULL);
 
-    /* "pywrapfst.pyx":2591
+    /* "pywrapfst.pyx":2660
  *     if syms is None:
  *       self._mfst.get().SetOutputSymbols(NULL)
  *       return             # <<<<<<<<<<<<<<
@@ -28058,7 +29057,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_output_symbols(struct __pyx_ob
  */
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":2589
+    /* "pywrapfst.pyx":2658
  * 
  *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:
  *     if syms is None:             # <<<<<<<<<<<<<<
@@ -28067,7 +29066,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_output_symbols(struct __pyx_ob
  */
   }
 
-  /* "pywrapfst.pyx":2592
+  /* "pywrapfst.pyx":2661
  *       self._mfst.get().SetOutputSymbols(NULL)
  *       return
  *     self._mfst.get().SetOutputSymbols(syms._table)             # <<<<<<<<<<<<<<
@@ -28076,15 +29075,15 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_output_symbols(struct __pyx_ob
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2592, __pyx_L1_error)
+    __PYX_ERR(0, 2661, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_syms) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 2592, __pyx_L1_error)
+    __PYX_ERR(0, 2661, __pyx_L1_error)
   }
   __pyx_v_self->_mfst.get()->SetOutputSymbols(__pyx_v_syms->_table);
 
-  /* "pywrapfst.pyx":2593
+  /* "pywrapfst.pyx":2662
  *       return
  *     self._mfst.get().SetOutputSymbols(syms._table)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -28093,11 +29092,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_output_symbols(struct __pyx_ob
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2593, __pyx_L1_error)
+    __PYX_ERR(0, 2662, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2593, __pyx_L1_error)
+  ((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, 2662, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2588
+  /* "pywrapfst.pyx":2657
  *     return self
  * 
  *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
@@ -28113,7 +29112,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_output_symbols(struct __pyx_ob
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2595
+/* "pywrapfst.pyx":2664
  *     self._check_mutating_imethod()
  * 
  *   def set_output_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
@@ -28123,12 +29122,12 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_output_symbols(struct __pyx_ob
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_57set_output_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_56set_output_symbols[] = "\n    set_output_symbols(self, syms)\n\n    Sets the output symbol table.\n\n    Passing None as a value will delete the output symbol table.\n\n    Args:\n      syms: A SymbolTable.\n\n    Returns:\n      self.\n\n    See also: `set_input_symbols`.\n    ";
+static char __pyx_doc_9pywrapfst_11_MutableFst_56set_output_symbols[] = "\n    set_output_symbols(self, syms)\n\n    Sets the output symbol table.\n\n    Passing None as a value will delete the output symbol table.\n\n    Args:\n      syms: A SymbolTable.\n\n    Returns:\n      self.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_57set_output_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_output_symbols (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_syms), __pyx_ptype_9pywrapfst__SymbolTable, 1, "syms", 0))) __PYX_ERR(0, 2595, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_syms), __pyx_ptype_9pywrapfst__SymbolTable, 1, "syms", 0))) __PYX_ERR(0, 2664, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_56set_output_symbols(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_syms));
 
   /* function exit code */
@@ -28145,8 +29144,8 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_56set_output_symbols(struct _
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_output_symbols", 0);
 
-  /* "pywrapfst.pyx":2611
- *     See also: `set_input_symbols`.
+  /* "pywrapfst.pyx":2678
+ *       self.
  *     """
  *     self._set_output_symbols(syms)             # <<<<<<<<<<<<<<
  *     return self
@@ -28154,11 +29153,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_56set_output_symbols(struct _
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_set_output_symbols");
-    __PYX_ERR(0, 2611, __pyx_L1_error)
+    __PYX_ERR(0, 2678, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_set_output_symbols(__pyx_v_self, __pyx_v_syms); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2611, __pyx_L1_error)
+  ((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, 2678, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2612
+  /* "pywrapfst.pyx":2679
  *     """
  *     self._set_output_symbols(syms)
  *     return self             # <<<<<<<<<<<<<<
@@ -28170,7 +29169,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_56set_output_symbols(struct _
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2595
+  /* "pywrapfst.pyx":2664
  *     self._check_mutating_imethod()
  * 
  *   def set_output_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
@@ -28188,7 +29187,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_56set_output_symbols(struct _
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2614
+/* "pywrapfst.pyx":2681
  *     return self
  * 
  *   cdef void _set_properties(self, uint64 props, uint64 mask):             # <<<<<<<<<<<<<<
@@ -28200,7 +29199,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_properties(struct __pyx_obj_9p
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_set_properties", 0);
 
-  /* "pywrapfst.pyx":2615
+  /* "pywrapfst.pyx":2682
  * 
  *   cdef void _set_properties(self, uint64 props, uint64 mask):
  *     self._mfst.get().SetProperties(props, mask)             # <<<<<<<<<<<<<<
@@ -28209,11 +29208,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_properties(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2615, __pyx_L1_error)
+    __PYX_ERR(0, 2682, __pyx_L1_error)
   }
   __pyx_v_self->_mfst.get()->SetProperties(__pyx_v_props, __pyx_v_mask);
 
-  /* "pywrapfst.pyx":2614
+  /* "pywrapfst.pyx":2681
  *     return self
  * 
  *   cdef void _set_properties(self, uint64 props, uint64 mask):             # <<<<<<<<<<<<<<
@@ -28229,7 +29228,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_properties(struct __pyx_obj_9p
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2617
+/* "pywrapfst.pyx":2684
  *     self._mfst.get().SetProperties(props, mask)
  * 
  *   def set_properties(self, uint64 props, uint64 mask):             # <<<<<<<<<<<<<<
@@ -28269,11 +29268,11 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_59set_properties(PyObject *__
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_mask)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("set_properties", 1, 2, 2, 1); __PYX_ERR(0, 2617, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("set_properties", 1, 2, 2, 1); __PYX_ERR(0, 2684, __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, 2617, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_properties") < 0)) __PYX_ERR(0, 2684, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -28281,12 +29280,12 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_59set_properties(PyObject *__
       values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
-    __pyx_v_props = __Pyx_PyInt_As_uint64_t(values[0]); if (unlikely((__pyx_v_props == ((uint64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2617, __pyx_L3_error)
-    __pyx_v_mask = __Pyx_PyInt_As_uint64_t(values[1]); if (unlikely((__pyx_v_mask == ((uint64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2617, __pyx_L3_error)
+    __pyx_v_props = __Pyx_PyInt_As_uint64_t(values[0]); if (unlikely((__pyx_v_props == ((uint64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2684, __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, 2684, __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, 2617, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("set_properties", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2684, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.set_properties", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -28304,7 +29303,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_58set_properties(struct __pyx
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_properties", 0);
 
-  /* "pywrapfst.pyx":2631
+  /* "pywrapfst.pyx":2698
  *       self.
  *     """
  *     self._set_properties(props, mask)             # <<<<<<<<<<<<<<
@@ -28313,11 +29312,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_58set_properties(struct __pyx
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_set_properties");
-    __PYX_ERR(0, 2631, __pyx_L1_error)
+    __PYX_ERR(0, 2698, __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":2632
+  /* "pywrapfst.pyx":2699
  *     """
  *     self._set_properties(props, mask)
  *     return self             # <<<<<<<<<<<<<<
@@ -28329,7 +29328,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_58set_properties(struct __pyx
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2617
+  /* "pywrapfst.pyx":2684
  *     self._mfst.get().SetProperties(props, mask)
  * 
  *   def set_properties(self, uint64 props, uint64 mask):             # <<<<<<<<<<<<<<
@@ -28347,7 +29346,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_58set_properties(struct __pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2634
+/* "pywrapfst.pyx":2701
  *     return self
  * 
  *   cdef void _set_start(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -28363,7 +29362,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_start(struct __pyx_obj_9pywrap
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("_set_start", 0);
 
-  /* "pywrapfst.pyx":2635
+  /* "pywrapfst.pyx":2702
  * 
  *   cdef void _set_start(self, int64 state) except *:
  *     if not self._mfst.get().SetStart(state):             # <<<<<<<<<<<<<<
@@ -28372,19 +29371,19 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_start(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2635, __pyx_L1_error)
+    __PYX_ERR(0, 2702, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->SetStart(__pyx_v_state) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2636
+    /* "pywrapfst.pyx":2703
  *   cdef void _set_start(self, int64 state) except *:
  *     if not self._mfst.get().SetStart(state):
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     self._check_mutating_imethod()
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2636, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2703, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -28398,14 +29397,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_start(struct __pyx_obj_9pywrap
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2636, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2703, __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, 2636, __pyx_L1_error)
+    __PYX_ERR(0, 2703, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2635
+    /* "pywrapfst.pyx":2702
  * 
  *   cdef void _set_start(self, int64 state) except *:
  *     if not self._mfst.get().SetStart(state):             # <<<<<<<<<<<<<<
@@ -28414,7 +29413,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_start(struct __pyx_obj_9pywrap
  */
   }
 
-  /* "pywrapfst.pyx":2637
+  /* "pywrapfst.pyx":2704
  *     if not self._mfst.get().SetStart(state):
  *       raise FstIndexError("State index out of range")
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -28423,11 +29422,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_start(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2637, __pyx_L1_error)
+    __PYX_ERR(0, 2704, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2637, __pyx_L1_error)
+  ((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, 2704, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2634
+  /* "pywrapfst.pyx":2701
  *     return self
  * 
  *   cdef void _set_start(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -28446,7 +29445,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_start(struct __pyx_obj_9pywrap
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2639
+/* "pywrapfst.pyx":2706
  *     self._check_mutating_imethod()
  * 
  *   def set_start(self, int64 state):             # <<<<<<<<<<<<<<
@@ -28456,14 +29455,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_start(struct __pyx_obj_9pywrap
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_61set_start(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_60set_start[] = "\n    set_start(self, state)\n\n    Sets a state to be the initial state state.\n\n    Args:\n      state: The integer index of a state.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n\n    See also: `set_final`.\n    ";
+static char __pyx_doc_9pywrapfst_11_MutableFst_60set_start[] = "\n    set_start(self, state)\n\n    Sets a state to be the initial state state.\n\n    Args:\n      state: The integer index of a state.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_61set_start(PyObject *__pyx_v_self, PyObject *__pyx_arg_state) {
   __pyx_t_10basictypes_int64 __pyx_v_state;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_start (wrapper)", 0);
   assert(__pyx_arg_state); {
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2639, __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, 2706, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -28483,8 +29482,8 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_60set_start(struct __pyx_obj_
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_start", 0);
 
-  /* "pywrapfst.pyx":2656
- *     See also: `set_final`.
+  /* "pywrapfst.pyx":2721
+ *       FstIndexError: State index out of range.
  *     """
  *     self._set_start(state)             # <<<<<<<<<<<<<<
  *     return self
@@ -28492,11 +29491,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_60set_start(struct __pyx_obj_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_set_start");
-    __PYX_ERR(0, 2656, __pyx_L1_error)
+    __PYX_ERR(0, 2721, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_set_start(__pyx_v_self, __pyx_v_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2656, __pyx_L1_error)
+  ((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, 2721, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2657
+  /* "pywrapfst.pyx":2722
  *     """
  *     self._set_start(state)
  *     return self             # <<<<<<<<<<<<<<
@@ -28508,7 +29507,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_60set_start(struct __pyx_obj_
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2639
+  /* "pywrapfst.pyx":2706
  *     self._check_mutating_imethod()
  * 
  *   def set_start(self, int64 state):             # <<<<<<<<<<<<<<
@@ -28526,7 +29525,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_60set_start(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2659
+/* "pywrapfst.pyx":2724
  *     return self
  * 
  *   cdef void _topsort(self) except *:             # <<<<<<<<<<<<<<
@@ -28542,7 +29541,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__topsort(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("_topsort", 0);
 
-  /* "pywrapfst.pyx":2661
+  /* "pywrapfst.pyx":2726
  *   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()):             # <<<<<<<<<<<<<<
@@ -28551,21 +29550,21 @@ static void __pyx_f_9pywrapfst_11_MutableFst__topsort(struct __pyx_obj_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2661, __pyx_L1_error)
+    __PYX_ERR(0, 2726, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(fst::script::TopSort(__pyx_v_self->_mfst.get()) != 0)) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2662
+    /* "pywrapfst.pyx":2727
  *     # TopSort returns False if the FST is cyclic, and thus can't be TopSorted.
  *     if not fst.TopSort(self._mfst.get()):
  *       logging.warning("Cannot topsort cyclic FST")             # <<<<<<<<<<<<<<
  *     self._check_mutating_imethod()
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_logging); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2662, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_logging); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2727, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_warning); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2662, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_warning); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2727, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __pyx_t_3 = NULL;
@@ -28580,12 +29579,12 @@ static void __pyx_f_9pywrapfst_11_MutableFst__topsort(struct __pyx_obj_9pywrapfs
     }
     __pyx_t_2 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_3, __pyx_kp_u_Cannot_topsort_cyclic_FST) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_kp_u_Cannot_topsort_cyclic_FST);
     __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2662, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2727, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-    /* "pywrapfst.pyx":2661
+    /* "pywrapfst.pyx":2726
  *   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()):             # <<<<<<<<<<<<<<
@@ -28594,7 +29593,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__topsort(struct __pyx_obj_9pywrapfs
  */
   }
 
-  /* "pywrapfst.pyx":2663
+  /* "pywrapfst.pyx":2728
  *     if not fst.TopSort(self._mfst.get()):
  *       logging.warning("Cannot topsort cyclic FST")
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -28603,11 +29602,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__topsort(struct __pyx_obj_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2663, __pyx_L1_error)
+    __PYX_ERR(0, 2728, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2663, __pyx_L1_error)
+  ((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, 2728, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2659
+  /* "pywrapfst.pyx":2724
  *     return self
  * 
  *   cdef void _topsort(self) except *:             # <<<<<<<<<<<<<<
@@ -28626,7 +29625,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__topsort(struct __pyx_obj_9pywrapfs
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2665
+/* "pywrapfst.pyx":2730
  *     self._check_mutating_imethod()
  * 
  *   def topsort(self):             # <<<<<<<<<<<<<<
@@ -28653,7 +29652,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_62topsort(struct __pyx_obj_9p
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("topsort", 0);
 
-  /* "pywrapfst.pyx":2678
+  /* "pywrapfst.pyx":2743
  *        self.
  *     """
  *     self._topsort()             # <<<<<<<<<<<<<<
@@ -28662,23 +29661,23 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_62topsort(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_topsort");
-    __PYX_ERR(0, 2678, __pyx_L1_error)
+    __PYX_ERR(0, 2743, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_topsort(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2678, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_topsort(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2743, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2679
+  /* "pywrapfst.pyx":2744
  *     """
  *     self._topsort()
  *     return self             # <<<<<<<<<<<<<<
  * 
- *   cdef void _union(self, _Fst ifst) except *:
+ *   def union(self, *fsts2):
  */
   __Pyx_XDECREF(__pyx_r);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2665
+  /* "pywrapfst.pyx":2730
  *     self._check_mutating_imethod()
  * 
  *   def topsort(self):             # <<<<<<<<<<<<<<
@@ -28696,112 +29695,120 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_62topsort(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2681
- *     return self
- * 
- *   cdef void _union(self, _Fst ifst) except *:             # <<<<<<<<<<<<<<
- *     fst.Union(self._mfst.get(), deref(ifst._fst))
- *     self._check_mutating_imethod()
- */
-
-static void __pyx_f_9pywrapfst_11_MutableFst__union(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst) {
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("_union", 0);
-
-  /* "pywrapfst.pyx":2682
- * 
- *   cdef void _union(self, _Fst ifst) except *:
- *     fst.Union(self._mfst.get(), deref(ifst._fst))             # <<<<<<<<<<<<<<
- *     self._check_mutating_imethod()
- * 
- */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2682, __pyx_L1_error)
-  }
-  if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2682, __pyx_L1_error)
-  }
-  fst::script::Union(__pyx_v_self->_mfst.get(), (*__pyx_v_ifst->_fst));
-
-  /* "pywrapfst.pyx":2683
- *   cdef void _union(self, _Fst ifst) except *:
- *     fst.Union(self._mfst.get(), deref(ifst._fst))
- *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
- * 
- *   def union(self, _Fst ifst):
- */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2683, __pyx_L1_error)
-  }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2683, __pyx_L1_error)
-
-  /* "pywrapfst.pyx":2681
+/* "pywrapfst.pyx":2746
  *     return self
  * 
- *   cdef void _union(self, _Fst ifst) except *:             # <<<<<<<<<<<<<<
- *     fst.Union(self._mfst.get(), deref(ifst._fst))
- *     self._check_mutating_imethod()
- */
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst._union", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-}
-
-/* "pywrapfst.pyx":2685
- *     self._check_mutating_imethod()
- * 
- *   def union(self, _Fst ifst):             # <<<<<<<<<<<<<<
+ *   def union(self, *fsts2):             # <<<<<<<<<<<<<<
  *     """
- *     union(self, ifst)
+ *     union(self, *fsts2)
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_65union(PyObject *__pyx_v_self, PyObject *__pyx_v_ifst); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_64union[] = "\n    union(self, ifst)\n\n    Computes the union (sum) of two FSTs.\n\n    This operation computes the union (sum) of two FSTs. If A transduces string\n    x to y with weight a and B transduces string w to v with weight b, then\n    their union transduces x to y with weight a and w to v with weight b.\n\n    Args:\n      ifst: The second input FST.\n\n    Returns:\n      self.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_65union(PyObject *__pyx_v_self, PyObject *__pyx_v_ifst) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_65union(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_64union[] = "\n    union(self, *fsts2)\n\n    Computes the union (sum) of two or more FSTs.\n\n    This operation computes the union of two or more FSTs. If A transduces\n    string x to y with weight a and B transduces string w to v with weight b,\n    then their union transduces x to y with weight a and w to v with weight b.\n\n    Args:\n      *fsts2: One or more input FSTs.\n\n    Returns:\n      self.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_65union(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_fsts2 = 0;
   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, 2685, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_64union(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_ifst));
+  if (unlikely(__pyx_kwds) && unlikely(PyDict_Size(__pyx_kwds) > 0) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "union", 0))) return NULL;
+  __Pyx_INCREF(__pyx_args);
+  __pyx_v_fsts2 = __pyx_args;
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_64union(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_fsts2);
 
   /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_fsts2);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_64union(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_64union(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_fsts2) {
+  std::vector<__pyx_t_9pywrapfst_const_FstClass_ptr>  __pyx_v__fsts2;
+  struct __pyx_obj_9pywrapfst__Fst *__pyx_v_fst2 = 0;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  Py_ssize_t __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
   __Pyx_RefNannySetupContext("union", 0);
 
-  /* "pywrapfst.pyx":2701
- *       self.
- *     """
- *     self._union(ifst)             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":2764
+ *     cdef vector[const_FstClass_ptr] _fsts2
+ *     cdef _Fst fst2
+ *     for fst2 in fsts2:             # <<<<<<<<<<<<<<
+ *       _fsts2.push_back(fst2._fst.get())
+ *     fst.Union(self._mfst.get(), _fsts2)
+ */
+  __pyx_t_1 = __pyx_v_fsts2; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
+  for (;;) {
+    if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+    #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
+    __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 2764, __pyx_L1_error)
+    #else
+    __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2764, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_3);
+    #endif
+    if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_9pywrapfst__Fst))))) __PYX_ERR(0, 2764, __pyx_L1_error)
+    __Pyx_XDECREF_SET(__pyx_v_fst2, ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_t_3));
+    __pyx_t_3 = 0;
+
+    /* "pywrapfst.pyx":2765
+ *     cdef _Fst fst2
+ *     for fst2 in fsts2:
+ *       _fsts2.push_back(fst2._fst.get())             # <<<<<<<<<<<<<<
+ *     fst.Union(self._mfst.get(), _fsts2)
+ *     self._check_mutating_imethod()
+ */
+    if (unlikely(((PyObject *)__pyx_v_fst2) == Py_None)) {
+      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
+      __PYX_ERR(0, 2765, __pyx_L1_error)
+    }
+    try {
+      __pyx_v__fsts2.push_back(__pyx_v_fst2->_fst.get());
+    } catch(...) {
+      __Pyx_CppExn2PyErr();
+      __PYX_ERR(0, 2765, __pyx_L1_error)
+    }
+
+    /* "pywrapfst.pyx":2764
+ *     cdef vector[const_FstClass_ptr] _fsts2
+ *     cdef _Fst fst2
+ *     for fst2 in fsts2:             # <<<<<<<<<<<<<<
+ *       _fsts2.push_back(fst2._fst.get())
+ *     fst.Union(self._mfst.get(), _fsts2)
+ */
+  }
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "pywrapfst.pyx":2766
+ *     for fst2 in fsts2:
+ *       _fsts2.push_back(fst2._fst.get())
+ *     fst.Union(self._mfst.get(), _fsts2)             # <<<<<<<<<<<<<<
+ *     self._check_mutating_imethod()
+ *     return self
+ */
+  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
+    __PYX_ERR(0, 2766, __pyx_L1_error)
+  }
+  fst::script::Union(__pyx_v_self->_mfst.get(), __pyx_v__fsts2);
+
+  /* "pywrapfst.pyx":2767
+ *       _fsts2.push_back(fst2._fst.get())
+ *     fst.Union(self._mfst.get(), _fsts2)
+ *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
  *     return self
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_union");
-    __PYX_ERR(0, 2701, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
+    __PYX_ERR(0, 2767, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_union(__pyx_v_self, __pyx_v_ifst); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2701, __pyx_L1_error)
+  ((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, 2767, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2702
- *     """
- *     self._union(ifst)
+  /* "pywrapfst.pyx":2768
+ *     fst.Union(self._mfst.get(), _fsts2)
+ *     self._check_mutating_imethod()
  *     return self             # <<<<<<<<<<<<<<
  * 
  * 
@@ -28811,25 +29818,28 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_64union(struct __pyx_obj_9pyw
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2685
- *     self._check_mutating_imethod()
+  /* "pywrapfst.pyx":2746
+ *     return self
  * 
- *   def union(self, _Fst ifst):             # <<<<<<<<<<<<<<
+ *   def union(self, *fsts2):             # <<<<<<<<<<<<<<
  *     """
- *     union(self, ifst)
+ *     union(self, *fsts2)
  */
 
   /* function exit code */
   __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_3);
   __Pyx_AddTraceback("pywrapfst._MutableFst.union", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_fst2);
   __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2727
+/* "pywrapfst.pyx":2793
  * 
  * 
  * cdef _Fst _init_Fst(FstClass_ptr tfst):             # <<<<<<<<<<<<<<
@@ -28847,7 +29857,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9p
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("_init_Fst", 0);
 
-  /* "pywrapfst.pyx":2728
+  /* "pywrapfst.pyx":2794
  * 
  * cdef _Fst _init_Fst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
@@ -28857,14 +29867,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9p
   __pyx_t_1 = ((__pyx_v_tfst->Properties(fst::kError, 1) == fst::kError) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2729
+    /* "pywrapfst.pyx":2795
  * cdef _Fst _init_Fst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kError, True) == fst.kError:
  *     raise FstOpError("Operation failed")             # <<<<<<<<<<<<<<
  *   cdef _Fst ofst = _Fst.__new__(_Fst)
  *   ofst._fst.reset(tfst)
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2729, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2795, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -28878,14 +29888,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9p
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_Operation_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_Operation_failed);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2729, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2795, __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, 2729, __pyx_L1_error)
+    __PYX_ERR(0, 2795, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2728
+    /* "pywrapfst.pyx":2794
  * 
  * cdef _Fst _init_Fst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
@@ -28894,19 +29904,19 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9p
  */
   }
 
-  /* "pywrapfst.pyx":2730
+  /* "pywrapfst.pyx":2796
  *   if tfst.Properties(fst.kError, True) == fst.kError:
  *     raise FstOpError("Operation failed")
  *   cdef _Fst ofst = _Fst.__new__(_Fst)             # <<<<<<<<<<<<<<
  *   ofst._fst.reset(tfst)
  *   return ofst
  */
-  __pyx_t_2 = ((PyObject *)__pyx_tp_new_9pywrapfst__Fst(((PyTypeObject *)__pyx_ptype_9pywrapfst__Fst), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2730, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_tp_new_9pywrapfst__Fst(((PyTypeObject *)__pyx_ptype_9pywrapfst__Fst), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2796, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_2));
   __pyx_v_ofst = ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_t_2);
   __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2731
+  /* "pywrapfst.pyx":2797
  *     raise FstOpError("Operation failed")
  *   cdef _Fst ofst = _Fst.__new__(_Fst)
  *   ofst._fst.reset(tfst)             # <<<<<<<<<<<<<<
@@ -28915,11 +29925,11 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9p
  */
   if (unlikely(((PyObject *)__pyx_v_ofst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2731, __pyx_L1_error)
+    __PYX_ERR(0, 2797, __pyx_L1_error)
   }
   __pyx_v_ofst->_fst.reset(__pyx_v_tfst);
 
-  /* "pywrapfst.pyx":2732
+  /* "pywrapfst.pyx":2798
  *   cdef _Fst ofst = _Fst.__new__(_Fst)
  *   ofst._fst.reset(tfst)
  *   return ofst             # <<<<<<<<<<<<<<
@@ -28931,7 +29941,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":2727
+  /* "pywrapfst.pyx":2793
  * 
  * 
  * cdef _Fst _init_Fst(FstClass_ptr tfst):             # <<<<<<<<<<<<<<
@@ -28953,7 +29963,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2735
+/* "pywrapfst.pyx":2801
  * 
  * 
  * cdef _MutableFst _init_MutableFst(MutableFstClass_ptr tfst):             # <<<<<<<<<<<<<<
@@ -28971,7 +29981,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__init_Mutable
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("_init_MutableFst", 0);
 
-  /* "pywrapfst.pyx":2736
+  /* "pywrapfst.pyx":2802
  * 
  * cdef _MutableFst _init_MutableFst(MutableFstClass_ptr tfst):
  *   if tfst.Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
@@ -28981,14 +29991,14 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__init_Mutable
   __pyx_t_1 = ((__pyx_v_tfst->Properties(fst::kError, 1) == fst::kError) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2737
+    /* "pywrapfst.pyx":2803
  * cdef _MutableFst _init_MutableFst(MutableFstClass_ptr tfst):
  *   if tfst.Properties(fst.kError, True) == fst.kError:
  *     raise FstOpError("Operation failed")             # <<<<<<<<<<<<<<
  *   cdef _MutableFst ofst = _MutableFst.__new__(_MutableFst)
  *   ofst._fst.reset(tfst)
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2737, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2803, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -29002,14 +30012,14 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__init_Mutable
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_Operation_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_Operation_failed);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2737, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2803, __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, 2737, __pyx_L1_error)
+    __PYX_ERR(0, 2803, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2736
+    /* "pywrapfst.pyx":2802
  * 
  * cdef _MutableFst _init_MutableFst(MutableFstClass_ptr tfst):
  *   if tfst.Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
@@ -29018,19 +30028,19 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__init_Mutable
  */
   }
 
-  /* "pywrapfst.pyx":2738
+  /* "pywrapfst.pyx":2804
  *   if tfst.Properties(fst.kError, True) == fst.kError:
  *     raise FstOpError("Operation failed")
  *   cdef _MutableFst ofst = _MutableFst.__new__(_MutableFst)             # <<<<<<<<<<<<<<
  *   ofst._fst.reset(tfst)
  *   # Makes a copy of it as the derived type! Cool.
  */
-  __pyx_t_2 = ((PyObject *)__pyx_tp_new_9pywrapfst__MutableFst(((PyTypeObject *)__pyx_ptype_9pywrapfst__MutableFst), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2738, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_tp_new_9pywrapfst__MutableFst(((PyTypeObject *)__pyx_ptype_9pywrapfst__MutableFst), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2804, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_2));
   __pyx_v_ofst = ((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_t_2);
   __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2739
+  /* "pywrapfst.pyx":2805
  *     raise FstOpError("Operation failed")
  *   cdef _MutableFst ofst = _MutableFst.__new__(_MutableFst)
  *   ofst._fst.reset(tfst)             # <<<<<<<<<<<<<<
@@ -29039,11 +30049,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__init_Mutable
  */
   if (unlikely(((PyObject *)__pyx_v_ofst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2739, __pyx_L1_error)
+    __PYX_ERR(0, 2805, __pyx_L1_error)
   }
   __pyx_v_ofst->__pyx_base._fst.reset(__pyx_v_tfst);
 
-  /* "pywrapfst.pyx":2741
+  /* "pywrapfst.pyx":2807
  *   ofst._fst.reset(tfst)
  *   # Makes a copy of it as the derived type! Cool.
  *   ofst._mfst = static_pointer_cast[fst.MutableFstClass, fst.FstClass](ofst._fst)             # <<<<<<<<<<<<<<
@@ -29052,15 +30062,15 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__init_Mutable
  */
   if (unlikely(((PyObject *)__pyx_v_ofst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2741, __pyx_L1_error)
+    __PYX_ERR(0, 2807, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ofst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2741, __pyx_L1_error)
+    __PYX_ERR(0, 2807, __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":2742
+  /* "pywrapfst.pyx":2808
  *   # Makes a copy of it as the derived type! Cool.
  *   ofst._mfst = static_pointer_cast[fst.MutableFstClass, fst.FstClass](ofst._fst)
  *   return ofst             # <<<<<<<<<<<<<<
@@ -29072,7 +30082,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__init_Mutable
   __pyx_r = __pyx_v_ofst;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2735
+  /* "pywrapfst.pyx":2801
  * 
  * 
  * cdef _MutableFst _init_MutableFst(MutableFstClass_ptr tfst):             # <<<<<<<<<<<<<<
@@ -29094,7 +30104,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__init_Mutable
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2745
+/* "pywrapfst.pyx":2811
  * 
  * 
  * cdef _Fst _init_XFst(FstClass_ptr tfst):             # <<<<<<<<<<<<<<
@@ -29109,7 +30119,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":2746
+  /* "pywrapfst.pyx":2812
  * 
  * cdef _Fst _init_XFst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kMutable, True) == fst.kMutable:             # <<<<<<<<<<<<<<
@@ -29119,7 +30129,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_XFst(__pyx_t_9
   __pyx_t_1 = ((__pyx_v_tfst->Properties(fst::kMutable, 1) == fst::kMutable) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2747
+    /* "pywrapfst.pyx":2813
  * cdef _Fst _init_XFst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kMutable, True) == fst.kMutable:
  *     return _init_MutableFst(static_cast[MutableFstClass_ptr](tfst))             # <<<<<<<<<<<<<<
@@ -29127,13 +30137,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, 2747, __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, 2813, __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":2746
+    /* "pywrapfst.pyx":2812
  * 
  * cdef _Fst _init_XFst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kMutable, True) == fst.kMutable:             # <<<<<<<<<<<<<<
@@ -29142,7 +30152,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_XFst(__pyx_t_9
  */
   }
 
-  /* "pywrapfst.pyx":2749
+  /* "pywrapfst.pyx":2815
  *     return _init_MutableFst(static_cast[MutableFstClass_ptr](tfst))
  *   else:
  *     return _init_Fst(tfst)             # <<<<<<<<<<<<<<
@@ -29151,14 +30161,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, 2749, __pyx_L1_error)
+    __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_Fst(__pyx_v_tfst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2815, __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":2745
+  /* "pywrapfst.pyx":2811
  * 
  * 
  * cdef _Fst _init_XFst(FstClass_ptr tfst):             # <<<<<<<<<<<<<<
@@ -29177,7 +30187,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_XFst(__pyx_t_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2752
+/* "pywrapfst.pyx":2818
  * 
  * 
  * cdef _MutableFst _create_Fst(arc_type=b"standard"):             # <<<<<<<<<<<<<<
@@ -29204,17 +30214,17 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__create_Fst(s
     }
   }
 
-  /* "pywrapfst.pyx":2754
+  /* "pywrapfst.pyx":2820
  * cdef _MutableFst _create_Fst(arc_type=b"standard"):
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(tostring(arc_type)))             # <<<<<<<<<<<<<<
  *   if tfst.get() == NULL:
  *     raise FstOpError("Unknown arc type: {!r}".format(arc_type))
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2754, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2820, __pyx_L1_error)
   __pyx_v_tfst.reset(new fst::script::VectorFstClass(__pyx_t_1));
 
-  /* "pywrapfst.pyx":2755
+  /* "pywrapfst.pyx":2821
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(tostring(arc_type)))
  *   if tfst.get() == NULL:             # <<<<<<<<<<<<<<
@@ -29224,16 +30234,16 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__create_Fst(s
   __pyx_t_2 = ((__pyx_v_tfst.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":2756
+    /* "pywrapfst.pyx":2822
  *   tfst.reset(new fst.VectorFstClass(tostring(arc_type)))
  *   if tfst.get() == NULL:
  *     raise FstOpError("Unknown arc type: {!r}".format(arc_type))             # <<<<<<<<<<<<<<
  *   return _init_MutableFst(tfst.release())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2756, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2822, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Unknown_arc_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2756, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Unknown_arc_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2822, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __pyx_t_7 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
@@ -29247,7 +30257,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__create_Fst(s
     }
     __pyx_t_5 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_v_arc_type) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_arc_type);
     __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2756, __pyx_L1_error)
+    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2822, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __pyx_t_6 = NULL;
@@ -29263,14 +30273,14 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__create_Fst(s
     __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5);
     __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2756, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2822, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 2756, __pyx_L1_error)
+    __PYX_ERR(0, 2822, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2755
+    /* "pywrapfst.pyx":2821
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(tostring(arc_type)))
  *   if tfst.get() == NULL:             # <<<<<<<<<<<<<<
@@ -29279,7 +30289,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__create_Fst(s
  */
   }
 
-  /* "pywrapfst.pyx":2757
+  /* "pywrapfst.pyx":2823
  *   if tfst.get() == NULL:
  *     raise FstOpError("Unknown arc type: {!r}".format(arc_type))
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -29287,13 +30297,13 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__create_Fst(s
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2757, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2823, __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":2752
+  /* "pywrapfst.pyx":2818
  * 
  * 
  * cdef _MutableFst _create_Fst(arc_type=b"standard"):             # <<<<<<<<<<<<<<
@@ -29316,16 +30326,16 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__create_Fst(s
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2760
+/* "pywrapfst.pyx":2826
  * 
  * 
- * cpdef _Fst _read(filename):             # <<<<<<<<<<<<<<
+ * cpdef _Fst _read(source):             # <<<<<<<<<<<<<<
  *   cdef unique_ptr[fst.FstClass] tfst
- *   tfst.reset(fst.FstClass.Read(tostring(filename)))
+ *   tfst.reset(fst.FstClass.Read(tostring(source)))
  */
 
-static PyObject *__pyx_pw_9pywrapfst_15_read(PyObject *__pyx_self, PyObject *__pyx_v_filename); /*proto*/
-static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read(PyObject *__pyx_v_filename, CYTHON_UNUSED int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_17_read(PyObject *__pyx_self, PyObject *__pyx_v_source); /*proto*/
+static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read(PyObject *__pyx_v_source, CYTHON_UNUSED int __pyx_skip_dispatch) {
   std::unique_ptr<fst::script::FstClass>  __pyx_v_tfst;
   struct __pyx_obj_9pywrapfst__Fst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
@@ -29338,36 +30348,36 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read(PyObject *__py
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("_read", 0);
 
-  /* "pywrapfst.pyx":2762
- * cpdef _Fst _read(filename):
+  /* "pywrapfst.pyx":2828
+ * cpdef _Fst _read(source):
  *   cdef unique_ptr[fst.FstClass] tfst
- *   tfst.reset(fst.FstClass.Read(tostring(filename)))             # <<<<<<<<<<<<<<
+ *   tfst.reset(fst.FstClass.Read(tostring(source)))             # <<<<<<<<<<<<<<
  *   if tfst.get() == NULL:
- *     raise FstIOError("Read failed: {!r}".format(filename))
+ *     raise FstIOError("Read failed: {!r}".format(source))
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2762, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2828, __pyx_L1_error)
   __pyx_v_tfst.reset(fst::script::FstClass::Read(__pyx_t_1));
 
-  /* "pywrapfst.pyx":2763
+  /* "pywrapfst.pyx":2829
  *   cdef unique_ptr[fst.FstClass] tfst
- *   tfst.reset(fst.FstClass.Read(tostring(filename)))
+ *   tfst.reset(fst.FstClass.Read(tostring(source)))
  *   if tfst.get() == NULL:             # <<<<<<<<<<<<<<
- *     raise FstIOError("Read failed: {!r}".format(filename))
+ *     raise FstIOError("Read failed: {!r}".format(source))
  *   return _init_XFst(tfst.release())
  */
   __pyx_t_2 = ((__pyx_v_tfst.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":2764
- *   tfst.reset(fst.FstClass.Read(tostring(filename)))
+    /* "pywrapfst.pyx":2830
+ *   tfst.reset(fst.FstClass.Read(tostring(source)))
  *   if tfst.get() == NULL:
- *     raise FstIOError("Read failed: {!r}".format(filename))             # <<<<<<<<<<<<<<
+ *     raise FstIOError("Read failed: {!r}".format(source))             # <<<<<<<<<<<<<<
  *   return _init_XFst(tfst.release())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2764, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2830, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2764, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2830, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __pyx_t_7 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
@@ -29379,9 +30389,9 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read(PyObject *__py
         __Pyx_DECREF_SET(__pyx_t_6, function);
       }
     }
-    __pyx_t_5 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_v_filename) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_filename);
+    __pyx_t_5 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_source);
     __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2764, __pyx_L1_error)
+    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2830, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __pyx_t_6 = NULL;
@@ -29397,42 +30407,42 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read(PyObject *__py
     __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5);
     __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2764, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2830, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 2764, __pyx_L1_error)
+    __PYX_ERR(0, 2830, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2763
+    /* "pywrapfst.pyx":2829
  *   cdef unique_ptr[fst.FstClass] tfst
- *   tfst.reset(fst.FstClass.Read(tostring(filename)))
+ *   tfst.reset(fst.FstClass.Read(tostring(source)))
  *   if tfst.get() == NULL:             # <<<<<<<<<<<<<<
- *     raise FstIOError("Read failed: {!r}".format(filename))
+ *     raise FstIOError("Read failed: {!r}".format(source))
  *   return _init_XFst(tfst.release())
  */
   }
 
-  /* "pywrapfst.pyx":2765
+  /* "pywrapfst.pyx":2831
  *   if tfst.get() == NULL:
- *     raise FstIOError("Read failed: {!r}".format(filename))
+ *     raise FstIOError("Read failed: {!r}".format(source))
  *   return _init_XFst(tfst.release())             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2765, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2831, __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":2760
+  /* "pywrapfst.pyx":2826
  * 
  * 
- * cpdef _Fst _read(filename):             # <<<<<<<<<<<<<<
+ * cpdef _Fst _read(source):             # <<<<<<<<<<<<<<
  *   cdef unique_ptr[fst.FstClass] tfst
- *   tfst.reset(fst.FstClass.Read(tostring(filename)))
+ *   tfst.reset(fst.FstClass.Read(tostring(source)))
  */
 
   /* function exit code */
@@ -29451,25 +30461,25 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read(PyObject *__py
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_15_read(PyObject *__pyx_self, PyObject *__pyx_v_filename); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_15_read(PyObject *__pyx_self, PyObject *__pyx_v_filename) {
+static PyObject *__pyx_pw_9pywrapfst_17_read(PyObject *__pyx_self, PyObject *__pyx_v_source); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_17_read(PyObject *__pyx_self, PyObject *__pyx_v_source) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_read (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_14_read(__pyx_self, ((PyObject *)__pyx_v_filename));
+  __pyx_r = __pyx_pf_9pywrapfst_16_read(__pyx_self, ((PyObject *)__pyx_v_source));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_14_read(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_filename) {
+static PyObject *__pyx_pf_9pywrapfst_16_read(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_source) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("_read", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read(__pyx_v_filename, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2760, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read(__pyx_v_source, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2826, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -29486,7 +30496,7 @@ static PyObject *__pyx_pf_9pywrapfst_14_read(CYTHON_UNUSED PyObject *__pyx_self,
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2768
+/* "pywrapfst.pyx":2834
  * 
  * 
  * cpdef _Fst _read_Fst_from_string(state):             # <<<<<<<<<<<<<<
@@ -29494,7 +30504,7 @@ static PyObject *__pyx_pf_9pywrapfst_14_read(CYTHON_UNUSED PyObject *__pyx_self,
  *   sstrm << tostring(state)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_17_read_Fst_from_string(PyObject *__pyx_self, PyObject *__pyx_v_state); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_19_read_Fst_from_string(PyObject *__pyx_self, PyObject *__pyx_v_state); /*proto*/
 static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst_from_string(PyObject *__pyx_v_state, CYTHON_UNUSED int __pyx_skip_dispatch) {
   std::stringstream __pyx_v_sstrm;
   std::unique_ptr<fst::script::FstClass>  __pyx_v_tfst;
@@ -29507,17 +30517,17 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst_from_strin
   PyObject *__pyx_t_5 = NULL;
   __Pyx_RefNannySetupContext("_read_Fst_from_string", 0);
 
-  /* "pywrapfst.pyx":2770
+  /* "pywrapfst.pyx":2836
  * cpdef _Fst _read_Fst_from_string(state):
  *   cdef stringstream sstrm
  *   sstrm << tostring(state)             # <<<<<<<<<<<<<<
  *   cdef unique_ptr[fst.FstClass] tfst
  *   tfst.reset(fst.FstClass.ReadStream(sstrm, b"<pywrapfst>"))
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2770, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2836, __pyx_L1_error)
   (void)((__pyx_v_sstrm << __pyx_t_1));
 
-  /* "pywrapfst.pyx":2772
+  /* "pywrapfst.pyx":2838
  *   sstrm << tostring(state)
  *   cdef unique_ptr[fst.FstClass] tfst
  *   tfst.reset(fst.FstClass.ReadStream(sstrm, b"<pywrapfst>"))             # <<<<<<<<<<<<<<
@@ -29526,7 +30536,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst_from_strin
  */
   __pyx_v_tfst.reset(fst::script::FstClass::Read(__pyx_v_sstrm, __pyx_k_pywrapfst));
 
-  /* "pywrapfst.pyx":2773
+  /* "pywrapfst.pyx":2839
  *   cdef unique_ptr[fst.FstClass] tfst
  *   tfst.reset(fst.FstClass.ReadStream(sstrm, b"<pywrapfst>"))
  *   if tfst.get() == NULL:             # <<<<<<<<<<<<<<
@@ -29536,14 +30546,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst_from_strin
   __pyx_t_2 = ((__pyx_v_tfst.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":2774
+    /* "pywrapfst.pyx":2840
  *   tfst.reset(fst.FstClass.ReadStream(sstrm, b"<pywrapfst>"))
  *   if tfst.get() == NULL:
  *     raise FstIOError("Read failed")             # <<<<<<<<<<<<<<
  *   return _init_XFst(tfst.release())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2774, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2840, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __pyx_t_5 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
@@ -29557,14 +30567,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst_from_strin
     }
     __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_kp_u_Read_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_kp_u_Read_failed);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2774, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2840, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 2774, __pyx_L1_error)
+    __PYX_ERR(0, 2840, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2773
+    /* "pywrapfst.pyx":2839
  *   cdef unique_ptr[fst.FstClass] tfst
  *   tfst.reset(fst.FstClass.ReadStream(sstrm, b"<pywrapfst>"))
  *   if tfst.get() == NULL:             # <<<<<<<<<<<<<<
@@ -29573,7 +30583,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst_from_strin
  */
   }
 
-  /* "pywrapfst.pyx":2775
+  /* "pywrapfst.pyx":2841
  *   if tfst.get() == NULL:
  *     raise FstIOError("Read failed")
  *   return _init_XFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -29581,13 +30591,13 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst_from_strin
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2775, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2841, __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":2768
+  /* "pywrapfst.pyx":2834
  * 
  * 
  * cpdef _Fst _read_Fst_from_string(state):             # <<<<<<<<<<<<<<
@@ -29609,25 +30619,25 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst_from_strin
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_17_read_Fst_from_string(PyObject *__pyx_self, PyObject *__pyx_v_state); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_17_read_Fst_from_string(PyObject *__pyx_self, PyObject *__pyx_v_state) {
+static PyObject *__pyx_pw_9pywrapfst_19_read_Fst_from_string(PyObject *__pyx_self, PyObject *__pyx_v_state); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_19_read_Fst_from_string(PyObject *__pyx_self, PyObject *__pyx_v_state) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_read_Fst_from_string (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_16_read_Fst_from_string(__pyx_self, ((PyObject *)__pyx_v_state));
+  __pyx_r = __pyx_pf_9pywrapfst_18_read_Fst_from_string(__pyx_self, ((PyObject *)__pyx_v_state));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_16_read_Fst_from_string(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_state) {
+static PyObject *__pyx_pf_9pywrapfst_18_read_Fst_from_string(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_state) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("_read_Fst_from_string", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_Fst_from_string(__pyx_v_state, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2768, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_Fst_from_string(__pyx_v_state, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2834, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -29644,7 +30654,7 @@ static PyObject *__pyx_pf_9pywrapfst_16_read_Fst_from_string(CYTHON_UNUSED PyObj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2795
+/* "pywrapfst.pyx":2861
  *    """
  * 
  *    def __new__(cls, arc_type=b"standard"):             # <<<<<<<<<<<<<<
@@ -29689,7 +30699,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, 2795, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__new__") < 0)) __PYX_ERR(0, 2861, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -29705,7 +30715,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, 2795, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__new__", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2861, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.Fst.__new__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -29725,7 +30735,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":2796
+  /* "pywrapfst.pyx":2862
  * 
  *    def __new__(cls, arc_type=b"standard"):
  *     return _create_Fst(arc_type)             # <<<<<<<<<<<<<<
@@ -29735,13 +30745,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, 2796, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__create_Fst(&__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2862, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2795
+  /* "pywrapfst.pyx":2861
  *    """
  * 
  *    def __new__(cls, arc_type=b"standard"):             # <<<<<<<<<<<<<<
@@ -29760,55 +30770,55 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst___new__(CYTHON_UNUSED PyObject *__pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2799
+/* "pywrapfst.pyx":2865
  * 
  *    @staticmethod
- *    def read(filename):             # <<<<<<<<<<<<<<
+ *    def read(source):             # <<<<<<<<<<<<<<
  *      """
- *      read(filename):
+ *      read(source)
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_3Fst_3read(PyObject *__pyx_self, PyObject *__pyx_v_filename); /*proto*/
-static char __pyx_doc_9pywrapfst_3Fst_2read[] = "\n     read(filename):\n\n     Reads an FST from a file.\n\n     Args:\n       filename: The string location of the input file.\n\n     Returns:\n       An FST object.\n\n     Raises:\n       FstIOError: Read failed.\n     ";
+static PyObject *__pyx_pw_9pywrapfst_3Fst_3read(PyObject *__pyx_self, PyObject *__pyx_v_source); /*proto*/
+static char __pyx_doc_9pywrapfst_3Fst_2read[] = "\n     read(source)\n\n     Reads an FST from a file.\n\n     Args:\n       source: The string location of the input file.\n\n     Returns:\n       An FST object.\n\n     Raises:\n       FstIOError: Read failed.\n     ";
 static PyMethodDef __pyx_mdef_9pywrapfst_3Fst_3read = {"read", (PyCFunction)__pyx_pw_9pywrapfst_3Fst_3read, METH_O, __pyx_doc_9pywrapfst_3Fst_2read};
-static PyObject *__pyx_pw_9pywrapfst_3Fst_3read(PyObject *__pyx_self, PyObject *__pyx_v_filename) {
+static PyObject *__pyx_pw_9pywrapfst_3Fst_3read(PyObject *__pyx_self, PyObject *__pyx_v_source) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("read (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_3Fst_2read(__pyx_self, ((PyObject *)__pyx_v_filename));
+  __pyx_r = __pyx_pf_9pywrapfst_3Fst_2read(__pyx_self, ((PyObject *)__pyx_v_source));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_3Fst_2read(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_filename) {
+static PyObject *__pyx_pf_9pywrapfst_3Fst_2read(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_source) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("read", 0);
 
-  /* "pywrapfst.pyx":2814
+  /* "pywrapfst.pyx":2880
  *        FstIOError: Read failed.
  *      """
- *      return _read(filename)             # <<<<<<<<<<<<<<
+ *      return _read(source)             # <<<<<<<<<<<<<<
  * 
  *    @staticmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read(__pyx_v_filename, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2814, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read(__pyx_v_source, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2880, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2799
+  /* "pywrapfst.pyx":2865
  * 
  *    @staticmethod
- *    def read(filename):             # <<<<<<<<<<<<<<
+ *    def read(source):             # <<<<<<<<<<<<<<
  *      """
- *      read(filename):
+ *      read(source)
  */
 
   /* function exit code */
@@ -29822,17 +30832,17 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_2read(CYTHON_UNUSED PyObject *__pyx_se
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2817
+/* "pywrapfst.pyx":2883
  * 
  *    @staticmethod
  *    def read_from_string(state):             # <<<<<<<<<<<<<<
  *      """
- *      read_from_string(string, fst_type=None)
+ *      read_from_string(state)
  */
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_3Fst_5read_from_string(PyObject *__pyx_self, PyObject *__pyx_v_state); /*proto*/
-static char __pyx_doc_9pywrapfst_3Fst_4read_from_string[] = "\n     read_from_string(string, fst_type=None)\n\n     Reads an FST from a serialized string.\n\n     Args:\n       state: A string containing the serialized FST.\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 char __pyx_doc_9pywrapfst_3Fst_4read_from_string[] = "\n     read_from_string(state)\n\n     Reads an FST from a serialized string.\n\n     Args:\n       state: A string containing the serialized FST.\n\n     Returns:\n       An FST object.\n\n     Raises:\n       FstIOError: Read failed.\n     ";
 static PyMethodDef __pyx_mdef_9pywrapfst_3Fst_5read_from_string = {"read_from_string", (PyCFunction)__pyx_pw_9pywrapfst_3Fst_5read_from_string, METH_O, __pyx_doc_9pywrapfst_3Fst_4read_from_string};
 static PyObject *__pyx_pw_9pywrapfst_3Fst_5read_from_string(PyObject *__pyx_self, PyObject *__pyx_v_state) {
   PyObject *__pyx_r = 0;
@@ -29851,26 +30861,26 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_4read_from_string(CYTHON_UNUSED PyObje
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("read_from_string", 0);
 
-  /* "pywrapfst.pyx":2835
- *      See also: `write_to_string`.
+  /* "pywrapfst.pyx":2898
+ *        FstIOError: Read failed.
  *      """
  *      return _read_Fst_from_string(state)             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_Fst_from_string(__pyx_v_state, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2835, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_Fst_from_string(__pyx_v_state, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2898, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2817
+  /* "pywrapfst.pyx":2883
  * 
  *    @staticmethod
  *    def read_from_string(state):             # <<<<<<<<<<<<<<
  *      """
- *      read_from_string(string, fst_type=None)
+ *      read_from_string(state)
  */
 
   /* function exit code */
@@ -29884,7 +30894,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_4read_from_string(CYTHON_UNUSED PyObje
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2948
+/* "pywrapfst.pyx":3011
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -29914,7 +30924,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc___repr__(struct __pyx_obj_9pywrapfst_A
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":2949
+  /* "pywrapfst.pyx":3012
  * 
  *   def __repr__(self):
  *     return "<Arc at 0x{:x}>".format(id(self))             # <<<<<<<<<<<<<<
@@ -29922,9 +30932,9 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc___repr__(struct __pyx_obj_9pywrapfst_A
  *   def __init__(self, int64 ilabel, int64 olabel, weight, int64 nextstate):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Arc_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2949, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Arc_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3012, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2949, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3012, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_t_4 = NULL;
   if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
@@ -29939,14 +30949,14 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc___repr__(struct __pyx_obj_9pywrapfst_A
   __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2949, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3012, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2948
+  /* "pywrapfst.pyx":3011
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -29968,7 +30978,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc___repr__(struct __pyx_obj_9pywrapfst_A
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2951
+/* "pywrapfst.pyx":3014
  *     return "<Arc at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, int64 ilabel, int64 olabel, weight, int64 nextstate):             # <<<<<<<<<<<<<<
@@ -30013,23 +31023,23 @@ static int __pyx_pw_9pywrapfst_3Arc_3__init__(PyObject *__pyx_v_self, PyObject *
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_olabel)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 1); __PYX_ERR(0, 2951, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 1); __PYX_ERR(0, 3014, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
         if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_weight)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 2); __PYX_ERR(0, 2951, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 2); __PYX_ERR(0, 3014, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  3:
         if (likely((values[3] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_nextstate)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 3); __PYX_ERR(0, 2951, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 3); __PYX_ERR(0, 3014, __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, 2951, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 3014, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
       goto __pyx_L5_argtuple_error;
@@ -30039,14 +31049,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, 2951, __pyx_L3_error)
-    __pyx_v_olabel = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_olabel == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2951, __pyx_L3_error)
+    __pyx_v_ilabel = __Pyx_PyInt_As_int64_t(values[0]); if (unlikely((__pyx_v_ilabel == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3014, __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, 3014, __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, 2951, __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, 3014, __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, 2951, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3014, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.Arc.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -30066,17 +31076,17 @@ static int __pyx_pf_9pywrapfst_3Arc_2__init__(struct __pyx_obj_9pywrapfst_Arc *_
   fst::script::WeightClass __pyx_t_1;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":2952
+  /* "pywrapfst.pyx":3015
  * 
  *   def __init__(self, int64 ilabel, int64 olabel, weight, int64 nextstate):
  *     cdef fst.WeightClass wc = _get_WeightClass_or_One(b"tropical", weight)             # <<<<<<<<<<<<<<
  *     self._arc.reset(new fst.ArcClass(ilabel, olabel, wc, nextstate))
  * 
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_One(__pyx_k_tropical, __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2952, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_One(__pyx_k_tropical, __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3015, __pyx_L1_error)
   __pyx_v_wc = __pyx_t_1;
 
-  /* "pywrapfst.pyx":2953
+  /* "pywrapfst.pyx":3016
  *   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))             # <<<<<<<<<<<<<<
@@ -30085,11 +31095,11 @@ static int __pyx_pf_9pywrapfst_3Arc_2__init__(struct __pyx_obj_9pywrapfst_Arc *_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 2953, __pyx_L1_error)
+    __PYX_ERR(0, 3016, __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":2951
+  /* "pywrapfst.pyx":3014
  *     return "<Arc at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, int64 ilabel, int64 olabel, weight, int64 nextstate):             # <<<<<<<<<<<<<<
@@ -30108,7 +31118,7 @@ static int __pyx_pf_9pywrapfst_3Arc_2__init__(struct __pyx_obj_9pywrapfst_Arc *_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2955
+/* "pywrapfst.pyx":3018
  *     self._arc.reset(new fst.ArcClass(ilabel, olabel, wc, nextstate))
  * 
  *   cpdef Arc copy(self):             # <<<<<<<<<<<<<<
@@ -30135,7 +31145,7 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst_3Arc_copy(struct __py
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_copy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2955, __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, 3018, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Arc_5copy)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -30152,10 +31162,10 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst_3Arc_copy(struct __py
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2955, __pyx_L1_error)
+        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;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Arc))))) __PYX_ERR(0, 2955, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Arc))))) __PYX_ERR(0, 3018, __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;
@@ -30174,7 +31184,7 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst_3Arc_copy(struct __py
     #endif
   }
 
-  /* "pywrapfst.pyx":2956
+  /* "pywrapfst.pyx":3019
  * 
  *   cpdef Arc copy(self):
  *     return Arc(self.ilabel, self.olabel, self.weight, self.nextstate)             # <<<<<<<<<<<<<<
@@ -30182,15 +31192,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, 2956, __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, 3019, __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, 2956, __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, 3019, __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, 2956, __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, 3019, __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, 2956, __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, 3019, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2956, __pyx_L1_error)
+  __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3019, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1);
@@ -30204,14 +31214,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, 2956, __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, 3019, __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":2955
+  /* "pywrapfst.pyx":3018
  *     self._arc.reset(new fst.ArcClass(ilabel, olabel, wc, nextstate))
  * 
  *   cpdef Arc copy(self):             # <<<<<<<<<<<<<<
@@ -30253,7 +31263,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, 2955, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Arc_copy(__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;
@@ -30270,7 +31280,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_4copy(struct __pyx_obj_9pywrapfst_Arc
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2960
+/* "pywrapfst.pyx":3023
  *   property ilabel:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -30297,7 +31307,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6ilabel___get__(struct __pyx_obj_9pywr
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "pywrapfst.pyx":2961
+  /* "pywrapfst.pyx":3024
  * 
  *     def __get__(self):
  *       return deref(self._arc).ilabel             # <<<<<<<<<<<<<<
@@ -30307,15 +31317,15 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6ilabel___get__(struct __pyx_obj_9pywr
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 2961, __pyx_L1_error)
+    __PYX_ERR(0, 3024, __pyx_L1_error)
   }
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t((*__pyx_v_self->_arc).ilabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2961, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t((*__pyx_v_self->_arc).ilabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3024, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2960
+  /* "pywrapfst.pyx":3023
  *   property ilabel:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -30334,7 +31344,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6ilabel___get__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2963
+/* "pywrapfst.pyx":3026
  *       return deref(self._arc).ilabel
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -30350,7 +31360,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, 2963, __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, 3026, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -30370,7 +31380,7 @@ static int __pyx_pf_9pywrapfst_3Arc_6ilabel_2__set__(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__set__", 0);
 
-  /* "pywrapfst.pyx":2964
+  /* "pywrapfst.pyx":3027
  * 
  *     def __set__(self, int64 value):
  *       deref(self._arc).ilabel = value             # <<<<<<<<<<<<<<
@@ -30379,11 +31389,11 @@ static int __pyx_pf_9pywrapfst_3Arc_6ilabel_2__set__(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 2964, __pyx_L1_error)
+    __PYX_ERR(0, 3027, __pyx_L1_error)
   }
   (*__pyx_v_self->_arc).ilabel = __pyx_v_value;
 
-  /* "pywrapfst.pyx":2963
+  /* "pywrapfst.pyx":3026
  *       return deref(self._arc).ilabel
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -30402,7 +31412,7 @@ static int __pyx_pf_9pywrapfst_3Arc_6ilabel_2__set__(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2968
+/* "pywrapfst.pyx":3031
  *   property olabel:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -30429,7 +31439,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6olabel___get__(struct __pyx_obj_9pywr
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "pywrapfst.pyx":2969
+  /* "pywrapfst.pyx":3032
  * 
  *     def __get__(self):
  *       return deref(self._arc).olabel             # <<<<<<<<<<<<<<
@@ -30439,15 +31449,15 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6olabel___get__(struct __pyx_obj_9pywr
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 2969, __pyx_L1_error)
+    __PYX_ERR(0, 3032, __pyx_L1_error)
   }
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t((*__pyx_v_self->_arc).olabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2969, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t((*__pyx_v_self->_arc).olabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3032, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2968
+  /* "pywrapfst.pyx":3031
  *   property olabel:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -30466,7 +31476,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6olabel___get__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2971
+/* "pywrapfst.pyx":3034
  *       return deref(self._arc).olabel
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -30482,7 +31492,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, 2971, __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, 3034, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -30502,7 +31512,7 @@ static int __pyx_pf_9pywrapfst_3Arc_6olabel_2__set__(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__set__", 0);
 
-  /* "pywrapfst.pyx":2972
+  /* "pywrapfst.pyx":3035
  * 
  *     def __set__(self, int64 value):
  *       deref(self._arc).olabel = value             # <<<<<<<<<<<<<<
@@ -30511,11 +31521,11 @@ static int __pyx_pf_9pywrapfst_3Arc_6olabel_2__set__(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 2972, __pyx_L1_error)
+    __PYX_ERR(0, 3035, __pyx_L1_error)
   }
   (*__pyx_v_self->_arc).olabel = __pyx_v_value;
 
-  /* "pywrapfst.pyx":2971
+  /* "pywrapfst.pyx":3034
  *       return deref(self._arc).olabel
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -30534,7 +31544,7 @@ static int __pyx_pf_9pywrapfst_3Arc_6olabel_2__set__(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2976
+/* "pywrapfst.pyx":3039
  *   property weight:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -30562,19 +31572,19 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6weight___get__(struct __pyx_obj_9pywr
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "pywrapfst.pyx":2977
+  /* "pywrapfst.pyx":3040
  * 
  *     def __get__(self):
  *       cdef Weight weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
  *       weight._weight.reset(new fst.WeightClass(deref(self._arc).weight))
  *       return weight
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2977, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3040, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v_weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2978
+  /* "pywrapfst.pyx":3041
  *     def __get__(self):
  *       cdef Weight weight = Weight.__new__(Weight)
  *       weight._weight.reset(new fst.WeightClass(deref(self._arc).weight))             # <<<<<<<<<<<<<<
@@ -30583,15 +31593,15 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6weight___get__(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 2978, __pyx_L1_error)
+    __PYX_ERR(0, 3041, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 2978, __pyx_L1_error)
+    __PYX_ERR(0, 3041, __pyx_L1_error)
   }
   __pyx_v_weight->_weight.reset(new fst::script::WeightClass((*__pyx_v_self->_arc).weight));
 
-  /* "pywrapfst.pyx":2979
+  /* "pywrapfst.pyx":3042
  *       cdef Weight weight = Weight.__new__(Weight)
  *       weight._weight.reset(new fst.WeightClass(deref(self._arc).weight))
  *       return weight             # <<<<<<<<<<<<<<
@@ -30603,7 +31613,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6weight___get__(struct __pyx_obj_9pywr
   __pyx_r = ((PyObject *)__pyx_v_weight);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2976
+  /* "pywrapfst.pyx":3039
  *   property weight:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -30623,7 +31633,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6weight___get__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2981
+/* "pywrapfst.pyx":3044
  *       return weight
  * 
  *     def __set__(self, weight):             # <<<<<<<<<<<<<<
@@ -30650,21 +31660,21 @@ static int __pyx_pf_9pywrapfst_3Arc_6weight_2__set__(struct __pyx_obj_9pywrapfst
   fst::script::WeightClass __pyx_t_1;
   __Pyx_RefNannySetupContext("__set__", 0);
 
-  /* "pywrapfst.pyx":2982
+  /* "pywrapfst.pyx":3045
  * 
  *     def __set__(self, weight):
  *       deref(self._arc).weight = _get_WeightClass_or_One(b"tropical", weight)             # <<<<<<<<<<<<<<
  * 
  *   property nextstate:
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_One(__pyx_k_tropical, __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2982, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_One(__pyx_k_tropical, __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3045, __pyx_L1_error)
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 2982, __pyx_L1_error)
+    __PYX_ERR(0, 3045, __pyx_L1_error)
   }
   (*__pyx_v_self->_arc).weight = __pyx_t_1;
 
-  /* "pywrapfst.pyx":2981
+  /* "pywrapfst.pyx":3044
  *       return weight
  * 
  *     def __set__(self, weight):             # <<<<<<<<<<<<<<
@@ -30683,7 +31693,7 @@ static int __pyx_pf_9pywrapfst_3Arc_6weight_2__set__(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2986
+/* "pywrapfst.pyx":3049
  *   property nextstate:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -30710,7 +31720,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_9nextstate___get__(struct __pyx_obj_9p
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "pywrapfst.pyx":2987
+  /* "pywrapfst.pyx":3050
  * 
  *     def __get__(self):
  *       return deref(self._arc).nextstate             # <<<<<<<<<<<<<<
@@ -30720,15 +31730,15 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_9nextstate___get__(struct __pyx_obj_9p
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 2987, __pyx_L1_error)
+    __PYX_ERR(0, 3050, __pyx_L1_error)
   }
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t((*__pyx_v_self->_arc).nextstate); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2987, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t((*__pyx_v_self->_arc).nextstate); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3050, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2986
+  /* "pywrapfst.pyx":3049
  *   property nextstate:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -30747,7 +31757,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_9nextstate___get__(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2989
+/* "pywrapfst.pyx":3052
  *       return deref(self._arc).nextstate
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -30763,7 +31773,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, 2989, __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, 3052, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -30783,7 +31793,7 @@ static int __pyx_pf_9pywrapfst_3Arc_9nextstate_2__set__(struct __pyx_obj_9pywrap
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__set__", 0);
 
-  /* "pywrapfst.pyx":2990
+  /* "pywrapfst.pyx":3053
  * 
  *     def __set__(self, int64 value):
  *       deref(self._arc).nextstate = value             # <<<<<<<<<<<<<<
@@ -30792,11 +31802,11 @@ static int __pyx_pf_9pywrapfst_3Arc_9nextstate_2__set__(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 2990, __pyx_L1_error)
+    __PYX_ERR(0, 3053, __pyx_L1_error)
   }
   (*__pyx_v_self->_arc).nextstate = __pyx_v_value;
 
-  /* "pywrapfst.pyx":2989
+  /* "pywrapfst.pyx":3052
  *       return deref(self._arc).nextstate
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -30846,7 +31856,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6__reduce_cython__(CYTHON_UNUSED struc
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._arc cannot be converted to a Python object for pickling")
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__23, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__21, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -30899,7 +31909,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_8__setstate_cython__(CYTHON_UNUSED str
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._arc cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__24, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__22, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -30922,7 +31932,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_8__setstate_cython__(CYTHON_UNUSED str
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2993
+/* "pywrapfst.pyx":3056
  * 
  * 
  * cdef Arc _init_Arc(const fst.ArcClass &arc):             # <<<<<<<<<<<<<<
@@ -30940,19 +31950,19 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst__init_Arc(fst::script
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("_init_Arc", 0);
 
-  /* "pywrapfst.pyx":2994
+  /* "pywrapfst.pyx":3057
  * 
  * cdef Arc _init_Arc(const fst.ArcClass &arc):
  *   cdef Weight weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
  *   weight._weight.reset(new fst.WeightClass(arc.weight))
  *   return Arc(arc.ilabel, arc.olabel, weight, arc.nextstate)
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2994, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3057, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v_weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2995
+  /* "pywrapfst.pyx":3058
  * cdef Arc _init_Arc(const fst.ArcClass &arc):
  *   cdef Weight weight = Weight.__new__(Weight)
  *   weight._weight.reset(new fst.WeightClass(arc.weight))             # <<<<<<<<<<<<<<
@@ -30961,11 +31971,11 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst__init_Arc(fst::script
  */
   if (unlikely(((PyObject *)__pyx_v_weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 2995, __pyx_L1_error)
+    __PYX_ERR(0, 3058, __pyx_L1_error)
   }
   __pyx_v_weight->_weight.reset(new fst::script::WeightClass(__pyx_v_arc.weight));
 
-  /* "pywrapfst.pyx":2996
+  /* "pywrapfst.pyx":3059
  *   cdef Weight weight = Weight.__new__(Weight)
  *   weight._weight.reset(new fst.WeightClass(arc.weight))
  *   return Arc(arc.ilabel, arc.olabel, weight, arc.nextstate)             # <<<<<<<<<<<<<<
@@ -30973,13 +31983,13 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst__init_Arc(fst::script
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_v_arc.ilabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2996, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_v_arc.ilabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3059, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_v_arc.olabel); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2996, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_v_arc.olabel); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3059, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_arc.nextstate); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2996, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_arc.nextstate); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3059, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = PyTuple_New(4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2996, __pyx_L1_error)
+  __pyx_t_4 = PyTuple_New(4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3059, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
@@ -30993,14 +32003,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, 2996, __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, 3059, __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":2993
+  /* "pywrapfst.pyx":3056
  * 
  * 
  * cdef Arc _init_Arc(const fst.ArcClass &arc):             # <<<<<<<<<<<<<<
@@ -31023,7 +32033,7 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst__init_Arc(fst::script
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3007
+/* "pywrapfst.pyx":3070
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -31053,7 +32063,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator___repr__(struct __pyx_obj_9py
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":3008
+  /* "pywrapfst.pyx":3071
  * 
  *   def __repr__(self):
  *     return "<ArcIterator at 0x{:x}>".format(id(self))             # <<<<<<<<<<<<<<
@@ -31061,9 +32071,9 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator___repr__(struct __pyx_obj_9py
  *   def __init__(self, _Fst ifst, int64 state):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_ArcIterator_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3008, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_ArcIterator_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3071, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3008, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3071, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_t_4 = NULL;
   if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
@@ -31078,14 +32088,14 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator___repr__(struct __pyx_obj_9py
   __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3008, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3071, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3007
+  /* "pywrapfst.pyx":3070
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -31107,7 +32117,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator___repr__(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3010
+/* "pywrapfst.pyx":3073
  *     return "<ArcIterator at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, _Fst ifst, int64 state):             # <<<<<<<<<<<<<<
@@ -31146,11 +32156,11 @@ static int __pyx_pw_9pywrapfst_11ArcIterator_3__init__(PyObject *__pyx_v_self, P
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_state)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); __PYX_ERR(0, 3010, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); __PYX_ERR(0, 3073, __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, 3010, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 3073, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -31159,17 +32169,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, 3010, __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, 3073, __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, 3010, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3073, __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, 3010, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3073, __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 */
@@ -31191,7 +32201,7 @@ static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapf
   std::shared_ptr<fst::script::FstClass>  __pyx_t_5;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":3011
+  /* "pywrapfst.pyx":3074
  * 
  *   def __init__(self, _Fst ifst, int64 state):
  *     if not ifst._fst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -31200,19 +32210,19 @@ static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3011, __pyx_L1_error)
+    __PYX_ERR(0, 3074, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_ifst->_fst.get()->ValidStateId(__pyx_v_state) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":3012
+    /* "pywrapfst.pyx":3075
  *   def __init__(self, _Fst ifst, int64 state):
  *     if not ifst._fst.get().ValidStateId(state):
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._fst = ifst._fst
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3012, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3075, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -31226,14 +32236,14 @@ static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapf
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3012, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3075, __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, 3012, __pyx_L1_error)
+    __PYX_ERR(0, 3075, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3011
+    /* "pywrapfst.pyx":3074
  * 
  *   def __init__(self, _Fst ifst, int64 state):
  *     if not ifst._fst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -31242,7 +32252,7 @@ static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapf
  */
   }
 
-  /* "pywrapfst.pyx":3014
+  /* "pywrapfst.pyx":3077
  *       raise FstIndexError("State index out of range")
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._fst = ifst._fst             # <<<<<<<<<<<<<<
@@ -31251,16 +32261,16 @@ static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3014, __pyx_L1_error)
+    __PYX_ERR(0, 3077, __pyx_L1_error)
   }
   __pyx_t_5 = __pyx_v_ifst->_fst;
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3014, __pyx_L1_error)
+    __PYX_ERR(0, 3077, __pyx_L1_error)
   }
   __pyx_v_self->_fst = __pyx_t_5;
 
-  /* "pywrapfst.pyx":3015
+  /* "pywrapfst.pyx":3078
  *     # 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))             # <<<<<<<<<<<<<<
@@ -31269,15 +32279,15 @@ static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3015, __pyx_L1_error)
+    __PYX_ERR(0, 3078, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3015, __pyx_L1_error)
+    __PYX_ERR(0, 3078, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.reset(new fst::script::ArcIteratorClass((*__pyx_v_self->_fst), __pyx_v_state));
 
-  /* "pywrapfst.pyx":3010
+  /* "pywrapfst.pyx":3073
  *     return "<ArcIterator at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, _Fst ifst, int64 state):             # <<<<<<<<<<<<<<
@@ -31299,7 +32309,7 @@ static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapf
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3018
+/* "pywrapfst.pyx":3081
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -31325,7 +32335,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_4__iter__(struct __pyx_obj_9p
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__iter__", 0);
 
-  /* "pywrapfst.pyx":3019
+  /* "pywrapfst.pyx":3082
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):
  *     return self             # <<<<<<<<<<<<<<
@@ -31337,7 +32347,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_4__iter__(struct __pyx_obj_9p
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3018
+  /* "pywrapfst.pyx":3081
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -31352,7 +32362,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_4__iter__(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3022
+/* "pywrapfst.pyx":3085
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -31381,7 +32391,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("__next__", 0);
 
-  /* "pywrapfst.pyx":3023
+  /* "pywrapfst.pyx":3086
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -31390,12 +32400,12 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "done");
-    __PYX_ERR(0, 3023, __pyx_L1_error)
+    __PYX_ERR(0, 3086, __pyx_L1_error)
   }
   __pyx_t_1 = (((struct __pyx_vtabstruct_9pywrapfst_ArcIterator *)__pyx_v_self->__pyx_vtab)->done(__pyx_v_self, 0) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":3024
+    /* "pywrapfst.pyx":3087
  *   def __next__(self):
  *     if self.done():
  *       raise StopIteration             # <<<<<<<<<<<<<<
@@ -31403,9 +32413,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, 3024, __pyx_L1_error)
+    __PYX_ERR(0, 3087, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3023
+    /* "pywrapfst.pyx":3086
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -31414,7 +32424,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
  */
   }
 
-  /* "pywrapfst.pyx":3025
+  /* "pywrapfst.pyx":3088
  *     if self.done():
  *       raise StopIteration
  *     result = self.value()             # <<<<<<<<<<<<<<
@@ -31423,14 +32433,14 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "value");
-    __PYX_ERR(0, 3025, __pyx_L1_error)
+    __PYX_ERR(0, 3088, __pyx_L1_error)
   }
-  __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst_ArcIterator *)__pyx_v_self->__pyx_vtab)->value(__pyx_v_self, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3025, __pyx_L1_error)
+  __pyx_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, 3088, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_v_result = __pyx_t_2;
   __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3026
+  /* "pywrapfst.pyx":3089
  *       raise StopIteration
  *     result = self.value()
  *     self.next()             # <<<<<<<<<<<<<<
@@ -31439,11 +32449,11 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "next");
-    __PYX_ERR(0, 3026, __pyx_L1_error)
+    __PYX_ERR(0, 3089, __pyx_L1_error)
   }
   ((struct __pyx_vtabstruct_9pywrapfst_ArcIterator *)__pyx_v_self->__pyx_vtab)->next(__pyx_v_self, 0);
 
-  /* "pywrapfst.pyx":3027
+  /* "pywrapfst.pyx":3090
  *     result = self.value()
  *     self.next()
  *     return result             # <<<<<<<<<<<<<<
@@ -31455,7 +32465,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3022
+  /* "pywrapfst.pyx":3085
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -31475,7 +32485,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3029
+/* "pywrapfst.pyx":3092
  *     return result
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -31502,7 +32512,7 @@ static bool __pyx_f_9pywrapfst_11ArcIterator_done(struct __pyx_obj_9pywrapfst_Ar
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_done); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3029, __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, 3092, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_11ArcIterator_9done)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -31518,10 +32528,10 @@ static bool __pyx_f_9pywrapfst_11ArcIterator_done(struct __pyx_obj_9pywrapfst_Ar
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3029, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3092, __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, 3029, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3092, __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;
@@ -31540,21 +32550,21 @@ static bool __pyx_f_9pywrapfst_11ArcIterator_done(struct __pyx_obj_9pywrapfst_Ar
     #endif
   }
 
-  /* "pywrapfst.pyx":3038
+  /* "pywrapfst.pyx":3101
  *       True if the iterator is exhausted, False otherwise.
  *     """
  *     return self._aiter.get().Done()             # <<<<<<<<<<<<<<
  * 
- *   cpdef uint32 flags(self):
+ *   cpdef uint8 flags(self):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3038, __pyx_L1_error)
+    __PYX_ERR(0, 3101, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Done();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3029
+  /* "pywrapfst.pyx":3092
  *     return result
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -31595,7 +32605,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, 3029, __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, 3092, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -31612,23 +32622,23 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_8done(struct __pyx_obj_9pywra
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3040
+/* "pywrapfst.pyx":3103
  *     return self._aiter.get().Done()
  * 
- *   cpdef uint32 flags(self):             # <<<<<<<<<<<<<<
+ *   cpdef uint8 flags(self):             # <<<<<<<<<<<<<<
  *     """
  *     flags(self)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_11flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_11ArcIterator_flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
-  __pyx_t_10basictypes_uint32 __pyx_r;
+static __pyx_t_10basictypes_uint8 __pyx_f_9pywrapfst_11ArcIterator_flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
+  __pyx_t_10basictypes_uint8 __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
-  __pyx_t_10basictypes_uint32 __pyx_t_5;
+  __pyx_t_10basictypes_uint8 __pyx_t_5;
   __Pyx_RefNannySetupContext("flags", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -31639,7 +32649,7 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_11ArcIterator_flags(struct
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3040, __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, 3103, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_11ArcIterator_11flags)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -31655,10 +32665,10 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_11ArcIterator_flags(struct
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3040, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3103, __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, 3040, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyInt_As_uint8_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((uint8_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3103, __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;
@@ -31677,7 +32687,7 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_11ArcIterator_flags(struct
     #endif
   }
 
-  /* "pywrapfst.pyx":3049
+  /* "pywrapfst.pyx":3112
  *       The current iterator behavioral flags as an integer.
  *     """
  *     return self._aiter.get().Flags()             # <<<<<<<<<<<<<<
@@ -31686,15 +32696,15 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_11ArcIterator_flags(struct
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3049, __pyx_L1_error)
+    __PYX_ERR(0, 3112, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Flags();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3040
+  /* "pywrapfst.pyx":3103
  *     return self._aiter.get().Done()
  * 
- *   cpdef uint32 flags(self):             # <<<<<<<<<<<<<<
+ *   cpdef uint8 flags(self):             # <<<<<<<<<<<<<<
  *     """
  *     flags(self)
  */
@@ -31732,7 +32742,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, 3040, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(__pyx_f_9pywrapfst_11ArcIterator_flags(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3103, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -31749,7 +32759,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_10flags(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3051
+/* "pywrapfst.pyx":3114
  *     return self._aiter.get().Flags()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -31774,7 +32784,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_next(struct __pyx_obj_9pywrapfst_Ar
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_next); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3051, __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, 3114, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_11ArcIterator_13next)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -31790,7 +32800,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_next(struct __pyx_obj_9pywrapfst_Ar
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3051, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3114, __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;
@@ -31810,7 +32820,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_next(struct __pyx_obj_9pywrapfst_Ar
     #endif
   }
 
-  /* "pywrapfst.pyx":3057
+  /* "pywrapfst.pyx":3120
  *     Advances the iterator.
  *     """
  *     self._aiter.get().Next()             # <<<<<<<<<<<<<<
@@ -31819,11 +32829,11 @@ static void __pyx_f_9pywrapfst_11ArcIterator_next(struct __pyx_obj_9pywrapfst_Ar
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3057, __pyx_L1_error)
+    __PYX_ERR(0, 3120, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Next();
 
-  /* "pywrapfst.pyx":3051
+  /* "pywrapfst.pyx":3114
  *     return self._aiter.get().Flags()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -31863,7 +32873,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, 3051, __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, 3114, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -31880,7 +32890,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_12next(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3059
+/* "pywrapfst.pyx":3122
  *     self._aiter.get().Next()
  * 
  *   cpdef size_t position(self):             # <<<<<<<<<<<<<<
@@ -31907,7 +32917,7 @@ static size_t __pyx_f_9pywrapfst_11ArcIterator_position(struct __pyx_obj_9pywrap
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_position); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3059, __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, 3122, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_11ArcIterator_15position)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -31923,10 +32933,10 @@ static size_t __pyx_f_9pywrapfst_11ArcIterator_position(struct __pyx_obj_9pywrap
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3059, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3122, __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, 3059, __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, 3122, __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;
@@ -31945,7 +32955,7 @@ static size_t __pyx_f_9pywrapfst_11ArcIterator_position(struct __pyx_obj_9pywrap
     #endif
   }
 
-  /* "pywrapfst.pyx":3068
+  /* "pywrapfst.pyx":3131
  *       The iterator's position, expressed as an integer.
  *     """
  *     return self._aiter.get().Position()             # <<<<<<<<<<<<<<
@@ -31954,12 +32964,12 @@ static size_t __pyx_f_9pywrapfst_11ArcIterator_position(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3068, __pyx_L1_error)
+    __PYX_ERR(0, 3131, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Position();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3059
+  /* "pywrapfst.pyx":3122
  *     self._aiter.get().Next()
  * 
  *   cpdef size_t position(self):             # <<<<<<<<<<<<<<
@@ -32000,7 +33010,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, 3059, __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, 3122, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -32017,7 +33027,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_14position(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3070
+/* "pywrapfst.pyx":3133
  *     return self._aiter.get().Position()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -32042,7 +33052,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_reset(struct __pyx_obj_9pywrapfst_A
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_reset); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3070, __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, 3133, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_11ArcIterator_17reset)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -32058,7 +33068,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_reset(struct __pyx_obj_9pywrapfst_A
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3070, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3133, __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;
@@ -32078,7 +33088,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_reset(struct __pyx_obj_9pywrapfst_A
     #endif
   }
 
-  /* "pywrapfst.pyx":3076
+  /* "pywrapfst.pyx":3139
  *     Resets the iterator to the initial position.
  *     """
  *     self._aiter.get().Reset()             # <<<<<<<<<<<<<<
@@ -32087,11 +33097,11 @@ static void __pyx_f_9pywrapfst_11ArcIterator_reset(struct __pyx_obj_9pywrapfst_A
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3076, __pyx_L1_error)
+    __PYX_ERR(0, 3139, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Reset();
 
-  /* "pywrapfst.pyx":3070
+  /* "pywrapfst.pyx":3133
  *     return self._aiter.get().Position()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -32131,7 +33141,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, 3070, __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, 3133, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -32148,7 +33158,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_16reset(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3078
+/* "pywrapfst.pyx":3141
  *     self._aiter.get().Reset()
  * 
  *   cpdef void seek(self, size_t a):             # <<<<<<<<<<<<<<
@@ -32174,10 +33184,10 @@ static void __pyx_f_9pywrapfst_11ArcIterator_seek(struct __pyx_obj_9pywrapfst_Ar
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_seek); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3078, __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, 3141, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_11ArcIterator_19seek)) {
-        __pyx_t_3 = __Pyx_PyInt_FromSize_t(__pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3078, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_FromSize_t(__pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3141, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -32193,7 +33203,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_seek(struct __pyx_obj_9pywrapfst_Ar
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3078, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3141, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -32213,20 +33223,20 @@ static void __pyx_f_9pywrapfst_11ArcIterator_seek(struct __pyx_obj_9pywrapfst_Ar
     #endif
   }
 
-  /* "pywrapfst.pyx":3087
+  /* "pywrapfst.pyx":3150
  *       a: The position to seek to.
  *     """
  *     self._aiter.get().Seek(a)             # <<<<<<<<<<<<<<
  * 
- *   cpdef void set_flags(self, uint32 flags, uint32 mask):
+ *   cpdef void set_flags(self, uint8 flags, uint8 mask):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3087, __pyx_L1_error)
+    __PYX_ERR(0, 3150, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Seek(__pyx_v_a);
 
-  /* "pywrapfst.pyx":3078
+  /* "pywrapfst.pyx":3141
  *     self._aiter.get().Reset()
  * 
  *   cpdef void seek(self, size_t a):             # <<<<<<<<<<<<<<
@@ -32256,7 +33266,7 @@ static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_19seek(PyObject *__pyx_v_self
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("seek (wrapper)", 0);
   assert(__pyx_arg_a); {
-    __pyx_v_a = __Pyx_PyInt_As_size_t(__pyx_arg_a); if (unlikely((__pyx_v_a == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 3078, __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, 3141, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -32277,7 +33287,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, 3078, __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, 3141, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -32294,16 +33304,16 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_18seek(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3089
+/* "pywrapfst.pyx":3152
  *     self._aiter.get().Seek(a)
  * 
- *   cpdef void set_flags(self, uint32 flags, uint32 mask):             # <<<<<<<<<<<<<<
+ *   cpdef void set_flags(self, uint8 flags, uint8 mask):             # <<<<<<<<<<<<<<
  *     """
  *     set_flags(self, flags, mask)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_21set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, __pyx_t_10basictypes_uint32 __pyx_v_flags, __pyx_t_10basictypes_uint32 __pyx_v_mask, int __pyx_skip_dispatch) {
+static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, __pyx_t_10basictypes_uint8 __pyx_v_flags, __pyx_t_10basictypes_uint8 __pyx_v_mask, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -32323,12 +33333,12 @@ static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapf
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3089, __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, 3152, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_11ArcIterator_21set_flags)) {
-        __pyx_t_3 = __Pyx_PyInt_From_uint32_t(__pyx_v_flags); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3089, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_uint8_t(__pyx_v_flags); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3152, __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, 3089, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyInt_From_uint8_t(__pyx_v_mask); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3152, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_5 = __pyx_t_1; __pyx_t_6 = NULL;
@@ -32346,7 +33356,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, 3089, __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, 3152, __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;
@@ -32356,7 +33366,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, 3089, __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, 3152, __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;
@@ -32364,7 +33374,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, 3089, __pyx_L1_error)
+          __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 3152, __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;
@@ -32375,7 +33385,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, 3089, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3152, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
         }
@@ -32397,7 +33407,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapf
     #endif
   }
 
-  /* "pywrapfst.pyx":3099
+  /* "pywrapfst.pyx":3162
  *       mask: A mask to be applied to the `flags` argument before setting them.
  *     """
  *     self._aiter.get().SetFlags(flags, mask)             # <<<<<<<<<<<<<<
@@ -32406,14 +33416,14 @@ static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3099, __pyx_L1_error)
+    __PYX_ERR(0, 3162, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->SetFlags(__pyx_v_flags, __pyx_v_mask);
 
-  /* "pywrapfst.pyx":3089
+  /* "pywrapfst.pyx":3152
  *     self._aiter.get().Seek(a)
  * 
- *   cpdef void set_flags(self, uint32 flags, uint32 mask):             # <<<<<<<<<<<<<<
+ *   cpdef void set_flags(self, uint8 flags, uint8 mask):             # <<<<<<<<<<<<<<
  *     """
  *     set_flags(self, flags, mask)
  */
@@ -32437,8 +33447,8 @@ static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapf
 static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_21set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static char __pyx_doc_9pywrapfst_11ArcIterator_20set_flags[] = "\n    set_flags(self, flags, mask)\n\n    Sets the current iterator behavioral flags.\n\n    Args:\n      flags: The properties to be set.\n      mask: A mask to be applied to the `flags` argument before setting them.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_21set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  __pyx_t_10basictypes_uint32 __pyx_v_flags;
-  __pyx_t_10basictypes_uint32 __pyx_v_mask;
+  __pyx_t_10basictypes_uint8 __pyx_v_flags;
+  __pyx_t_10basictypes_uint8 __pyx_v_mask;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_flags (wrapper)", 0);
@@ -32465,11 +33475,11 @@ static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_21set_flags(PyObject *__pyx_v
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_mask)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, 1); __PYX_ERR(0, 3089, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, 1); __PYX_ERR(0, 3152, __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, 3089, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_flags") < 0)) __PYX_ERR(0, 3152, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -32477,12 +33487,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, 3089, __pyx_L3_error)
-    __pyx_v_mask = __Pyx_PyInt_As_uint32_t(values[1]); if (unlikely((__pyx_v_mask == ((uint32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3089, __pyx_L3_error)
+    __pyx_v_flags = __Pyx_PyInt_As_uint8_t(values[0]); if (unlikely((__pyx_v_flags == ((uint8_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3152, __pyx_L3_error)
+    __pyx_v_mask = __Pyx_PyInt_As_uint8_t(values[1]); if (unlikely((__pyx_v_mask == ((uint8_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3152, __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, 3089, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3152, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.ArcIterator.set_flags", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -32495,13 +33505,13 @@ static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_21set_flags(PyObject *__pyx_v
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_20set_flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, __pyx_t_10basictypes_uint32 __pyx_v_flags, __pyx_t_10basictypes_uint32 __pyx_v_mask) {
+static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_20set_flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, __pyx_t_10basictypes_uint8 __pyx_v_flags, __pyx_t_10basictypes_uint8 __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_11ArcIterator_set_flags(__pyx_v_self, __pyx_v_flags, __pyx_v_mask, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3089, __pyx_L1_error)
+  __pyx_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, 3152, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -32518,7 +33528,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_20set_flags(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3101
+/* "pywrapfst.pyx":3164
  *     self._aiter.get().SetFlags(flags, mask)
  * 
  *   cpdef object value(self):             # <<<<<<<<<<<<<<
@@ -32544,7 +33554,7 @@ static PyObject *__pyx_f_9pywrapfst_11ArcIterator_value(struct __pyx_obj_9pywrap
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3101, __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, 3164, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_11ArcIterator_23value)) {
         __Pyx_XDECREF(__pyx_r);
@@ -32561,7 +33571,7 @@ static PyObject *__pyx_f_9pywrapfst_11ArcIterator_value(struct __pyx_obj_9pywrap
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3101, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3164, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __pyx_r = __pyx_t_2;
@@ -32582,7 +33592,7 @@ static PyObject *__pyx_f_9pywrapfst_11ArcIterator_value(struct __pyx_obj_9pywrap
     #endif
   }
 
-  /* "pywrapfst.pyx":3107
+  /* "pywrapfst.pyx":3170
  *     Returns the current arc.
  *     """
  *     return _init_Arc(self._aiter.get().Value())             # <<<<<<<<<<<<<<
@@ -32592,15 +33602,15 @@ static PyObject *__pyx_f_9pywrapfst_11ArcIterator_value(struct __pyx_obj_9pywrap
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3107, __pyx_L1_error)
+    __PYX_ERR(0, 3170, __pyx_L1_error)
   }
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_Arc(__pyx_v_self->_aiter.get()->Value())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3107, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_Arc(__pyx_v_self->_aiter.get()->Value())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3170, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3101
+  /* "pywrapfst.pyx":3164
  *     self._aiter.get().SetFlags(flags, mask)
  * 
  *   cpdef object value(self):             # <<<<<<<<<<<<<<
@@ -32642,7 +33652,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, 3101, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_11ArcIterator_value(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3164, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -32690,7 +33700,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_24__reduce_cython__(CYTHON_UN
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._aiter,self._fst cannot be converted to a Python object for pickling")
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__25, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__23, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -32743,7 +33753,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_26__setstate_cython__(CYTHON_
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._aiter,self._fst cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__26, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__24, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -32766,7 +33776,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_26__setstate_cython__(CYTHON_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3119
+/* "pywrapfst.pyx":3182
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -32796,7 +33806,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator___repr__(struct __pyx_
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":3120
+  /* "pywrapfst.pyx":3183
  * 
  *   def __repr__(self):
  *     return "<MutableArcIterator at 0x{:x}>".format(id(self))             # <<<<<<<<<<<<<<
@@ -32804,9 +33814,9 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator___repr__(struct __pyx_
  *   def __init__(self, _MutableFst ifst, int64 state):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_MutableArcIterator_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3120, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_MutableArcIterator_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3183, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3120, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3183, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_t_4 = NULL;
   if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
@@ -32821,14 +33831,14 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator___repr__(struct __pyx_
   __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3120, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3183, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3119
+  /* "pywrapfst.pyx":3182
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -32850,7 +33860,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator___repr__(struct __pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3122
+/* "pywrapfst.pyx":3185
  *     return "<MutableArcIterator at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, _MutableFst ifst, int64 state):             # <<<<<<<<<<<<<<
@@ -32889,11 +33899,11 @@ static int __pyx_pw_9pywrapfst_18MutableArcIterator_3__init__(PyObject *__pyx_v_
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_state)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); __PYX_ERR(0, 3122, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); __PYX_ERR(0, 3185, __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, 3122, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 3185, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -32902,17 +33912,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, 3122, __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, 3185, __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, 3122, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3185, __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, 3122, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__MutableFst, 1, "ifst", 0))) __PYX_ERR(0, 3185, __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 */
@@ -32934,7 +33944,7 @@ static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9
   std::shared_ptr<fst::script::MutableFstClass>  __pyx_t_5;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":3123
+  /* "pywrapfst.pyx":3186
  * 
  *   def __init__(self, _MutableFst ifst, int64 state):
  *     if not ifst._fst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -32943,19 +33953,19 @@ static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3123, __pyx_L1_error)
+    __PYX_ERR(0, 3186, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_ifst->__pyx_base._fst.get()->ValidStateId(__pyx_v_state) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":3124
+    /* "pywrapfst.pyx":3187
  *   def __init__(self, _MutableFst ifst, int64 state):
  *     if not ifst._fst.get().ValidStateId(state):
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._mfst = ifst._mfst
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3124, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3187, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -32969,14 +33979,14 @@ static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3124, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3187, __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, 3124, __pyx_L1_error)
+    __PYX_ERR(0, 3187, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3123
+    /* "pywrapfst.pyx":3186
  * 
  *   def __init__(self, _MutableFst ifst, int64 state):
  *     if not ifst._fst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -32985,7 +33995,7 @@ static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9
  */
   }
 
-  /* "pywrapfst.pyx":3126
+  /* "pywrapfst.pyx":3189
  *       raise FstIndexError("State index out of range")
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._mfst = ifst._mfst             # <<<<<<<<<<<<<<
@@ -32994,16 +34004,16 @@ static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 3126, __pyx_L1_error)
+    __PYX_ERR(0, 3189, __pyx_L1_error)
   }
   __pyx_t_5 = __pyx_v_ifst->_mfst;
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 3126, __pyx_L1_error)
+    __PYX_ERR(0, 3189, __pyx_L1_error)
   }
   __pyx_v_self->_mfst = __pyx_t_5;
 
-  /* "pywrapfst.pyx":3127
+  /* "pywrapfst.pyx":3190
  *     # 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))             # <<<<<<<<<<<<<<
@@ -33012,15 +34022,15 @@ static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3127, __pyx_L1_error)
+    __PYX_ERR(0, 3190, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 3127, __pyx_L1_error)
+    __PYX_ERR(0, 3190, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.reset(new fst::script::MutableArcIteratorClass(__pyx_v_ifst->_mfst.get(), __pyx_v_state));
 
-  /* "pywrapfst.pyx":3122
+  /* "pywrapfst.pyx":3185
  *     return "<MutableArcIterator at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, _MutableFst ifst, int64 state):             # <<<<<<<<<<<<<<
@@ -33043,7 +34053,7 @@ static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9
 }
 static PyObject *__pyx_gb_9pywrapfst_18MutableArcIterator_6generator(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */
 
-/* "pywrapfst.pyx":3130
+/* "pywrapfst.pyx":3193
  * 
  *   # Magic method used to get a Pythonic Iterator API out of the C++ API
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -33073,7 +34083,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_4__iter__(struct __pyx
   if (unlikely(!__pyx_cur_scope)) {
     __pyx_cur_scope = ((struct __pyx_obj_9pywrapfst___pyx_scope_struct____iter__ *)Py_None);
     __Pyx_INCREF(Py_None);
-    __PYX_ERR(0, 3130, __pyx_L1_error)
+    __PYX_ERR(0, 3193, __pyx_L1_error)
   } else {
     __Pyx_GOTREF(__pyx_cur_scope);
   }
@@ -33081,7 +34091,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_4__iter__(struct __pyx
   __Pyx_INCREF((PyObject *)__pyx_cur_scope->__pyx_v_self);
   __Pyx_GIVEREF((PyObject *)__pyx_cur_scope->__pyx_v_self);
   {
-    __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_9pywrapfst_18MutableArcIterator_6generator, NULL, (PyObject *) __pyx_cur_scope, __pyx_n_s_iter, __pyx_n_s_MutableArcIterator___iter, __pyx_n_s_pywrapfst_2); if (unlikely(!gen)) __PYX_ERR(0, 3130, __pyx_L1_error)
+    __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_9pywrapfst_18MutableArcIterator_6generator, NULL, (PyObject *) __pyx_cur_scope, __pyx_n_s_iter, __pyx_n_s_MutableArcIterator___iter, __pyx_n_s_pywrapfst_2); if (unlikely(!gen)) __PYX_ERR(0, 3193, __pyx_L1_error)
     __Pyx_DECREF(__pyx_cur_scope);
     __Pyx_RefNannyFinishContext();
     return (PyObject *) gen;
@@ -33113,9 +34123,9 @@ static PyObject *__pyx_gb_9pywrapfst_18MutableArcIterator_6generator(__pyx_Corou
     return NULL;
   }
   __pyx_L3_first_run:;
-  if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 3130, __pyx_L1_error)
+  if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 3193, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3131
+  /* "pywrapfst.pyx":3194
  *   # Magic method used to get a Pythonic Iterator API out of the C++ API
  *   def __iter__(self):
  *     while not self.done():             # <<<<<<<<<<<<<<
@@ -33125,12 +34135,12 @@ static PyObject *__pyx_gb_9pywrapfst_18MutableArcIterator_6generator(__pyx_Corou
   while (1) {
     if (unlikely(((PyObject *)__pyx_cur_scope->__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "done");
-      __PYX_ERR(0, 3131, __pyx_L1_error)
+      __PYX_ERR(0, 3194, __pyx_L1_error)
     }
     __pyx_t_1 = ((!(((struct __pyx_vtabstruct_9pywrapfst_MutableArcIterator *)__pyx_cur_scope->__pyx_v_self->__pyx_vtab)->done(__pyx_cur_scope->__pyx_v_self, 0) != 0)) != 0);
     if (!__pyx_t_1) break;
 
-    /* "pywrapfst.pyx":3132
+    /* "pywrapfst.pyx":3195
  *   def __iter__(self):
  *     while not self.done():
  *       yield self.value()             # <<<<<<<<<<<<<<
@@ -33139,9 +34149,9 @@ static PyObject *__pyx_gb_9pywrapfst_18MutableArcIterator_6generator(__pyx_Corou
  */
     if (unlikely(((PyObject *)__pyx_cur_scope->__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "value");
-      __PYX_ERR(0, 3132, __pyx_L1_error)
+      __PYX_ERR(0, 3195, __pyx_L1_error)
     }
-    __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst_MutableArcIterator *)__pyx_cur_scope->__pyx_v_self->__pyx_vtab)->value(__pyx_cur_scope->__pyx_v_self, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3132, __pyx_L1_error)
+    __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst_MutableArcIterator *)__pyx_cur_scope->__pyx_v_self->__pyx_vtab)->value(__pyx_cur_scope->__pyx_v_self, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3195, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_r = __pyx_t_2;
     __pyx_t_2 = 0;
@@ -33152,9 +34162,9 @@ static PyObject *__pyx_gb_9pywrapfst_18MutableArcIterator_6generator(__pyx_Corou
     __pyx_generator->resume_label = 1;
     return __pyx_r;
     __pyx_L6_resume_from_yield:;
-    if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 3132, __pyx_L1_error)
+    if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 3195, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3133
+    /* "pywrapfst.pyx":3196
  *     while not self.done():
  *       yield self.value()
  *       self.next()             # <<<<<<<<<<<<<<
@@ -33163,13 +34173,13 @@ static PyObject *__pyx_gb_9pywrapfst_18MutableArcIterator_6generator(__pyx_Corou
  */
     if (unlikely(((PyObject *)__pyx_cur_scope->__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "next");
-      __PYX_ERR(0, 3133, __pyx_L1_error)
+      __PYX_ERR(0, 3196, __pyx_L1_error)
     }
     ((struct __pyx_vtabstruct_9pywrapfst_MutableArcIterator *)__pyx_cur_scope->__pyx_v_self->__pyx_vtab)->next(__pyx_cur_scope->__pyx_v_self, 0);
   }
   CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope);
 
-  /* "pywrapfst.pyx":3130
+  /* "pywrapfst.pyx":3193
  * 
  *   # Magic method used to get a Pythonic Iterator API out of the C++ API
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -33194,7 +34204,7 @@ static PyObject *__pyx_gb_9pywrapfst_18MutableArcIterator_6generator(__pyx_Corou
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3135
+/* "pywrapfst.pyx":3198
  *       self.next()
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -33221,7 +34231,7 @@ static bool __pyx_f_9pywrapfst_18MutableArcIterator_done(struct __pyx_obj_9pywra
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_done); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3135, __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, 3198, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_18MutableArcIterator_8done)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -33237,10 +34247,10 @@ static bool __pyx_f_9pywrapfst_18MutableArcIterator_done(struct __pyx_obj_9pywra
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3135, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3198, __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, 3135, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3198, __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;
@@ -33259,21 +34269,21 @@ static bool __pyx_f_9pywrapfst_18MutableArcIterator_done(struct __pyx_obj_9pywra
     #endif
   }
 
-  /* "pywrapfst.pyx":3144
+  /* "pywrapfst.pyx":3207
  *       True if the iterator is exhausted, False otherwise.
  *     """
  *     return self._aiter.get().Done()             # <<<<<<<<<<<<<<
  * 
- *   cpdef uint32 flags(self):
+ *   cpdef uint8 flags(self):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3144, __pyx_L1_error)
+    __PYX_ERR(0, 3207, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Done();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3135
+  /* "pywrapfst.pyx":3198
  *       self.next()
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -33314,7 +34324,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_7done(struct __pyx_obj
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("done", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_18MutableArcIterator_done(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3135, __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, 3198, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33331,23 +34341,23 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_7done(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3146
+/* "pywrapfst.pyx":3209
  *     return self._aiter.get().Done()
  * 
- *   cpdef uint32 flags(self):             # <<<<<<<<<<<<<<
+ *   cpdef uint8 flags(self):             # <<<<<<<<<<<<<<
  *     """
  *     flags(self)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_10flags(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;
+static __pyx_t_10basictypes_uint8 __pyx_f_9pywrapfst_18MutableArcIterator_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
+  __pyx_t_10basictypes_uint8 __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
-  __pyx_t_10basictypes_uint32 __pyx_t_5;
+  __pyx_t_10basictypes_uint8 __pyx_t_5;
   __Pyx_RefNannySetupContext("flags", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -33358,7 +34368,7 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_18MutableArcIterator_flags
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3146, __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, 3209, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_18MutableArcIterator_10flags)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -33374,10 +34384,10 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_18MutableArcIterator_flags
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3146, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3209, __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, 3146, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyInt_As_uint8_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((uint8_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3209, __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;
@@ -33396,7 +34406,7 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_18MutableArcIterator_flags
     #endif
   }
 
-  /* "pywrapfst.pyx":3155
+  /* "pywrapfst.pyx":3218
  *       The current iterator behavioral flags as an integer.
  *     """
  *     return self._aiter.get().Flags()             # <<<<<<<<<<<<<<
@@ -33405,15 +34415,15 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_18MutableArcIterator_flags
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3155, __pyx_L1_error)
+    __PYX_ERR(0, 3218, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Flags();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3146
+  /* "pywrapfst.pyx":3209
  *     return self._aiter.get().Done()
  * 
- *   cpdef uint32 flags(self):             # <<<<<<<<<<<<<<
+ *   cpdef uint8 flags(self):             # <<<<<<<<<<<<<<
  *     """
  *     flags(self)
  */
@@ -33451,7 +34461,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_9flags(struct __pyx_ob
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("flags", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_From_uint32_t(__pyx_f_9pywrapfst_18MutableArcIterator_flags(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3146, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(__pyx_f_9pywrapfst_18MutableArcIterator_flags(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3209, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33468,7 +34478,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_9flags(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3157
+/* "pywrapfst.pyx":3220
  *     return self._aiter.get().Flags()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -33493,7 +34503,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_next(struct __pyx_obj_9pywra
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_next); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3157, __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, 3220, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_18MutableArcIterator_12next)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -33509,7 +34519,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_next(struct __pyx_obj_9pywra
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3157, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3220, __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;
@@ -33529,7 +34539,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_next(struct __pyx_obj_9pywra
     #endif
   }
 
-  /* "pywrapfst.pyx":3163
+  /* "pywrapfst.pyx":3226
  *     Advances the iterator.
  *     """
  *     self._aiter.get().Next()             # <<<<<<<<<<<<<<
@@ -33538,11 +34548,11 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_next(struct __pyx_obj_9pywra
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3163, __pyx_L1_error)
+    __PYX_ERR(0, 3226, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Next();
 
-  /* "pywrapfst.pyx":3157
+  /* "pywrapfst.pyx":3220
  *     return self._aiter.get().Flags()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -33582,7 +34592,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_11next(struct __pyx_ob
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("next", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_18MutableArcIterator_next(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3157, __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, 3220, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33599,7 +34609,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_11next(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3165
+/* "pywrapfst.pyx":3228
  *     self._aiter.get().Next()
  * 
  *   cpdef size_t position(self):             # <<<<<<<<<<<<<<
@@ -33626,7 +34636,7 @@ static size_t __pyx_f_9pywrapfst_18MutableArcIterator_position(struct __pyx_obj_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_position); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3165, __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, 3228, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_18MutableArcIterator_14position)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -33642,10 +34652,10 @@ static size_t __pyx_f_9pywrapfst_18MutableArcIterator_position(struct __pyx_obj_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3165, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3228, __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, 3165, __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, 3228, __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;
@@ -33664,7 +34674,7 @@ static size_t __pyx_f_9pywrapfst_18MutableArcIterator_position(struct __pyx_obj_
     #endif
   }
 
-  /* "pywrapfst.pyx":3174
+  /* "pywrapfst.pyx":3237
  *       The iterator's position, expressed as an integer.
  *     """
  *     return self._aiter.get().Position()             # <<<<<<<<<<<<<<
@@ -33673,12 +34683,12 @@ static size_t __pyx_f_9pywrapfst_18MutableArcIterator_position(struct __pyx_obj_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3174, __pyx_L1_error)
+    __PYX_ERR(0, 3237, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Position();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3165
+  /* "pywrapfst.pyx":3228
  *     self._aiter.get().Next()
  * 
  *   cpdef size_t position(self):             # <<<<<<<<<<<<<<
@@ -33719,7 +34729,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_13position(struct __py
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("position", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_FromSize_t(__pyx_f_9pywrapfst_18MutableArcIterator_position(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3165, __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, 3228, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33736,7 +34746,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_13position(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3176
+/* "pywrapfst.pyx":3239
  *     return self._aiter.get().Position()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -33761,7 +34771,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_reset(struct __pyx_obj_9pywr
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_reset); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3176, __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, 3239, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_18MutableArcIterator_16reset)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -33777,7 +34787,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_reset(struct __pyx_obj_9pywr
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3176, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3239, __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;
@@ -33797,7 +34807,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_reset(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":3182
+  /* "pywrapfst.pyx":3245
  *     Resets the iterator to the initial position.
  *     """
  *     self._aiter.get().Reset()             # <<<<<<<<<<<<<<
@@ -33806,11 +34816,11 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_reset(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3182, __pyx_L1_error)
+    __PYX_ERR(0, 3245, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Reset();
 
-  /* "pywrapfst.pyx":3176
+  /* "pywrapfst.pyx":3239
  *     return self._aiter.get().Position()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -33850,7 +34860,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_15reset(struct __pyx_o
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("reset", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_18MutableArcIterator_reset(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3176, __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, 3239, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33867,7 +34877,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_15reset(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3184
+/* "pywrapfst.pyx":3247
  *     self._aiter.get().Reset()
  * 
  *   cpdef void seek(self, size_t a):             # <<<<<<<<<<<<<<
@@ -33893,10 +34903,10 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_seek(struct __pyx_obj_9pywra
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_seek); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3184, __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, 3247, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_18MutableArcIterator_18seek)) {
-        __pyx_t_3 = __Pyx_PyInt_FromSize_t(__pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3184, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_FromSize_t(__pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3247, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -33912,7 +34922,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_seek(struct __pyx_obj_9pywra
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3184, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3247, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -33932,20 +34942,20 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_seek(struct __pyx_obj_9pywra
     #endif
   }
 
-  /* "pywrapfst.pyx":3193
+  /* "pywrapfst.pyx":3256
  *       a: The position to seek to.
  *     """
  *     self._aiter.get().Seek(a)             # <<<<<<<<<<<<<<
  * 
- *   cpdef void set_flags(self, uint32 flags, uint32 mask):
+ *   cpdef void set_flags(self, uint8 flags, uint8 mask):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3193, __pyx_L1_error)
+    __PYX_ERR(0, 3256, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Seek(__pyx_v_a);
 
-  /* "pywrapfst.pyx":3184
+  /* "pywrapfst.pyx":3247
  *     self._aiter.get().Reset()
  * 
  *   cpdef void seek(self, size_t a):             # <<<<<<<<<<<<<<
@@ -33975,7 +34985,7 @@ static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_18seek(PyObject *__pyx
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("seek (wrapper)", 0);
   assert(__pyx_arg_a); {
-    __pyx_v_a = __Pyx_PyInt_As_size_t(__pyx_arg_a); if (unlikely((__pyx_v_a == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 3184, __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, 3247, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -33996,7 +35006,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_17seek(struct __pyx_ob
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("seek", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_18MutableArcIterator_seek(__pyx_v_self, __pyx_v_a, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3184, __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, 3247, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -34013,16 +35023,16 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_17seek(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3195
+/* "pywrapfst.pyx":3258
  *     self._aiter.get().Seek(a)
  * 
- *   cpdef void set_flags(self, uint32 flags, uint32 mask):             # <<<<<<<<<<<<<<
+ *   cpdef void set_flags(self, uint8 flags, uint8 mask):             # <<<<<<<<<<<<<<
  *     """
  *     set_flags(self, flags, mask)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_20set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, __pyx_t_10basictypes_uint32 __pyx_v_flags, __pyx_t_10basictypes_uint32 __pyx_v_mask, int __pyx_skip_dispatch) {
+static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, __pyx_t_10basictypes_uint8 __pyx_v_flags, __pyx_t_10basictypes_uint8 __pyx_v_mask, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -34042,12 +35052,12 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3195, __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, 3258, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_18MutableArcIterator_20set_flags)) {
-        __pyx_t_3 = __Pyx_PyInt_From_uint32_t(__pyx_v_flags); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3195, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_uint8_t(__pyx_v_flags); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3258, __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, 3195, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyInt_From_uint8_t(__pyx_v_mask); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3258, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_5 = __pyx_t_1; __pyx_t_6 = NULL;
@@ -34065,7 +35075,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, 3195, __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, 3258, __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;
@@ -34075,7 +35085,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, 3195, __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, 3258, __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;
@@ -34083,7 +35093,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, 3195, __pyx_L1_error)
+          __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 3258, __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;
@@ -34094,7 +35104,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, 3195, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3258, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
         }
@@ -34116,7 +35126,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9
     #endif
   }
 
-  /* "pywrapfst.pyx":3205
+  /* "pywrapfst.pyx":3268
  *       mask: A mask to be applied to the `flags` argument before setting them.
  *     """
  *     self._aiter.get().SetFlags(flags, mask)             # <<<<<<<<<<<<<<
@@ -34125,14 +35135,14 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3205, __pyx_L1_error)
+    __PYX_ERR(0, 3268, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->SetFlags(__pyx_v_flags, __pyx_v_mask);
 
-  /* "pywrapfst.pyx":3195
+  /* "pywrapfst.pyx":3258
  *     self._aiter.get().Seek(a)
  * 
- *   cpdef void set_flags(self, uint32 flags, uint32 mask):             # <<<<<<<<<<<<<<
+ *   cpdef void set_flags(self, uint8 flags, uint8 mask):             # <<<<<<<<<<<<<<
  *     """
  *     set_flags(self, flags, mask)
  */
@@ -34156,8 +35166,8 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9
 static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_20set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static char __pyx_doc_9pywrapfst_18MutableArcIterator_19set_flags[] = "\n    set_flags(self, flags, mask)\n\n    Sets the current iterator behavioral flags.\n\n    Args:\n      flags: The properties to be set.\n      mask: A mask to be applied to the `flags` argument before setting them.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_20set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  __pyx_t_10basictypes_uint32 __pyx_v_flags;
-  __pyx_t_10basictypes_uint32 __pyx_v_mask;
+  __pyx_t_10basictypes_uint8 __pyx_v_flags;
+  __pyx_t_10basictypes_uint8 __pyx_v_mask;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_flags (wrapper)", 0);
@@ -34184,11 +35194,11 @@ static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_20set_flags(PyObject *
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_mask)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, 1); __PYX_ERR(0, 3195, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, 1); __PYX_ERR(0, 3258, __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, 3195, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_flags") < 0)) __PYX_ERR(0, 3258, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -34196,12 +35206,12 @@ static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_20set_flags(PyObject *
       values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
-    __pyx_v_flags = __Pyx_PyInt_As_uint32_t(values[0]); if (unlikely((__pyx_v_flags == ((uint32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3195, __pyx_L3_error)
-    __pyx_v_mask = __Pyx_PyInt_As_uint32_t(values[1]); if (unlikely((__pyx_v_mask == ((uint32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3195, __pyx_L3_error)
+    __pyx_v_flags = __Pyx_PyInt_As_uint8_t(values[0]); if (unlikely((__pyx_v_flags == ((uint8_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3258, __pyx_L3_error)
+    __pyx_v_mask = __Pyx_PyInt_As_uint8_t(values[1]); if (unlikely((__pyx_v_mask == ((uint8_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3258, __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, 3195, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3258, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableArcIterator.set_flags", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -34214,13 +35224,13 @@ static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_20set_flags(PyObject *
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_19set_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_19set_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, __pyx_t_10basictypes_uint8 __pyx_v_flags, __pyx_t_10basictypes_uint8 __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, 3195, __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, 3258, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -34237,7 +35247,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_19set_flags(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3207
+/* "pywrapfst.pyx":3270
  *     self._aiter.get().SetFlags(flags, mask)
  * 
  *   cpdef void set_value(self, Arc arc):             # <<<<<<<<<<<<<<
@@ -34262,7 +35272,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_value(struct __pyx_obj_9
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3207, __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, 3270, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_18MutableArcIterator_22set_value)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -34278,7 +35288,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_value(struct __pyx_obj_9
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, ((PyObject *)__pyx_v_arc)) : __Pyx_PyObject_CallOneArg(__pyx_t_3, ((PyObject *)__pyx_v_arc));
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3207, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3270, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -34298,7 +35308,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_value(struct __pyx_obj_9
     #endif
   }
 
-  /* "pywrapfst.pyx":3216
+  /* "pywrapfst.pyx":3279
  *       arc: The arc to replace the current arc with.
  *     """
  *     self._aiter.get().SetValue(deref(arc._arc))             # <<<<<<<<<<<<<<
@@ -34307,15 +35317,15 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_value(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3216, __pyx_L1_error)
+    __PYX_ERR(0, 3279, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_arc) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 3216, __pyx_L1_error)
+    __PYX_ERR(0, 3279, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->SetValue((*__pyx_v_arc->_arc));
 
-  /* "pywrapfst.pyx":3207
+  /* "pywrapfst.pyx":3270
  *     self._aiter.get().SetFlags(flags, mask)
  * 
  *   cpdef void set_value(self, Arc arc):             # <<<<<<<<<<<<<<
@@ -34342,7 +35352,7 @@ static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_22set_value(PyObject *
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_value (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_arc), __pyx_ptype_9pywrapfst_Arc, 1, "arc", 0))) __PYX_ERR(0, 3207, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_arc), __pyx_ptype_9pywrapfst_Arc, 1, "arc", 0))) __PYX_ERR(0, 3270, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_21set_value(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_Arc *)__pyx_v_arc));
 
   /* function exit code */
@@ -34360,7 +35370,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_21set_value(struct __p
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("set_value", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_18MutableArcIterator_set_value(__pyx_v_self, __pyx_v_arc, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3207, __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, 3270, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -34377,7 +35387,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_21set_value(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3218
+/* "pywrapfst.pyx":3281
  *     self._aiter.get().SetValue(deref(arc._arc))
  * 
  *   cpdef object value(self):             # <<<<<<<<<<<<<<
@@ -34403,7 +35413,7 @@ static PyObject *__pyx_f_9pywrapfst_18MutableArcIterator_value(struct __pyx_obj_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3218, __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, 3281, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_18MutableArcIterator_24value)) {
         __Pyx_XDECREF(__pyx_r);
@@ -34420,7 +35430,7 @@ static PyObject *__pyx_f_9pywrapfst_18MutableArcIterator_value(struct __pyx_obj_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3218, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3281, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __pyx_r = __pyx_t_2;
@@ -34441,7 +35451,7 @@ static PyObject *__pyx_f_9pywrapfst_18MutableArcIterator_value(struct __pyx_obj_
     #endif
   }
 
-  /* "pywrapfst.pyx":3224
+  /* "pywrapfst.pyx":3287
  *     Returns the current arc.
  *     """
  *     return _init_Arc(self._aiter.get().Value())             # <<<<<<<<<<<<<<
@@ -34451,15 +35461,15 @@ static PyObject *__pyx_f_9pywrapfst_18MutableArcIterator_value(struct __pyx_obj_
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3224, __pyx_L1_error)
+    __PYX_ERR(0, 3287, __pyx_L1_error)
   }
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_Arc(__pyx_v_self->_aiter.get()->Value())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3224, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_Arc(__pyx_v_self->_aiter.get()->Value())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3287, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3218
+  /* "pywrapfst.pyx":3281
  *     self._aiter.get().SetValue(deref(arc._arc))
  * 
  *   cpdef object value(self):             # <<<<<<<<<<<<<<
@@ -34501,7 +35511,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_23value(struct __pyx_o
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("value", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_18MutableArcIterator_value(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3218, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_18MutableArcIterator_value(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3281, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -34549,7 +35559,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_25__reduce_cython__(CY
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._aiter,self._mfst cannot be converted to a Python object for pickling")
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__27, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__25, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -34602,7 +35612,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_27__setstate_cython__(
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._aiter,self._mfst cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__28, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__26, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -34625,7 +35635,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_27__setstate_cython__(
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3238
+/* "pywrapfst.pyx":3301
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -34655,7 +35665,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator___repr__(struct __pyx_obj_9
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":3239
+  /* "pywrapfst.pyx":3302
  * 
  *   def __repr__(self):
  *     return "<StateIterator at 0x{:x}>".format(id(self))             # <<<<<<<<<<<<<<
@@ -34663,9 +35673,9 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator___repr__(struct __pyx_obj_9
  *   def __init__(self, _Fst ifst):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_StateIterator_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3239, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_StateIterator_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3302, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3239, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3302, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_t_4 = NULL;
   if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
@@ -34680,14 +35690,14 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator___repr__(struct __pyx_obj_9
   __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3239, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3302, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3238
+  /* "pywrapfst.pyx":3301
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -34709,7 +35719,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator___repr__(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3241
+/* "pywrapfst.pyx":3304
  *     return "<StateIterator at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, _Fst ifst):             # <<<<<<<<<<<<<<
@@ -34743,7 +35753,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, 3241, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 3304, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
       goto __pyx_L5_argtuple_error;
@@ -34754,13 +35764,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, 3241, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3304, __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, 3241, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3304, __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 */
@@ -34778,7 +35788,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":3243
+  /* "pywrapfst.pyx":3306
  *   def __init__(self, _Fst ifst):
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._fst = ifst._fst             # <<<<<<<<<<<<<<
@@ -34787,16 +35797,16 @@ static int __pyx_pf_9pywrapfst_13StateIterator_2__init__(struct __pyx_obj_9pywra
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3243, __pyx_L1_error)
+    __PYX_ERR(0, 3306, __pyx_L1_error)
   }
   __pyx_t_1 = __pyx_v_ifst->_fst;
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3243, __pyx_L1_error)
+    __PYX_ERR(0, 3306, __pyx_L1_error)
   }
   __pyx_v_self->_fst = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3244
+  /* "pywrapfst.pyx":3307
  *     # 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)))             # <<<<<<<<<<<<<<
@@ -34805,15 +35815,15 @@ static int __pyx_pf_9pywrapfst_13StateIterator_2__init__(struct __pyx_obj_9pywra
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 3244, __pyx_L1_error)
+    __PYX_ERR(0, 3307, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3244, __pyx_L1_error)
+    __PYX_ERR(0, 3307, __pyx_L1_error)
   }
   __pyx_v_self->_siter.reset(new fst::script::StateIteratorClass((*__pyx_v_self->_fst)));
 
-  /* "pywrapfst.pyx":3241
+  /* "pywrapfst.pyx":3304
  *     return "<StateIterator at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, _Fst ifst):             # <<<<<<<<<<<<<<
@@ -34832,7 +35842,7 @@ static int __pyx_pf_9pywrapfst_13StateIterator_2__init__(struct __pyx_obj_9pywra
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3247
+/* "pywrapfst.pyx":3310
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -34858,7 +35868,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_4__iter__(struct __pyx_obj_
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__iter__", 0);
 
-  /* "pywrapfst.pyx":3248
+  /* "pywrapfst.pyx":3311
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):
  *     return self             # <<<<<<<<<<<<<<
@@ -34870,7 +35880,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_4__iter__(struct __pyx_obj_
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3247
+  /* "pywrapfst.pyx":3310
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -34885,7 +35895,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_4__iter__(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3251
+/* "pywrapfst.pyx":3314
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -34914,7 +35924,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("__next__", 0);
 
-  /* "pywrapfst.pyx":3252
+  /* "pywrapfst.pyx":3315
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -34923,12 +35933,12 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "done");
-    __PYX_ERR(0, 3252, __pyx_L1_error)
+    __PYX_ERR(0, 3315, __pyx_L1_error)
   }
   __pyx_t_1 = (((struct __pyx_vtabstruct_9pywrapfst_StateIterator *)__pyx_v_self->__pyx_vtab)->done(__pyx_v_self, 0) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":3253
+    /* "pywrapfst.pyx":3316
  *   def __next__(self):
  *     if self.done():
  *       raise StopIteration             # <<<<<<<<<<<<<<
@@ -34936,9 +35946,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, 3253, __pyx_L1_error)
+    __PYX_ERR(0, 3316, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3252
+    /* "pywrapfst.pyx":3315
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -34947,7 +35957,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
  */
   }
 
-  /* "pywrapfst.pyx":3254
+  /* "pywrapfst.pyx":3317
  *     if self.done():
  *       raise StopIteration
  *     cdef int64 result = self.value()             # <<<<<<<<<<<<<<
@@ -34956,11 +35966,11 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "value");
-    __PYX_ERR(0, 3254, __pyx_L1_error)
+    __PYX_ERR(0, 3317, __pyx_L1_error)
   }
   __pyx_v_result = ((struct __pyx_vtabstruct_9pywrapfst_StateIterator *)__pyx_v_self->__pyx_vtab)->value(__pyx_v_self, 0);
 
-  /* "pywrapfst.pyx":3255
+  /* "pywrapfst.pyx":3318
  *       raise StopIteration
  *     cdef int64 result = self.value()
  *     self.next()             # <<<<<<<<<<<<<<
@@ -34969,11 +35979,11 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "next");
-    __PYX_ERR(0, 3255, __pyx_L1_error)
+    __PYX_ERR(0, 3318, __pyx_L1_error)
   }
   ((struct __pyx_vtabstruct_9pywrapfst_StateIterator *)__pyx_v_self->__pyx_vtab)->next(__pyx_v_self, 0);
 
-  /* "pywrapfst.pyx":3256
+  /* "pywrapfst.pyx":3319
  *     cdef int64 result = self.value()
  *     self.next()
  *     return result             # <<<<<<<<<<<<<<
@@ -34981,13 +35991,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, 3256, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_v_result); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3319, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3251
+  /* "pywrapfst.pyx":3314
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -35006,7 +36016,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3258
+/* "pywrapfst.pyx":3321
  *     return result
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -35033,7 +36043,7 @@ static bool __pyx_f_9pywrapfst_13StateIterator_done(struct __pyx_obj_9pywrapfst_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_done); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3258, __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, 3321, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_13StateIterator_9done)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -35049,10 +36059,10 @@ static bool __pyx_f_9pywrapfst_13StateIterator_done(struct __pyx_obj_9pywrapfst_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3258, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3321, __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, 3258, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3321, __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;
@@ -35071,7 +36081,7 @@ static bool __pyx_f_9pywrapfst_13StateIterator_done(struct __pyx_obj_9pywrapfst_
     #endif
   }
 
-  /* "pywrapfst.pyx":3267
+  /* "pywrapfst.pyx":3330
  *       True if the iterator is exhausted, False otherwise.
  *     """
  *     return self._siter.get().Done()             # <<<<<<<<<<<<<<
@@ -35080,12 +36090,12 @@ static bool __pyx_f_9pywrapfst_13StateIterator_done(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 3267, __pyx_L1_error)
+    __PYX_ERR(0, 3330, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_siter.get()->Done();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3258
+  /* "pywrapfst.pyx":3321
  *     return result
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -35126,7 +36136,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, 3258, __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, 3321, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -35143,7 +36153,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_8done(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3269
+/* "pywrapfst.pyx":3332
  *     return self._siter.get().Done()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -35168,7 +36178,7 @@ static void __pyx_f_9pywrapfst_13StateIterator_next(struct __pyx_obj_9pywrapfst_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_next); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3269, __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, 3332, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_13StateIterator_11next)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -35184,7 +36194,7 @@ static void __pyx_f_9pywrapfst_13StateIterator_next(struct __pyx_obj_9pywrapfst_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3269, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3332, __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;
@@ -35204,7 +36214,7 @@ static void __pyx_f_9pywrapfst_13StateIterator_next(struct __pyx_obj_9pywrapfst_
     #endif
   }
 
-  /* "pywrapfst.pyx":3275
+  /* "pywrapfst.pyx":3338
  *     Advances the iterator.
  *     """
  *     self._siter.get().Next()             # <<<<<<<<<<<<<<
@@ -35213,11 +36223,11 @@ static void __pyx_f_9pywrapfst_13StateIterator_next(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 3275, __pyx_L1_error)
+    __PYX_ERR(0, 3338, __pyx_L1_error)
   }
   __pyx_v_self->_siter.get()->Next();
 
-  /* "pywrapfst.pyx":3269
+  /* "pywrapfst.pyx":3332
  *     return self._siter.get().Done()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -35257,7 +36267,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, 3269, __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, 3332, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -35274,7 +36284,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_10next(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3277
+/* "pywrapfst.pyx":3340
  *     self._siter.get().Next()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -35299,7 +36309,7 @@ static void __pyx_f_9pywrapfst_13StateIterator_reset(struct __pyx_obj_9pywrapfst
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_reset); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3277, __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, 3340, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_13StateIterator_13reset)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -35315,7 +36325,7 @@ static void __pyx_f_9pywrapfst_13StateIterator_reset(struct __pyx_obj_9pywrapfst
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3277, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3340, __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;
@@ -35335,7 +36345,7 @@ static void __pyx_f_9pywrapfst_13StateIterator_reset(struct __pyx_obj_9pywrapfst
     #endif
   }
 
-  /* "pywrapfst.pyx":3283
+  /* "pywrapfst.pyx":3346
  *     Resets the iterator to the initial position.
  *     """
  *     self._siter.get().Reset()             # <<<<<<<<<<<<<<
@@ -35344,11 +36354,11 @@ static void __pyx_f_9pywrapfst_13StateIterator_reset(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 3283, __pyx_L1_error)
+    __PYX_ERR(0, 3346, __pyx_L1_error)
   }
   __pyx_v_self->_siter.get()->Reset();
 
-  /* "pywrapfst.pyx":3277
+  /* "pywrapfst.pyx":3340
  *     self._siter.get().Next()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -35388,7 +36398,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, 3277, __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, 3340, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -35405,7 +36415,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_12reset(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3285
+/* "pywrapfst.pyx":3348
  *     self._siter.get().Reset()
  * 
  *   cpdef int64 value(self):             # <<<<<<<<<<<<<<
@@ -35432,7 +36442,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_13StateIterator_value(struc
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3285, __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, 3348, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_13StateIterator_15value)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -35448,10 +36458,10 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_13StateIterator_value(struc
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3285, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3348, __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, 3285, __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, 3348, __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;
@@ -35470,7 +36480,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_13StateIterator_value(struc
     #endif
   }
 
-  /* "pywrapfst.pyx":3291
+  /* "pywrapfst.pyx":3354
  *     Returns the current state index.
  *     """
  *     return self._siter.get().Value()             # <<<<<<<<<<<<<<
@@ -35479,12 +36489,12 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_13StateIterator_value(struc
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 3291, __pyx_L1_error)
+    __PYX_ERR(0, 3354, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_siter.get()->Value();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3285
+  /* "pywrapfst.pyx":3348
  *     self._siter.get().Reset()
  * 
  *   cpdef int64 value(self):             # <<<<<<<<<<<<<<
@@ -35525,7 +36535,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, 3285, __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, 3348, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -35573,7 +36583,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_16__reduce_cython__(CYTHON_
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._fst,self._siter cannot be converted to a Python object for pickling")
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__29, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__27, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -35626,7 +36636,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_18__setstate_cython__(CYTHO
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._fst,self._siter cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__30, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__28, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -35649,7 +36659,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_18__setstate_cython__(CYTHO
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3297
+/* "pywrapfst.pyx":3360
  * 
  * 
  * cdef _Fst _map(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -35658,11 +36668,11 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_18__setstate_cython__(CYTHO
  */
 
 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__31;
+  float __pyx_v_delta = __pyx_k__29;
   PyObject *__pyx_v_map_type = ((PyObject *)__pyx_n_b_identity);
   double __pyx_v_power = ((double)1.);
 
-  /* "pywrapfst.pyx":3301
+  /* "pywrapfst.pyx":3364
  *                map_type=b"identity",
  *                double power=1.,
  *                weight=None):             # <<<<<<<<<<<<<<
@@ -35682,7 +36692,6 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
   PyObject *__pyx_t_6 = NULL;
   PyObject *__pyx_t_7 = NULL;
   fst::script::WeightClass __pyx_t_8;
-  fst::script::WeightClass __pyx_t_9;
   __Pyx_RefNannySetupContext("_map", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -35699,27 +36708,27 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
     }
   }
 
-  /* "pywrapfst.pyx":3303
+  /* "pywrapfst.pyx":3366
  *                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(),
+ *   cdef fst.WeightClass wc
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_map_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3303, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_map_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3366, __pyx_L1_error)
   __pyx_t_2 = ((!(fst::script::GetMapType(__pyx_t_1, (&__pyx_v_map_type_enum)) != 0)) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":3304
+    /* "pywrapfst.pyx":3367
  *   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
+ *   cdef fst.WeightClass wc
+ *   if map_type_enum == fst.TIMES_MAPPER:
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3304, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3367, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Unknown_map_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3304, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Unknown_map_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3367, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __pyx_t_7 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
@@ -35733,7 +36742,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
     }
     __pyx_t_5 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_v_map_type) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_map_type);
     __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3304, __pyx_L1_error)
+    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3367, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __pyx_t_6 = NULL;
@@ -35749,73 +36758,76 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
     __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5);
     __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3304, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3367, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 3304, __pyx_L1_error)
+    __PYX_ERR(0, 3367, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3303
+    /* "pywrapfst.pyx":3366
  *                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(),
+ *   cdef fst.WeightClass wc
  */
   }
 
-  /* "pywrapfst.pyx":3306
+  /* "pywrapfst.pyx":3369
  *     raise FstArgError("Unknown map type: {!r}".format(map_type))
- *   cdef fst.WeightClass wc = (_get_WeightClass_or_One(ifst.weight_type(),
- *       weight) if map_type_enum == fst.TIMES_MAPPER else             # <<<<<<<<<<<<<<
- *       _get_WeightClass_or_Zero(ifst.weight_type(), weight))
- *   return _init_XFst(fst.Map(deref(ifst._fst), map_type_enum, delta, power, wc))
+ *   cdef fst.WeightClass wc
+ *   if map_type_enum == fst.TIMES_MAPPER:             # <<<<<<<<<<<<<<
+ *       wc = _get_WeightClass_or_One(ifst.weight_type(), weight)
+ *   else:
  */
-  if (((__pyx_v_map_type_enum == fst::script::TIMES_MAPPER) != 0)) {
+  __pyx_t_2 = ((__pyx_v_map_type_enum == fst::script::TIMES_MAPPER) != 0);
+  if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":3305
- *   if not fst.GetMapType(tostring(map_type), addr(map_type_enum)):
- *     raise FstArgError("Unknown map type: {!r}".format(map_type))
- *   cdef fst.WeightClass wc = (_get_WeightClass_or_One(ifst.weight_type(),             # <<<<<<<<<<<<<<
- *       weight) if map_type_enum == fst.TIMES_MAPPER else
- *       _get_WeightClass_or_Zero(ifst.weight_type(), weight))
+    /* "pywrapfst.pyx":3370
+ *   cdef fst.WeightClass wc
+ *   if map_type_enum == fst.TIMES_MAPPER:
+ *       wc = _get_WeightClass_or_One(ifst.weight_type(), weight)             # <<<<<<<<<<<<<<
+ *   else:
+ *       wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)
  */
     if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-      __PYX_ERR(0, 3305, __pyx_L1_error)
+      __PYX_ERR(0, 3370, __pyx_L1_error)
     }
+    __pyx_t_8 = __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, 3370, __pyx_L1_error)
+    __pyx_v_wc = __pyx_t_8;
 
-    /* "pywrapfst.pyx":3306
+    /* "pywrapfst.pyx":3369
  *     raise FstArgError("Unknown map type: {!r}".format(map_type))
- *   cdef fst.WeightClass wc = (_get_WeightClass_or_One(ifst.weight_type(),
- *       weight) if map_type_enum == fst.TIMES_MAPPER else             # <<<<<<<<<<<<<<
- *       _get_WeightClass_or_Zero(ifst.weight_type(), weight))
- *   return _init_XFst(fst.Map(deref(ifst._fst), map_type_enum, delta, power, wc))
+ *   cdef fst.WeightClass wc
+ *   if map_type_enum == fst.TIMES_MAPPER:             # <<<<<<<<<<<<<<
+ *       wc = _get_WeightClass_or_One(ifst.weight_type(), weight)
+ *   else:
  */
-    __pyx_t_9 = __pyx_f_9pywrapfst__get_WeightClass_or_One(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3305, __pyx_L1_error)
-    __pyx_t_8 = __pyx_t_9;
-  } else {
+    goto __pyx_L4;
+  }
 
-    /* "pywrapfst.pyx":3307
- *   cdef fst.WeightClass wc = (_get_WeightClass_or_One(ifst.weight_type(),
- *       weight) if map_type_enum == fst.TIMES_MAPPER else
- *       _get_WeightClass_or_Zero(ifst.weight_type(), weight))             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":3372
+ *       wc = _get_WeightClass_or_One(ifst.weight_type(), weight)
+ *   else:
+ *       wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)             # <<<<<<<<<<<<<<
  *   return _init_XFst(fst.Map(deref(ifst._fst), map_type_enum, delta, power, wc))
  * 
  */
+  /*else*/ {
     if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-      __PYX_ERR(0, 3307, __pyx_L1_error)
+      __PYX_ERR(0, 3372, __pyx_L1_error)
     }
-    __pyx_t_9 = __pyx_f_9pywrapfst__get_WeightClass_or_Zero(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3307, __pyx_L1_error)
-    __pyx_t_8 = __pyx_t_9;
+    __pyx_t_8 = __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, 3372, __pyx_L1_error)
+    __pyx_v_wc = __pyx_t_8;
   }
-  __pyx_v_wc = __pyx_t_8;
+  __pyx_L4:;
 
-  /* "pywrapfst.pyx":3308
- *       weight) if map_type_enum == fst.TIMES_MAPPER else
- *       _get_WeightClass_or_Zero(ifst.weight_type(), weight))
+  /* "pywrapfst.pyx":3373
+ *   else:
+ *       wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)
  *   return _init_XFst(fst.Map(deref(ifst._fst), map_type_enum, delta, power, wc))             # <<<<<<<<<<<<<<
  * 
  * 
@@ -35823,15 +36835,15 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
   __Pyx_XDECREF(((PyObject *)__pyx_r));
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3308, __pyx_L1_error)
+    __PYX_ERR(0, 3373, __pyx_L1_error)
   }
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(fst::script::Map((*__pyx_v_ifst->_fst), __pyx_v_map_type_enum, __pyx_v_delta, __pyx_v_power, __pyx_v_wc))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3308, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(fst::script::Map((*__pyx_v_ifst->_fst), __pyx_v_map_type_enum, __pyx_v_delta, __pyx_v_power, __pyx_v_wc))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3373, __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":3297
+  /* "pywrapfst.pyx":3360
  * 
  * 
  * cdef _Fst _map(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -35854,7 +36866,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3311
+/* "pywrapfst.pyx":3376
  * 
  * 
  * cpdef _Fst arcmap(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -35862,13 +36874,13 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
  *                   map_type=b"identity",
  */
 
-static PyObject *__pyx_pw_9pywrapfst_19arcmap(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_21arcmap(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__32;
+  float __pyx_v_delta = __pyx_k__30;
   PyObject *__pyx_v_map_type = ((PyObject *)__pyx_n_b_identity);
   double __pyx_v_power = ((double)1.);
 
-  /* "pywrapfst.pyx":3315
+  /* "pywrapfst.pyx":3380
  *                   map_type=b"identity",
  *                   double power=1.,
  *                   weight=None):             # <<<<<<<<<<<<<<
@@ -35896,8 +36908,8 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_arcmap(struct __pyx_
     }
   }
 
-  /* "pywrapfst.pyx":3358
- *   See also: `statemap`.
+  /* "pywrapfst.pyx":3421
+ *     FstArgError: Unknown map type.
  *   """
  *   return _map(ifst, delta, map_type, power, weight)             # <<<<<<<<<<<<<<
  * 
@@ -35909,13 +36921,13 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_arcmap(struct __pyx_
   __pyx_t_2.map_type = __pyx_v_map_type;
   __pyx_t_2.power = __pyx_v_power;
   __pyx_t_2.weight = __pyx_v_weight;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__map(__pyx_v_ifst, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3358, __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, 3421, __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":3311
+  /* "pywrapfst.pyx":3376
  * 
  * 
  * cpdef _Fst arcmap(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -35935,9 +36947,9 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_arcmap(struct __pyx_
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_19arcmap(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_18arcmap[] = "\n  arcmap(ifst, delta=0.0009765625, map_type=\"identity\", power=1., weight=None)\n\n  Constructively applies a transform to all arcs and final states.\n\n  This operation transforms each arc and final state in the input FST using\n  one of the following:\n\n    * identity: maps to self.\n    * input_epsilon: replaces all input labels with epsilon.\n    * invert: reciprocates all non-Zero weights.\n    * float_power: raises all weights to a floating-point power.\n    * output_epsilon: replaces all output labels with epsilon.\n    * quantize: quantizes weights.\n    * plus: adds a constant to all weights.\n    * power: raises all weights to an integral power.\n    * rmweight: replaces all non-Zero weights with 1.\n    * superfinal: redirects final states to a new superfinal state.\n    * times: right-multiplies a constant by all weights.\n    * to_log: converts weights to the log semiring.\n    * to_log64: converts weights to the log64 semiring.\n    * to_standard: converts weights to the tropical (\"standard\") semiring.\n\n  Args:\n    ifst: The input FST.\n    delta: Comparison/quantization delta (ignored unless `map_type` is\n        `quantize`).\n    map_type: A string matching a known mapping operation (see above).\n    power: A positive scalar or integer power; ignored unless `map_type` is\n        `float_power` or `power` (in which case it defaults to 1).\n    weight: A Weight or weight string passed to the arc-mapper; ignored unless\n        `map_type` is `plus` (in which case it defaults to semiring Zero) or\n        `times` (in which case it defaults to semiring One).\n\n  Returns:\n    An FST with arcs and final states remapped.\n\n  Raises:\n    FstArgError: Unknown map type.\n\n  See also: `statemap`.\n  ";
-static PyObject *__pyx_pw_9pywrapfst_19arcmap(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_21arcmap(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_20arcmap[] = "\n  arcmap(ifst, delta=0.0009765625, map_type=\"identity\", power=1., weight=None)\n\n  Constructively applies a transform to all arcs and final states.\n\n  This operation transforms each arc and final state in the input FST using\n  one of the following:\n\n    * identity: maps to self.\n    * input_epsilon: replaces all input labels with epsilon.\n    * invert: reciprocates all non-Zero weights.\n    * float_power: raises all weights to a floating-point power.\n    * output_epsilon: replaces all output labels with epsilon.\n    * quantize: quantizes weights.\n    * plus: adds a constant to all weights.\n    * power: raises all weights to an integral power.\n    * rmweight: replaces all non-Zero weights with 1.\n    * superfinal: redirects final states to a new superfinal state.\n    * times: right-multiplies a constant by all weights.\n    * to_log: converts weights to the log semiring.\n    * to_log64: converts weights to the log64 semiring.\n    * to_standard: converts weights to the tropical (\"standard\") semiring.\n\n  Args:\n    ifst: The input FST.\n    delta: Comparison/quantization delta (ignored unless `map_type` is\n        `quantize`).\n    map_type: A string matching a known mapping operation (see above).\n    power: A positive scalar or integer power; ignored unless `map_type` is\n        `float_power` or `power` (in which case it defaults to 1).\n    weight: A Weight or weight string passed to the arc-mapper; ignored unless\n        `map_type` is `plus` (in which case it defaults to semiring Zero) or\n        `times` (in which case it defaults to semiring One).\n\n  Returns:\n    An FST with arcs and final states remapped.\n\n  Raises:\n    FstArgError: Unknown map type.\n  ";
+static PyObject *__pyx_pw_9pywrapfst_21arcmap(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst = 0;
   float __pyx_v_delta;
   PyObject *__pyx_v_map_type = 0;
@@ -35951,7 +36963,7 @@ static PyObject *__pyx_pw_9pywrapfst_19arcmap(PyObject *__pyx_self, PyObject *__
     PyObject* values[5] = {0,0,0,0,0};
     values[2] = ((PyObject *)__pyx_n_b_identity);
 
-    /* "pywrapfst.pyx":3315
+    /* "pywrapfst.pyx":3380
  *                   map_type=b"identity",
  *                   double power=1.,
  *                   weight=None):             # <<<<<<<<<<<<<<
@@ -36007,7 +37019,7 @@ static PyObject *__pyx_pw_9pywrapfst_19arcmap(PyObject *__pyx_self, PyObject *__
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "arcmap") < 0)) __PYX_ERR(0, 3311, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "arcmap") < 0)) __PYX_ERR(0, 3376, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -36026,13 +37038,13 @@ static PyObject *__pyx_pw_9pywrapfst_19arcmap(PyObject *__pyx_self, PyObject *__
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
     if (values[1]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3312, __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__32;
+      __pyx_v_delta = __pyx_k__30;
     }
     __pyx_v_map_type = values[2];
     if (values[3]) {
-      __pyx_v_power = __pyx_PyFloat_AsDouble(values[3]); if (unlikely((__pyx_v_power == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 3314, __pyx_L3_error)
+      __pyx_v_power = __pyx_PyFloat_AsDouble(values[3]); if (unlikely((__pyx_v_power == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 3379, __pyx_L3_error)
     } else {
       __pyx_v_power = ((double)1.);
     }
@@ -36040,16 +37052,16 @@ static PyObject *__pyx_pw_9pywrapfst_19arcmap(PyObject *__pyx_self, PyObject *__
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("arcmap", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3311, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("arcmap", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3376, __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, 3311, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_18arcmap(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_map_type, __pyx_v_power, __pyx_v_weight);
+  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_20arcmap(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_map_type, __pyx_v_power, __pyx_v_weight);
 
-  /* "pywrapfst.pyx":3311
+  /* "pywrapfst.pyx":3376
  * 
  * 
  * cpdef _Fst arcmap(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -36066,7 +37078,7 @@ static PyObject *__pyx_pw_9pywrapfst_19arcmap(PyObject *__pyx_self, PyObject *__
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_18arcmap(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, PyObject *__pyx_v_map_type, double __pyx_v_power, PyObject *__pyx_v_weight) {
+static PyObject *__pyx_pf_9pywrapfst_20arcmap(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, PyObject *__pyx_v_map_type, double __pyx_v_power, PyObject *__pyx_v_weight) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -36078,7 +37090,7 @@ static PyObject *__pyx_pf_9pywrapfst_18arcmap(CYTHON_UNUSED PyObject *__pyx_self
   __pyx_t_2.map_type = __pyx_v_map_type;
   __pyx_t_2.power = __pyx_v_power;
   __pyx_t_2.weight = __pyx_v_weight;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_arcmap(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3311, __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, 3376, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -36095,7 +37107,7 @@ static PyObject *__pyx_pf_9pywrapfst_18arcmap(CYTHON_UNUSED PyObject *__pyx_self
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3361
+/* "pywrapfst.pyx":3424
  * 
  * 
  * cpdef _MutableFst compose(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -36103,11 +37115,11 @@ static PyObject *__pyx_pf_9pywrapfst_18arcmap(CYTHON_UNUSED PyObject *__pyx_self
  *                           compose_filter=b"auto",
  */
 
-static PyObject *__pyx_pw_9pywrapfst_21compose(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_23compose(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 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":3364
+  /* "pywrapfst.pyx":3427
  *                           _Fst ifst2,
  *                           compose_filter=b"auto",
  *                           bool connect=True):             # <<<<<<<<<<<<<<
@@ -36132,40 +37144,40 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_compose(struc
     }
   }
 
-  /* "pywrapfst.pyx":3390
+  /* "pywrapfst.pyx":3451
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))             # <<<<<<<<<<<<<<
  *   cdef unique_ptr[fst.ComposeOptions] opts
- *   opts.reset(new fst.ComposeOptions(connect,
+ *   opts.reset(new fst.ComposeOptions(
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3390, __pyx_L1_error)
+    __PYX_ERR(0, 3451, __pyx_L1_error)
   }
   __pyx_v_tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst1->__pyx_vtab)->arc_type(__pyx_v_ifst1, 0)));
 
-  /* "pywrapfst.pyx":3393
- *   cdef unique_ptr[fst.ComposeOptions] opts
- *   opts.reset(new fst.ComposeOptions(connect,
+  /* "pywrapfst.pyx":3455
+ *   opts.reset(new fst.ComposeOptions(
+ *       connect,
  *       _get_compose_filter(tostring(compose_filter))))             # <<<<<<<<<<<<<<
  *   fst.Compose(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))
  *   return _init_MutableFst(tfst.release())
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_compose_filter); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3393, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3393, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_compose_filter); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3455, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3455, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3392
+  /* "pywrapfst.pyx":3453
  *   tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))
  *   cdef unique_ptr[fst.ComposeOptions] opts
- *   opts.reset(new fst.ComposeOptions(connect,             # <<<<<<<<<<<<<<
+ *   opts.reset(new fst.ComposeOptions(             # <<<<<<<<<<<<<<
+ *       connect,
  *       _get_compose_filter(tostring(compose_filter))))
- *   fst.Compose(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))
  */
   __pyx_v_opts.reset(new fst::ComposeOptions(__pyx_v_connect, __pyx_t_2));
 
-  /* "pywrapfst.pyx":3394
- *   opts.reset(new fst.ComposeOptions(connect,
+  /* "pywrapfst.pyx":3456
+ *       connect,
  *       _get_compose_filter(tostring(compose_filter))))
  *   fst.Compose(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))             # <<<<<<<<<<<<<<
  *   return _init_MutableFst(tfst.release())
@@ -36173,15 +37185,15 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_compose(struc
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3394, __pyx_L1_error)
+    __PYX_ERR(0, 3456, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ifst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3394, __pyx_L1_error)
+    __PYX_ERR(0, 3456, __pyx_L1_error)
   }
   fst::script::Compose((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_tfst.get(), (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":3395
+  /* "pywrapfst.pyx":3457
  *       _get_compose_filter(tostring(compose_filter))))
  *   fst.Compose(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -36189,13 +37201,13 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_compose(struc
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3395, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3457, __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":3361
+  /* "pywrapfst.pyx":3424
  * 
  * 
  * cpdef _MutableFst compose(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -36215,9 +37227,9 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_compose(struc
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_21compose(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_20compose[] = "\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\", \"no_match\", \"null\", \"sequence\",\n        \"trivial\".\n    connect: Should output be trimmed?\n\n  Returns:\n    An FST.\n\n  See also: `arcsort`.\n  ";
-static PyObject *__pyx_pw_9pywrapfst_21compose(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_23compose(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_22compose[] = "\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\", \"no_match\", \"null\", \"sequence\",\n        \"trivial\".\n    connect: Should output be trimmed?\n\n  Returns:\n    An FST.\n  ";
+static PyObject *__pyx_pw_9pywrapfst_23compose(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;
   PyObject *__pyx_v_compose_filter = 0;
@@ -36253,7 +37265,7 @@ static PyObject *__pyx_pw_9pywrapfst_21compose(PyObject *__pyx_self, PyObject *_
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ifst2)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("compose", 0, 2, 4, 1); __PYX_ERR(0, 3361, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("compose", 0, 2, 4, 1); __PYX_ERR(0, 3424, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -36269,7 +37281,7 @@ static PyObject *__pyx_pw_9pywrapfst_21compose(PyObject *__pyx_self, PyObject *_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "compose") < 0)) __PYX_ERR(0, 3361, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "compose") < 0)) __PYX_ERR(0, 3424, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -36287,10 +37299,10 @@ static PyObject *__pyx_pw_9pywrapfst_21compose(PyObject *__pyx_self, PyObject *_
     __pyx_v_ifst2 = ((struct __pyx_obj_9pywrapfst__Fst *)values[1]);
     __pyx_v_compose_filter = values[2];
     if (values[3]) {
-      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3364, __pyx_L3_error)
+      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3427, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3364
+      /* "pywrapfst.pyx":3427
  *                           _Fst ifst2,
  *                           compose_filter=b"auto",
  *                           bool connect=True):             # <<<<<<<<<<<<<<
@@ -36302,17 +37314,17 @@ static PyObject *__pyx_pw_9pywrapfst_21compose(PyObject *__pyx_self, PyObject *_
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("compose", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3361, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("compose", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3424, __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, 3361, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3362, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_20compose(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_compose_filter, __pyx_v_connect);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst__Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3424, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3425, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_22compose(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_compose_filter, __pyx_v_connect);
 
-  /* "pywrapfst.pyx":3361
+  /* "pywrapfst.pyx":3424
  * 
  * 
  * cpdef _MutableFst compose(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -36329,7 +37341,7 @@ static PyObject *__pyx_pw_9pywrapfst_21compose(PyObject *__pyx_self, PyObject *_
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_20compose(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, PyObject *__pyx_v_compose_filter, bool __pyx_v_connect) {
+static PyObject *__pyx_pf_9pywrapfst_22compose(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, PyObject *__pyx_v_compose_filter, bool __pyx_v_connect) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -36339,7 +37351,7 @@ static PyObject *__pyx_pf_9pywrapfst_20compose(CYTHON_UNUSED PyObject *__pyx_sel
   __pyx_t_2.__pyx_n = 2;
   __pyx_t_2.compose_filter = __pyx_v_compose_filter;
   __pyx_t_2.connect = __pyx_v_connect;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_compose(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3361, __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, 3424, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -36356,7 +37368,7 @@ static PyObject *__pyx_pf_9pywrapfst_20compose(CYTHON_UNUSED PyObject *__pyx_sel
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3398
+/* "pywrapfst.pyx":3460
  * 
  * 
  * cpdef _Fst convert(_Fst ifst, fst_type=b""):             # <<<<<<<<<<<<<<
@@ -36364,9 +37376,9 @@ static PyObject *__pyx_pf_9pywrapfst_20compose(CYTHON_UNUSED PyObject *__pyx_sel
  *   convert(ifst, fst_type="")
  */
 
-static PyObject *__pyx_pw_9pywrapfst_23convert(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_25convert(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__10);
+  PyObject *__pyx_v_fst_type = ((PyObject *)__pyx_kp_b__8);
   std::string __pyx_v_fst_type_string;
   std::unique_ptr<fst::script::FstClass>  __pyx_v_tfst;
   struct __pyx_obj_9pywrapfst__Fst *__pyx_r = NULL;
@@ -36385,17 +37397,17 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_convert(struct __pyx
     }
   }
 
-  /* "pywrapfst.pyx":3415
+  /* "pywrapfst.pyx":3477
  *     FstOpError: Conversion failed.
  *   """
  *   cdef string fst_type_string = tostring(fst_type)             # <<<<<<<<<<<<<<
  *   cdef unique_ptr[fst.FstClass] tfst
  *   tfst.reset(fst.Convert(deref(ifst._fst), fst_type_string))
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_fst_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3415, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_fst_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3477, __pyx_L1_error)
   __pyx_v_fst_type_string = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3417
+  /* "pywrapfst.pyx":3479
  *   cdef string fst_type_string = tostring(fst_type)
  *   cdef unique_ptr[fst.FstClass] tfst
  *   tfst.reset(fst.Convert(deref(ifst._fst), fst_type_string))             # <<<<<<<<<<<<<<
@@ -36404,11 +37416,11 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_convert(struct __pyx
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3417, __pyx_L1_error)
+    __PYX_ERR(0, 3479, __pyx_L1_error)
   }
   __pyx_v_tfst.reset(fst::script::Convert((*__pyx_v_ifst->_fst), __pyx_v_fst_type_string));
 
-  /* "pywrapfst.pyx":3419
+  /* "pywrapfst.pyx":3481
  *   tfst.reset(fst.Convert(deref(ifst._fst), fst_type_string))
  *   # Script-land Convert returns a null pointer to signal failure.
  *   if tfst.get() == NULL:             # <<<<<<<<<<<<<<
@@ -36418,16 +37430,16 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_convert(struct __pyx
   __pyx_t_2 = ((__pyx_v_tfst.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":3420
+    /* "pywrapfst.pyx":3482
  *   # Script-land Convert returns a null pointer to signal failure.
  *   if tfst.get() == NULL:
  *     raise FstOpError("Conversion to {!r} failed".format(fst_type))             # <<<<<<<<<<<<<<
  *   return _init_XFst(tfst.release())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3420, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3482, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Conversion_to_r_failed, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3420, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Conversion_to_r_failed, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3482, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __pyx_t_7 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
@@ -36441,7 +37453,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_convert(struct __pyx
     }
     __pyx_t_5 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_v_fst_type) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_fst_type);
     __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3420, __pyx_L1_error)
+    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3482, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __pyx_t_6 = NULL;
@@ -36457,14 +37469,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_convert(struct __pyx
     __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5);
     __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3420, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3482, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 3420, __pyx_L1_error)
+    __PYX_ERR(0, 3482, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3419
+    /* "pywrapfst.pyx":3481
  *   tfst.reset(fst.Convert(deref(ifst._fst), fst_type_string))
  *   # Script-land Convert returns a null pointer to signal failure.
  *   if tfst.get() == NULL:             # <<<<<<<<<<<<<<
@@ -36473,7 +37485,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_convert(struct __pyx
  */
   }
 
-  /* "pywrapfst.pyx":3421
+  /* "pywrapfst.pyx":3483
  *   if tfst.get() == NULL:
  *     raise FstOpError("Conversion to {!r} failed".format(fst_type))
  *   return _init_XFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -36481,13 +37493,13 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_convert(struct __pyx
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3421, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3483, __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":3398
+  /* "pywrapfst.pyx":3460
  * 
  * 
  * cpdef _Fst convert(_Fst ifst, fst_type=b""):             # <<<<<<<<<<<<<<
@@ -36511,9 +37523,9 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_convert(struct __pyx
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_23convert(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_22convert[] = "\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 an empty string\n        if no conversion is desired.\n\n  Returns:\n    The input FST converted to the desired FST type.\n\n  Raises:\n    FstOpError: Conversion failed.\n  ";
-static PyObject *__pyx_pw_9pywrapfst_23convert(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_25convert(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_24convert[] = "\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 an empty string\n        if no conversion is desired.\n\n  Returns:\n    The input FST converted to the desired FST type.\n\n  Raises:\n    FstOpError: Conversion failed.\n  ";
+static PyObject *__pyx_pw_9pywrapfst_25convert(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst = 0;
   PyObject *__pyx_v_fst_type = 0;
   PyObject *__pyx_r = 0;
@@ -36522,7 +37534,7 @@ static PyObject *__pyx_pw_9pywrapfst_23convert(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__10);
+    values[1] = ((PyObject *)__pyx_kp_b__8);
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
       const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
@@ -36547,7 +37559,7 @@ static PyObject *__pyx_pw_9pywrapfst_23convert(PyObject *__pyx_self, PyObject *_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "convert") < 0)) __PYX_ERR(0, 3398, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "convert") < 0)) __PYX_ERR(0, 3460, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -36563,14 +37575,14 @@ static PyObject *__pyx_pw_9pywrapfst_23convert(PyObject *__pyx_self, PyObject *_
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("convert", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3398, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("convert", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3460, __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, 3398, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_22convert(__pyx_self, __pyx_v_ifst, __pyx_v_fst_type);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3460, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_24convert(__pyx_self, __pyx_v_ifst, __pyx_v_fst_type);
 
   /* function exit code */
   goto __pyx_L0;
@@ -36581,7 +37593,7 @@ static PyObject *__pyx_pw_9pywrapfst_23convert(PyObject *__pyx_self, PyObject *_
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_22convert(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, PyObject *__pyx_v_fst_type) {
+static PyObject *__pyx_pf_9pywrapfst_24convert(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, PyObject *__pyx_v_fst_type) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -36590,7 +37602,7 @@ static PyObject *__pyx_pf_9pywrapfst_22convert(CYTHON_UNUSED PyObject *__pyx_sel
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_2.__pyx_n = 1;
   __pyx_t_2.fst_type = __pyx_v_fst_type;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_convert(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3398, __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, 3460, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -36607,7 +37619,7 @@ static PyObject *__pyx_pf_9pywrapfst_22convert(CYTHON_UNUSED PyObject *__pyx_sel
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3424
+/* "pywrapfst.pyx":3486
  * 
  * 
  * cpdef _MutableFst determinize(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -36615,14 +37627,14 @@ static PyObject *__pyx_pf_9pywrapfst_22convert(CYTHON_UNUSED PyObject *__pyx_sel
  *                               det_type=b"functional",
  */
 
-static PyObject *__pyx_pw_9pywrapfst_25determinize(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_27determinize(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__33;
+  float __pyx_v_delta = __pyx_k__31;
   PyObject *__pyx_v_det_type = ((PyObject *)__pyx_n_b_functional);
-  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__34;
+  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__32;
   __pyx_t_10basictypes_int64 __pyx_v_subsequential_label = ((__pyx_t_10basictypes_int64)0);
 
-  /* "pywrapfst.pyx":3429
+  /* "pywrapfst.pyx":3491
  *                               int64 nstate=fst.kNoStateId,
  *                               int64 subsequential_label=0,
  *                               weight=None,             # <<<<<<<<<<<<<<
@@ -36631,7 +37643,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
  */
   PyObject *__pyx_v_weight = ((PyObject *)Py_None);
 
-  /* "pywrapfst.pyx":3430
+  /* "pywrapfst.pyx":3492
  *                               int64 subsequential_label=0,
  *                               weight=None,
  *                               bool increment_subsequential_label=False):             # <<<<<<<<<<<<<<
@@ -36675,7 +37687,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
     }
   }
 
-  /* "pywrapfst.pyx":3466
+  /* "pywrapfst.pyx":3526
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -36684,11 +37696,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3466, __pyx_L1_error)
+    __PYX_ERR(0, 3526, __pyx_L1_error)
   }
   __pyx_v_tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
 
-  /* "pywrapfst.pyx":3468
+  /* "pywrapfst.pyx":3528
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   # Threshold is set to semiring Zero (no pruning) if weight unspecified.
  *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(),             # <<<<<<<<<<<<<<
@@ -36697,29 +37709,29 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 3468, __pyx_L1_error)
+    __PYX_ERR(0, 3528, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3469
+  /* "pywrapfst.pyx":3529
  *   # 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, 3468, __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, 3528, __pyx_L1_error)
   __pyx_v_wc = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3471
+  /* "pywrapfst.pyx":3531
  *                                                      weight)
  *   cdef fst.DeterminizeType determinize_type_enum
  *   if not fst.GetDeterminizeType(tostring(det_type),             # <<<<<<<<<<<<<<
  *                                 addr(determinize_type_enum)):
  *     raise FstArgError("Unknown determinization type: {!r}".format(det_type))
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_det_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3471, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_det_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3531, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3472
+  /* "pywrapfst.pyx":3532
  *   cdef fst.DeterminizeType determinize_type_enum
  *   if not fst.GetDeterminizeType(tostring(det_type),
  *                                 addr(determinize_type_enum)):             # <<<<<<<<<<<<<<
@@ -36728,7 +37740,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":3471
+  /* "pywrapfst.pyx":3531
  *                                                      weight)
  *   cdef fst.DeterminizeType determinize_type_enum
  *   if not fst.GetDeterminizeType(tostring(det_type),             # <<<<<<<<<<<<<<
@@ -36737,16 +37749,16 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
  */
   if (unlikely(__pyx_t_3)) {
 
-    /* "pywrapfst.pyx":3473
+    /* "pywrapfst.pyx":3533
  *   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,
+ *   opts.reset(new fst.DeterminizeOptions(delta,
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3473, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3533, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Unknown_determinization_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 3473, __pyx_L1_error)
+    __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Unknown_determinization_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 3533, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_7);
     __pyx_t_8 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) {
@@ -36760,7 +37772,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
     }
     __pyx_t_6 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_8, __pyx_v_det_type) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_v_det_type);
     __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
-    if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3473, __pyx_L1_error)
+    if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3533, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     __pyx_t_7 = NULL;
@@ -36776,14 +37788,14 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
     __pyx_t_4 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_7, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6);
     __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3473, __pyx_L1_error)
+    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3533, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_Raise(__pyx_t_4, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __PYX_ERR(0, 3473, __pyx_L1_error)
+    __PYX_ERR(0, 3533, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3471
+    /* "pywrapfst.pyx":3531
  *                                                      weight)
  *   cdef fst.DeterminizeType determinize_type_enum
  *   if not fst.GetDeterminizeType(tostring(det_type),             # <<<<<<<<<<<<<<
@@ -36792,16 +37804,16 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
  */
   }
 
-  /* "pywrapfst.pyx":3475
+  /* "pywrapfst.pyx":3535
  *     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,             # <<<<<<<<<<<<<<
- *                                         determinize_type_enum,
- *                                         increment_subsequential_label))
+ *   opts.reset(new fst.DeterminizeOptions(delta,             # <<<<<<<<<<<<<<
+ *                                         wc,
+ *                                         nstate,
  */
   __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":3478
+  /* "pywrapfst.pyx":3541
  *                                         determinize_type_enum,
  *                                         increment_subsequential_label))
  *   fst.Determinize(deref(ifst._fst), tfst.get(), deref(opts))             # <<<<<<<<<<<<<<
@@ -36810,11 +37822,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3478, __pyx_L1_error)
+    __PYX_ERR(0, 3541, __pyx_L1_error)
   }
   fst::script::Determinize((*__pyx_v_ifst->_fst), __pyx_v_tfst.get(), (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":3479
+  /* "pywrapfst.pyx":3542
  *                                         increment_subsequential_label))
  *   fst.Determinize(deref(ifst._fst), tfst.get(), deref(opts))
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -36822,13 +37834,13 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_4 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3479, __pyx_L1_error)
+  __pyx_t_4 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3542, __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":3424
+  /* "pywrapfst.pyx":3486
  * 
  * 
  * cpdef _MutableFst determinize(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -36852,9 +37864,9 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_25determinize(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_24determinize[] = "\n  determinize(ifst, delta=1e-6, det_type=\"functional\",\n              nstate=NO_STATE_ID, subsequential_label=0, weight=None,\n              incremental_subsequential_label=False)\n\n  Constructively determinizes a weighted FST.\n\n  This operations creates an equivalent FST that has the property that no\n  state has two transitions with the same input label. For this algorithm,\n  epsilon transitions are treated as regular symbols (cf. `rmepsilon`).\n\n  Args:\n    ifst: The input FST.\n    delta: Comparison/quantization delta.\n    det_type: Type of determinization; one of: \"functional\" (input transducer is\n        functional), \"nonfunctional\" (input transducer is not functional) and\n        disambiguate\" (input transducer is not functional but only keep the min\n        of ambiguous outputs).\n    nstate: State number threshold.\n    subsequential_label: Input label of arc corresponding to residual final\n        output when producing a subsequential transducer.\n    weight: A Weight or weight string indicating the desired weight threshold\n        below which paths are pruned; if omitted, no paths are pruned.\n    increment_subsequential_label: Increment subsequential when creating\n        several arcs for the residual final output at a given state.\n\n  Returns:\n    An equivalent deterministic FST.\n\n  Raises:\n    FstArgError: Unknown determinization type.\n\n  See also: `disambiguate`, `rmepsilon`.\n  ";
-static PyObject *__pyx_pw_9pywrapfst_25determinize(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_27determinize(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_26determinize[] = "\n  determinize(ifst, delta=1e-6, det_type=\"functional\",\n              nstate=NO_STATE_ID, subsequential_label=0, weight=None,\n              incremental_subsequential_label=False)\n\n  Constructively determinizes a weighted FST.\n\n  This operations creates an equivalent FST that has the property that no\n  state has two transitions with the same input label. For this algorithm,\n  epsilon transitions are treated as regular symbols (cf. `rmepsilon`).\n\n  Args:\n    ifst: The input FST.\n    delta: Comparison/quantization delta.\n    det_type: Type of determinization; one of: \"functional\" (input transducer is\n        functional), \"nonfunctional\" (input transducer is not functional) and\n        disambiguate\" (input transducer is not functional but only keep the min\n        of ambiguous outputs).\n    nstate: State number threshold.\n    subsequential_label: Input label of arc corresponding to residual final\n        output when producing a subsequential transducer.\n    weight: A Weight or weight string indicating the desired weight threshold\n        below which paths are pruned; if omitted, no paths are pruned.\n    increment_subsequential_label: Increment subsequential when creating\n        several arcs for the residual final output at a given state.\n\n  Returns:\n    An equivalent deterministic FST.\n\n  Raises:\n    FstArgError: Unknown determinization type.\n  ";
+static PyObject *__pyx_pw_9pywrapfst_27determinize(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst = 0;
   float __pyx_v_delta;
   PyObject *__pyx_v_det_type = 0;
@@ -36870,7 +37882,7 @@ static PyObject *__pyx_pw_9pywrapfst_25determinize(PyObject *__pyx_self, PyObjec
     PyObject* values[7] = {0,0,0,0,0,0,0};
     values[2] = ((PyObject *)__pyx_n_b_functional);
 
-    /* "pywrapfst.pyx":3429
+    /* "pywrapfst.pyx":3491
  *                               int64 nstate=fst.kNoStateId,
  *                               int64 subsequential_label=0,
  *                               weight=None,             # <<<<<<<<<<<<<<
@@ -36942,7 +37954,7 @@ static PyObject *__pyx_pw_9pywrapfst_25determinize(PyObject *__pyx_self, PyObjec
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "determinize") < 0)) __PYX_ERR(0, 3424, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "determinize") < 0)) __PYX_ERR(0, 3486, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -36965,27 +37977,27 @@ static PyObject *__pyx_pw_9pywrapfst_25determinize(PyObject *__pyx_self, PyObjec
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
     if (values[1]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3425, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3487, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__33;
+      __pyx_v_delta = __pyx_k__31;
     }
     __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, 3427, __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, 3489, __pyx_L3_error)
     } else {
-      __pyx_v_nstate = __pyx_k__34;
+      __pyx_v_nstate = __pyx_k__32;
     }
     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, 3428, __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, 3490, __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, 3430, __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, 3492, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3430
+      /* "pywrapfst.pyx":3492
  *                               int64 subsequential_label=0,
  *                               weight=None,
  *                               bool increment_subsequential_label=False):             # <<<<<<<<<<<<<<
@@ -36997,16 +38009,16 @@ static PyObject *__pyx_pw_9pywrapfst_25determinize(PyObject *__pyx_self, PyObjec
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("determinize", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3424, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("determinize", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3486, __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, 3424, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_24determinize(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_det_type, __pyx_v_nstate, __pyx_v_subsequential_label, __pyx_v_weight, __pyx_v_increment_subsequential_label);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3486, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_26determinize(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_det_type, __pyx_v_nstate, __pyx_v_subsequential_label, __pyx_v_weight, __pyx_v_increment_subsequential_label);
 
-  /* "pywrapfst.pyx":3424
+  /* "pywrapfst.pyx":3486
  * 
  * 
  * cpdef _MutableFst determinize(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -37023,7 +38035,7 @@ static PyObject *__pyx_pw_9pywrapfst_25determinize(PyObject *__pyx_self, PyObjec
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_24determinize(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, PyObject *__pyx_v_det_type, __pyx_t_10basictypes_int64 __pyx_v_nstate, __pyx_t_10basictypes_int64 __pyx_v_subsequential_label, PyObject *__pyx_v_weight, bool __pyx_v_increment_subsequential_label) {
+static PyObject *__pyx_pf_9pywrapfst_26determinize(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, PyObject *__pyx_v_det_type, __pyx_t_10basictypes_int64 __pyx_v_nstate, __pyx_t_10basictypes_int64 __pyx_v_subsequential_label, PyObject *__pyx_v_weight, bool __pyx_v_increment_subsequential_label) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -37037,7 +38049,7 @@ static PyObject *__pyx_pf_9pywrapfst_24determinize(CYTHON_UNUSED PyObject *__pyx
   __pyx_t_2.subsequential_label = __pyx_v_subsequential_label;
   __pyx_t_2.weight = __pyx_v_weight;
   __pyx_t_2.increment_subsequential_label = __pyx_v_increment_subsequential_label;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_determinize(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3424, __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, 3486, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -37054,7 +38066,7 @@ static PyObject *__pyx_pf_9pywrapfst_24determinize(CYTHON_UNUSED PyObject *__pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3482
+/* "pywrapfst.pyx":3545
  * 
  * 
  * cpdef _MutableFst difference(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -37062,11 +38074,11 @@ static PyObject *__pyx_pf_9pywrapfst_24determinize(CYTHON_UNUSED PyObject *__pyx
  *                              compose_filter=b"auto",
  */
 
-static PyObject *__pyx_pw_9pywrapfst_27difference(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_29difference(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 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":3485
+  /* "pywrapfst.pyx":3548
  *                              _Fst ifst2,
  *                              compose_filter=b"auto",
  *                              bool connect=True):             # <<<<<<<<<<<<<<
@@ -37091,70 +38103,70 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_difference(st
     }
   }
 
-  /* "pywrapfst.pyx":3510
+  /* "pywrapfst.pyx":3573
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))             # <<<<<<<<<<<<<<
  *   cdef unique_ptr[fst.ComposeOptions] opts
- *   opts.reset(new fst.ComposeOptions(connect, _get_compose_filter(
+ *   opts.reset(new fst.ComposeOptions(
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3510, __pyx_L1_error)
+    __PYX_ERR(0, 3573, __pyx_L1_error)
   }
   __pyx_v_tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst1->__pyx_vtab)->arc_type(__pyx_v_ifst1, 0)));
 
-  /* "pywrapfst.pyx":3513
- *   cdef unique_ptr[fst.ComposeOptions] opts
- *   opts.reset(new fst.ComposeOptions(connect, _get_compose_filter(
- *       tostring(compose_filter))))             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":3577
+ *   opts.reset(new fst.ComposeOptions(
+ *       connect,
+ *       _get_compose_filter(tostring(compose_filter))))             # <<<<<<<<<<<<<<
  *   fst.Difference(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))
  *   return _init_MutableFst(tfst.release())
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_compose_filter); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3513, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_compose_filter); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3577, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3577, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3512
+  /* "pywrapfst.pyx":3575
  *   tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))
  *   cdef unique_ptr[fst.ComposeOptions] opts
- *   opts.reset(new fst.ComposeOptions(connect, _get_compose_filter(             # <<<<<<<<<<<<<<
- *       tostring(compose_filter))))
- *   fst.Difference(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))
+ *   opts.reset(new fst.ComposeOptions(             # <<<<<<<<<<<<<<
+ *       connect,
+ *       _get_compose_filter(tostring(compose_filter))))
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3512, __pyx_L1_error)
   __pyx_v_opts.reset(new fst::ComposeOptions(__pyx_v_connect, __pyx_t_2));
 
-  /* "pywrapfst.pyx":3514
- *   opts.reset(new fst.ComposeOptions(connect, _get_compose_filter(
- *       tostring(compose_filter))))
+  /* "pywrapfst.pyx":3578
+ *       connect,
+ *       _get_compose_filter(tostring(compose_filter))))
  *   fst.Difference(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))             # <<<<<<<<<<<<<<
  *   return _init_MutableFst(tfst.release())
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3514, __pyx_L1_error)
+    __PYX_ERR(0, 3578, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ifst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3514, __pyx_L1_error)
+    __PYX_ERR(0, 3578, __pyx_L1_error)
   }
   fst::script::Difference((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_tfst.get(), (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":3515
- *       tostring(compose_filter))))
+  /* "pywrapfst.pyx":3579
+ *       _get_compose_filter(tostring(compose_filter))))
  *   fst.Difference(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3515, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3579, __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":3482
+  /* "pywrapfst.pyx":3545
  * 
  * 
  * cpdef _MutableFst difference(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -37174,9 +38186,9 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_difference(st
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_27difference(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_26difference[] = "\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\", \"no_match\", \"null\", \"sequence\",\n        \"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_27difference(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_29difference(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_28difference[] = "\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\", \"no_match\", \"null\", \"sequence\",\n        \"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_29difference(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;
   PyObject *__pyx_v_compose_filter = 0;
@@ -37212,7 +38224,7 @@ static PyObject *__pyx_pw_9pywrapfst_27difference(PyObject *__pyx_self, PyObject
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ifst2)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("difference", 0, 2, 4, 1); __PYX_ERR(0, 3482, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("difference", 0, 2, 4, 1); __PYX_ERR(0, 3545, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -37228,7 +38240,7 @@ static PyObject *__pyx_pw_9pywrapfst_27difference(PyObject *__pyx_self, PyObject
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "difference") < 0)) __PYX_ERR(0, 3482, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "difference") < 0)) __PYX_ERR(0, 3545, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -37246,10 +38258,10 @@ static PyObject *__pyx_pw_9pywrapfst_27difference(PyObject *__pyx_self, PyObject
     __pyx_v_ifst2 = ((struct __pyx_obj_9pywrapfst__Fst *)values[1]);
     __pyx_v_compose_filter = values[2];
     if (values[3]) {
-      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3485, __pyx_L3_error)
+      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3548, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3485
+      /* "pywrapfst.pyx":3548
  *                              _Fst ifst2,
  *                              compose_filter=b"auto",
  *                              bool connect=True):             # <<<<<<<<<<<<<<
@@ -37261,17 +38273,17 @@ static PyObject *__pyx_pw_9pywrapfst_27difference(PyObject *__pyx_self, PyObject
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("difference", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3482, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("difference", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3545, __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, 3482, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3483, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_26difference(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_compose_filter, __pyx_v_connect);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst__Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3545, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3546, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_28difference(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_compose_filter, __pyx_v_connect);
 
-  /* "pywrapfst.pyx":3482
+  /* "pywrapfst.pyx":3545
  * 
  * 
  * cpdef _MutableFst difference(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -37288,7 +38300,7 @@ static PyObject *__pyx_pw_9pywrapfst_27difference(PyObject *__pyx_self, PyObject
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_26difference(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, PyObject *__pyx_v_compose_filter, bool __pyx_v_connect) {
+static PyObject *__pyx_pf_9pywrapfst_28difference(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, PyObject *__pyx_v_compose_filter, bool __pyx_v_connect) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -37298,7 +38310,7 @@ static PyObject *__pyx_pf_9pywrapfst_26difference(CYTHON_UNUSED PyObject *__pyx_
   __pyx_t_2.__pyx_n = 2;
   __pyx_t_2.compose_filter = __pyx_v_compose_filter;
   __pyx_t_2.connect = __pyx_v_connect;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_difference(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3482, __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, 3545, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -37315,7 +38327,7 @@ static PyObject *__pyx_pf_9pywrapfst_26difference(CYTHON_UNUSED PyObject *__pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3518
+/* "pywrapfst.pyx":3582
  * 
  * 
  * cpdef _MutableFst disambiguate(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -37323,13 +38335,13 @@ static PyObject *__pyx_pf_9pywrapfst_26difference(CYTHON_UNUSED PyObject *__pyx_
  *                                int64 nstate=fst.kNoStateId,
  */
 
-static PyObject *__pyx_pw_9pywrapfst_29disambiguate(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_31disambiguate(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__35;
-  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__36;
+  float __pyx_v_delta = __pyx_k__33;
+  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__34;
   __pyx_t_10basictypes_int64 __pyx_v_subsequential_label = ((__pyx_t_10basictypes_int64)0);
 
-  /* "pywrapfst.pyx":3522
+  /* "pywrapfst.pyx":3586
  *                                int64 nstate=fst.kNoStateId,
  *                                int64 subsequential_label=0,
  *                                weight=None):             # <<<<<<<<<<<<<<
@@ -37360,7 +38372,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_disambiguate(
     }
   }
 
-  /* "pywrapfst.pyx":3549
+  /* "pywrapfst.pyx":3611
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -37369,11 +38381,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_disambiguate(
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3549, __pyx_L1_error)
+    __PYX_ERR(0, 3611, __pyx_L1_error)
   }
   __pyx_v_tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
 
-  /* "pywrapfst.pyx":3551
+  /* "pywrapfst.pyx":3613
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   # Threshold is set to semiring Zero (no pruning) if no weight is specified.
  *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(),             # <<<<<<<<<<<<<<
@@ -37382,30 +38394,30 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_disambiguate(
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 3551, __pyx_L1_error)
+    __PYX_ERR(0, 3613, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3552
+  /* "pywrapfst.pyx":3614
  *   # 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,
+ *   opts.reset(new fst.DisambiguateOptions(delta,
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_Zero(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3551, __pyx_L1_error)
+  __pyx_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, 3613, __pyx_L1_error)
   __pyx_v_wc = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3554
+  /* "pywrapfst.pyx":3616
  *                                                      weight)
  *   cdef unique_ptr[fst.DisambiguateOptions] opts
- *   opts.reset(new fst.DisambiguateOptions(delta, wc, nstate,             # <<<<<<<<<<<<<<
- *                                          subsequential_label))
- *   fst.Disambiguate(deref(ifst._fst), tfst.get(), deref(opts))
+ *   opts.reset(new fst.DisambiguateOptions(delta,             # <<<<<<<<<<<<<<
+ *                                          wc,
+ *                                          nstate,
  */
   __pyx_v_opts.reset(new fst::script::DisambiguateOptions(__pyx_v_delta, __pyx_v_wc, __pyx_v_nstate, __pyx_v_subsequential_label));
 
-  /* "pywrapfst.pyx":3556
- *   opts.reset(new fst.DisambiguateOptions(delta, wc, nstate,
+  /* "pywrapfst.pyx":3620
+ *                                          nstate,
  *                                          subsequential_label))
  *   fst.Disambiguate(deref(ifst._fst), tfst.get(), deref(opts))             # <<<<<<<<<<<<<<
  *   return _init_MutableFst(tfst.release())
@@ -37413,11 +38425,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_disambiguate(
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3556, __pyx_L1_error)
+    __PYX_ERR(0, 3620, __pyx_L1_error)
   }
   fst::script::Disambiguate((*__pyx_v_ifst->_fst), __pyx_v_tfst.get(), (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":3557
+  /* "pywrapfst.pyx":3621
  *                                          subsequential_label))
  *   fst.Disambiguate(deref(ifst._fst), tfst.get(), deref(opts))
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -37425,13 +38437,13 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_disambiguate(
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3557, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3621, __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":3518
+  /* "pywrapfst.pyx":3582
  * 
  * 
  * cpdef _MutableFst disambiguate(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -37451,9 +38463,9 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_disambiguate(
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_29disambiguate(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_28disambiguate[] = "\n  disambiguate(ifst, delta=0.0009765625, nstate=NO_STATE_ID,\n               subsequential_label=0, weight=None):\n\n  Constructively disambiguates a weighted transducer.\n\n  This operation disambiguates a weighted transducer. The result will be an\n  equivalent FST that has the property that no two successful paths have the\n  same input labeling. For this algorithm, epsilon transitions are treated as\n  regular symbols (cf. `rmepsilon`).\n\n  Args:\n    ifst: The input FST.\n    delta: Comparison/quantization delta.\n    nstate: State number threshold.\n    subsequential_label: Input label of arc corresponding to residual final\n        output when producing a subsequential transducer.\n    weight: A Weight or weight string indicating the desired weight threshold\n        below which paths are pruned; if omitted, no paths are pruned.\n\n  Returns:\n    An equivalent disambiguated FST.\n\n  See also: `determinize`, `rmepsilon`.\n  ";
-static PyObject *__pyx_pw_9pywrapfst_29disambiguate(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_31disambiguate(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_30disambiguate[] = "\n  disambiguate(ifst, delta=0.0009765625, nstate=NO_STATE_ID,\n               subsequential_label=0, weight=None):\n\n  Constructively disambiguates a weighted transducer.\n\n  This operation disambiguates a weighted transducer. The result will be an\n  equivalent FST that has the property that no two successful paths have the\n  same input labeling. For this algorithm, epsilon transitions are treated as\n  regular symbols (cf. `rmepsilon`).\n\n  Args:\n    ifst: The input FST.\n    delta: Comparison/quantization delta.\n    nstate: State number threshold.\n    subsequential_label: Input label of arc corresponding to residual final\n        output when producing a subsequential transducer.\n    weight: A Weight or weight string indicating the desired weight threshold\n        below which paths are pruned; if omitted, no paths are pruned.\n\n  Returns:\n    An equivalent disambiguated FST.\n  ";
+static PyObject *__pyx_pw_9pywrapfst_31disambiguate(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst = 0;
   float __pyx_v_delta;
   __pyx_t_10basictypes_int64 __pyx_v_nstate;
@@ -37466,7 +38478,7 @@ static PyObject *__pyx_pw_9pywrapfst_29disambiguate(PyObject *__pyx_self, PyObje
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_ifst,&__pyx_n_s_delta,&__pyx_n_s_nstate,&__pyx_n_s_subsequential_label,&__pyx_n_s_weight,0};
     PyObject* values[5] = {0,0,0,0,0};
 
-    /* "pywrapfst.pyx":3522
+    /* "pywrapfst.pyx":3586
  *                                int64 nstate=fst.kNoStateId,
  *                                int64 subsequential_label=0,
  *                                weight=None):             # <<<<<<<<<<<<<<
@@ -37522,7 +38534,7 @@ static PyObject *__pyx_pw_9pywrapfst_29disambiguate(PyObject *__pyx_self, PyObje
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "disambiguate") < 0)) __PYX_ERR(0, 3518, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "disambiguate") < 0)) __PYX_ERR(0, 3582, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -37541,17 +38553,17 @@ static PyObject *__pyx_pw_9pywrapfst_29disambiguate(PyObject *__pyx_self, PyObje
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
     if (values[1]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3519, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3583, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__35;
+      __pyx_v_delta = __pyx_k__33;
     }
     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, 3520, __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, 3584, __pyx_L3_error)
     } else {
-      __pyx_v_nstate = __pyx_k__36;
+      __pyx_v_nstate = __pyx_k__34;
     }
     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, 3521, __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, 3585, __pyx_L3_error)
     } else {
       __pyx_v_subsequential_label = ((__pyx_t_10basictypes_int64)0);
     }
@@ -37559,16 +38571,16 @@ static PyObject *__pyx_pw_9pywrapfst_29disambiguate(PyObject *__pyx_self, PyObje
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("disambiguate", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3518, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("disambiguate", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3582, __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, 3518, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_28disambiguate(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_nstate, __pyx_v_subsequential_label, __pyx_v_weight);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3582, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_30disambiguate(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_nstate, __pyx_v_subsequential_label, __pyx_v_weight);
 
-  /* "pywrapfst.pyx":3518
+  /* "pywrapfst.pyx":3582
  * 
  * 
  * cpdef _MutableFst disambiguate(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -37585,7 +38597,7 @@ static PyObject *__pyx_pw_9pywrapfst_29disambiguate(PyObject *__pyx_self, PyObje
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_28disambiguate(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, __pyx_t_10basictypes_int64 __pyx_v_nstate, __pyx_t_10basictypes_int64 __pyx_v_subsequential_label, PyObject *__pyx_v_weight) {
+static PyObject *__pyx_pf_9pywrapfst_30disambiguate(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, __pyx_t_10basictypes_int64 __pyx_v_nstate, __pyx_t_10basictypes_int64 __pyx_v_subsequential_label, PyObject *__pyx_v_weight) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -37597,7 +38609,7 @@ static PyObject *__pyx_pf_9pywrapfst_28disambiguate(CYTHON_UNUSED PyObject *__py
   __pyx_t_2.nstate = __pyx_v_nstate;
   __pyx_t_2.subsequential_label = __pyx_v_subsequential_label;
   __pyx_t_2.weight = __pyx_v_weight;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_disambiguate(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3518, __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, 3582, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -37614,7 +38626,7 @@ static PyObject *__pyx_pf_9pywrapfst_28disambiguate(CYTHON_UNUSED PyObject *__py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3560
+/* "pywrapfst.pyx":3624
  * 
  * 
  * cpdef _MutableFst epsnormalize(_Fst ifst, bool eps_norm_output=False):             # <<<<<<<<<<<<<<
@@ -37622,7 +38634,7 @@ static PyObject *__pyx_pf_9pywrapfst_28disambiguate(CYTHON_UNUSED PyObject *__py
  *   epsnormalize(ifst, eps_norm_output=False)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_31epsnormalize(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_33epsnormalize(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_epsnormalize(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_epsnormalize *__pyx_optional_args) {
   bool __pyx_v_eps_norm_output = ((bool)0);
   std::unique_ptr<fst::script::VectorFstClass>  __pyx_v_tfst;
@@ -37637,84 +38649,68 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_epsnormalize(
     }
   }
 
-  /* "pywrapfst.pyx":3583
+  /* "pywrapfst.pyx":3645
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
- *   fst.EpsNormalize(deref(ifst._fst), tfst.get(), fst.EPS_NORM_OUTPUT if
- *                                                  eps_norm_output else
+ *   fst.EpsNormalize(
+ *       deref(ifst._fst),
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3583, __pyx_L1_error)
+    __PYX_ERR(0, 3645, __pyx_L1_error)
   }
   __pyx_v_tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
 
-  /* "pywrapfst.pyx":3584
- *   cdef unique_ptr[fst.VectorFstClass] tfst
+  /* "pywrapfst.pyx":3647
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
- *   fst.EpsNormalize(deref(ifst._fst), tfst.get(), fst.EPS_NORM_OUTPUT if             # <<<<<<<<<<<<<<
- *                                                  eps_norm_output else
- *                                                  fst.EPS_NORM_INPUT)
+ *   fst.EpsNormalize(
+ *       deref(ifst._fst),             # <<<<<<<<<<<<<<
+ *       tfst.get(),
+ *       fst.EPS_NORM_OUTPUT if eps_norm_output else fst.EPS_NORM_INPUT)
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3584, __pyx_L1_error)
+    __PYX_ERR(0, 3647, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3585
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
- *   fst.EpsNormalize(deref(ifst._fst), tfst.get(), fst.EPS_NORM_OUTPUT if
- *                                                  eps_norm_output else             # <<<<<<<<<<<<<<
- *                                                  fst.EPS_NORM_INPUT)
+  /* "pywrapfst.pyx":3649
+ *       deref(ifst._fst),
+ *       tfst.get(),
+ *       fst.EPS_NORM_OUTPUT if eps_norm_output else fst.EPS_NORM_INPUT)             # <<<<<<<<<<<<<<
  *   return _init_MutableFst(tfst.release())
+ * 
  */
   if ((__pyx_v_eps_norm_output != 0)) {
-
-    /* "pywrapfst.pyx":3584
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
- *   fst.EpsNormalize(deref(ifst._fst), tfst.get(), fst.EPS_NORM_OUTPUT if             # <<<<<<<<<<<<<<
- *                                                  eps_norm_output else
- *                                                  fst.EPS_NORM_INPUT)
- */
     __pyx_t_1 = fst::EPS_NORM_OUTPUT;
   } else {
-
-    /* "pywrapfst.pyx":3586
- *   fst.EpsNormalize(deref(ifst._fst), tfst.get(), fst.EPS_NORM_OUTPUT if
- *                                                  eps_norm_output else
- *                                                  fst.EPS_NORM_INPUT)             # <<<<<<<<<<<<<<
- *   return _init_MutableFst(tfst.release())
- * 
- */
     __pyx_t_1 = fst::EPS_NORM_INPUT;
   }
 
-  /* "pywrapfst.pyx":3584
+  /* "pywrapfst.pyx":3646
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
- *   fst.EpsNormalize(deref(ifst._fst), tfst.get(), fst.EPS_NORM_OUTPUT if             # <<<<<<<<<<<<<<
- *                                                  eps_norm_output else
- *                                                  fst.EPS_NORM_INPUT)
+ *   fst.EpsNormalize(             # <<<<<<<<<<<<<<
+ *       deref(ifst._fst),
+ *       tfst.get(),
  */
   fst::script::EpsNormalize((*__pyx_v_ifst->_fst), __pyx_v_tfst.get(), __pyx_t_1);
 
-  /* "pywrapfst.pyx":3587
- *                                                  eps_norm_output else
- *                                                  fst.EPS_NORM_INPUT)
+  /* "pywrapfst.pyx":3650
+ *       tfst.get(),
+ *       fst.EPS_NORM_OUTPUT if eps_norm_output else fst.EPS_NORM_INPUT)
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3587, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3650, __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":3560
+  /* "pywrapfst.pyx":3624
  * 
  * 
  * cpdef _MutableFst epsnormalize(_Fst ifst, bool eps_norm_output=False):             # <<<<<<<<<<<<<<
@@ -37734,9 +38730,9 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_epsnormalize(
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_31epsnormalize(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_30epsnormalize[] = "\n  epsnormalize(ifst, eps_norm_output=False)\n\n  Constructively epsilon-normalizes an FST.\n\n  This operation creates an equivalent FST that is epsilon-normalized. An\n  acceptor is epsilon-normalized if it it is epsilon-removed (cf. `rmepsilon`).\n  A transducer is input epsilon-normalized if, in addition, along any path, all\n  arcs with epsilon input labels follow all arcs with non-epsilon input labels.\n  Output epsilon-normalized is defined similarly. The input FST must be\n  functional.\n\n  Args:\n    ifst: The input FST.\n    eps_norm_output: Should the FST be output epsilon-normalized?\n\n  Returns:\n    An equivalent epsilon-normalized FST.\n\n  See also: `rmepsilon`.\n  ";
-static PyObject *__pyx_pw_9pywrapfst_31epsnormalize(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_33epsnormalize(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_32epsnormalize[] = "\n  epsnormalize(ifst, eps_norm_output=False)\n\n  Constructively epsilon-normalizes an FST.\n\n  This operation creates an equivalent FST that is epsilon-normalized. An\n  acceptor is epsilon-normalized if it it is epsilon-removed (cf. `rmepsilon`).\n  A transducer is input epsilon-normalized if, in addition, along any path, all\n  arcs with epsilon input labels follow all arcs with non-epsilon input labels.\n  Output epsilon-normalized is defined similarly. The input FST must be\n  functional.\n\n  Args:\n    ifst: The input FST.\n    eps_norm_output: Should the FST be output epsilon-normalized?\n\n  Returns:\n    An equivalent epsilon-normalized FST.\n  ";
+static PyObject *__pyx_pw_9pywrapfst_33epsnormalize(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst = 0;
   bool __pyx_v_eps_norm_output;
   PyObject *__pyx_r = 0;
@@ -37769,7 +38765,7 @@ static PyObject *__pyx_pw_9pywrapfst_31epsnormalize(PyObject *__pyx_self, PyObje
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "epsnormalize") < 0)) __PYX_ERR(0, 3560, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "epsnormalize") < 0)) __PYX_ERR(0, 3624, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -37782,21 +38778,21 @@ static PyObject *__pyx_pw_9pywrapfst_31epsnormalize(PyObject *__pyx_self, PyObje
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
     if (values[1]) {
-      __pyx_v_eps_norm_output = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_eps_norm_output == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3560, __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, 3624, __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, 3560, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("epsnormalize", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3624, __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, 3560, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_30epsnormalize(__pyx_self, __pyx_v_ifst, __pyx_v_eps_norm_output);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3624, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_32epsnormalize(__pyx_self, __pyx_v_ifst, __pyx_v_eps_norm_output);
 
   /* function exit code */
   goto __pyx_L0;
@@ -37807,7 +38803,7 @@ static PyObject *__pyx_pw_9pywrapfst_31epsnormalize(PyObject *__pyx_self, PyObje
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_30epsnormalize(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, bool __pyx_v_eps_norm_output) {
+static PyObject *__pyx_pf_9pywrapfst_32epsnormalize(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, bool __pyx_v_eps_norm_output) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -37816,7 +38812,7 @@ static PyObject *__pyx_pf_9pywrapfst_30epsnormalize(CYTHON_UNUSED PyObject *__py
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_2.__pyx_n = 1;
   __pyx_t_2.eps_norm_output = __pyx_v_eps_norm_output;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_epsnormalize(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3560, __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, 3624, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -37833,7 +38829,7 @@ static PyObject *__pyx_pf_9pywrapfst_30epsnormalize(CYTHON_UNUSED PyObject *__py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3590
+/* "pywrapfst.pyx":3653
  * 
  * 
  * cpdef bool equal(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
@@ -37841,9 +38837,9 @@ static PyObject *__pyx_pf_9pywrapfst_30epsnormalize(CYTHON_UNUSED PyObject *__py
  *   equal(ifst1, ifst2, delta=0.0009765625)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_33equal(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_35equal(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__37;
+  float __pyx_v_delta = __pyx_k__35;
   bool __pyx_r;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("equal", 0);
@@ -37853,8 +38849,8 @@ static bool __pyx_f_9pywrapfst_equal(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_i
     }
   }
 
-  /* "pywrapfst.pyx":3610
- *   See also: `equivalent`, `isomorphic`, `randequivalent`.
+  /* "pywrapfst.pyx":3671
+ *     True if the FSTs satisfy the above condition, else False.
  *   """
  *   return fst.Equal(deref(ifst1._fst), deref(ifst2._fst), delta)             # <<<<<<<<<<<<<<
  * 
@@ -37862,16 +38858,16 @@ static bool __pyx_f_9pywrapfst_equal(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_i
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3610, __pyx_L1_error)
+    __PYX_ERR(0, 3671, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ifst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3610, __pyx_L1_error)
+    __PYX_ERR(0, 3671, __pyx_L1_error)
   }
   __pyx_r = fst::script::Equal((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_delta);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3590
+  /* "pywrapfst.pyx":3653
  * 
  * 
  * cpdef bool equal(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
@@ -37889,9 +38885,9 @@ static bool __pyx_f_9pywrapfst_equal(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_i
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_33equal(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_32equal[] = "\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_33equal(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_35equal(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_34equal[] = "\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  ";
+static PyObject *__pyx_pw_9pywrapfst_35equal(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;
   float __pyx_v_delta;
@@ -37923,7 +38919,7 @@ static PyObject *__pyx_pw_9pywrapfst_33equal(PyObject *__pyx_self, PyObject *__p
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ifst2)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("equal", 0, 2, 3, 1); __PYX_ERR(0, 3590, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("equal", 0, 2, 3, 1); __PYX_ERR(0, 3653, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -37933,7 +38929,7 @@ static PyObject *__pyx_pw_9pywrapfst_33equal(PyObject *__pyx_self, PyObject *__p
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "equal") < 0)) __PYX_ERR(0, 3590, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "equal") < 0)) __PYX_ERR(0, 3653, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -37948,22 +38944,22 @@ static PyObject *__pyx_pw_9pywrapfst_33equal(PyObject *__pyx_self, PyObject *__p
     __pyx_v_ifst1 = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
     __pyx_v_ifst2 = ((struct __pyx_obj_9pywrapfst__Fst *)values[1]);
     if (values[2]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3590, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3653, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__37;
+      __pyx_v_delta = __pyx_k__35;
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("equal", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3590, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("equal", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3653, __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, 3590, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3590, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_32equal(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_delta);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst__Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3653, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3653, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_34equal(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_delta);
 
   /* function exit code */
   goto __pyx_L0;
@@ -37974,7 +38970,7 @@ static PyObject *__pyx_pw_9pywrapfst_33equal(PyObject *__pyx_self, PyObject *__p
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_32equal(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, float __pyx_v_delta) {
+static PyObject *__pyx_pf_9pywrapfst_34equal(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, float __pyx_v_delta) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   bool __pyx_t_1;
@@ -37985,7 +38981,7 @@ static PyObject *__pyx_pf_9pywrapfst_32equal(CYTHON_UNUSED PyObject *__pyx_self,
   __pyx_t_2.__pyx_n = 1;
   __pyx_t_2.delta = __pyx_v_delta;
   __pyx_t_1 = __pyx_f_9pywrapfst_equal(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2); 
-  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3590, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3653, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -38002,7 +38998,7 @@ static PyObject *__pyx_pf_9pywrapfst_32equal(CYTHON_UNUSED PyObject *__pyx_self,
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3613
+/* "pywrapfst.pyx":3674
  * 
  * 
  * cpdef bool equivalent(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta) except *:             # <<<<<<<<<<<<<<
@@ -38010,9 +39006,9 @@ static PyObject *__pyx_pf_9pywrapfst_32equal(CYTHON_UNUSED PyObject *__pyx_self,
  *   equivalent(ifst1, ifst2, delta=0.0009765625)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_35equivalent(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_37equivalent(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__38;
+  float __pyx_v_delta = __pyx_k__36;
   bool __pyx_r;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("equivalent", 0);
@@ -38022,8 +39018,8 @@ static bool __pyx_f_9pywrapfst_equivalent(struct __pyx_obj_9pywrapfst__Fst *__py
     }
   }
 
-  /* "pywrapfst.pyx":3633
- *   See also: `equal`, `isomorphic`, `randequivalent`.
+  /* "pywrapfst.pyx":3692
+ *     True if the FSTs satisfy the above condition, else False.
  *   """
  *   return fst.Equivalent(deref(ifst1._fst), deref(ifst2._fst), delta)             # <<<<<<<<<<<<<<
  * 
@@ -38031,16 +39027,16 @@ static bool __pyx_f_9pywrapfst_equivalent(struct __pyx_obj_9pywrapfst__Fst *__py
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3633, __pyx_L1_error)
+    __PYX_ERR(0, 3692, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ifst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3633, __pyx_L1_error)
+    __PYX_ERR(0, 3692, __pyx_L1_error)
   }
   __pyx_r = fst::script::Equivalent((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_delta);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3613
+  /* "pywrapfst.pyx":3674
  * 
  * 
  * cpdef bool equivalent(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta) except *:             # <<<<<<<<<<<<<<
@@ -38058,9 +39054,9 @@ static bool __pyx_f_9pywrapfst_equivalent(struct __pyx_obj_9pywrapfst__Fst *__py
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_35equivalent(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_34equivalent[] = "\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  See also: `equal`, `isomorphic`, `randequivalent`.\n  ";
-static PyObject *__pyx_pw_9pywrapfst_35equivalent(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_37equivalent(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_36equivalent[] = "\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  ";
+static PyObject *__pyx_pw_9pywrapfst_37equivalent(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;
   float __pyx_v_delta;
@@ -38092,7 +39088,7 @@ static PyObject *__pyx_pw_9pywrapfst_35equivalent(PyObject *__pyx_self, PyObject
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ifst2)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("equivalent", 0, 2, 3, 1); __PYX_ERR(0, 3613, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("equivalent", 0, 2, 3, 1); __PYX_ERR(0, 3674, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -38102,7 +39098,7 @@ static PyObject *__pyx_pw_9pywrapfst_35equivalent(PyObject *__pyx_self, PyObject
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "equivalent") < 0)) __PYX_ERR(0, 3613, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "equivalent") < 0)) __PYX_ERR(0, 3674, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -38117,22 +39113,22 @@ static PyObject *__pyx_pw_9pywrapfst_35equivalent(PyObject *__pyx_self, PyObject
     __pyx_v_ifst1 = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
     __pyx_v_ifst2 = ((struct __pyx_obj_9pywrapfst__Fst *)values[1]);
     if (values[2]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3613, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3674, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__38;
+      __pyx_v_delta = __pyx_k__36;
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("equivalent", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3613, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("equivalent", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3674, __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, 3613, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3613, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_34equivalent(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_delta);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst__Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3674, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3674, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_36equivalent(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_delta);
 
   /* function exit code */
   goto __pyx_L0;
@@ -38143,7 +39139,7 @@ static PyObject *__pyx_pw_9pywrapfst_35equivalent(PyObject *__pyx_self, PyObject
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_34equivalent(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, float __pyx_v_delta) {
+static PyObject *__pyx_pf_9pywrapfst_36equivalent(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, float __pyx_v_delta) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   bool __pyx_t_1;
@@ -38153,8 +39149,8 @@ static PyObject *__pyx_pf_9pywrapfst_34equivalent(CYTHON_UNUSED PyObject *__pyx_
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_2.__pyx_n = 1;
   __pyx_t_2.delta = __pyx_v_delta;
-  __pyx_t_1 = __pyx_f_9pywrapfst_equivalent(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2); if (unlikely(__pyx_t_1 == ((bool)-1) && PyErr_Occurred())) __PYX_ERR(0, 3613, __pyx_L1_error)
-  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3613, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_equivalent(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2); if (unlikely(__pyx_t_1 == ((bool)-1) && PyErr_Occurred())) __PYX_ERR(0, 3674, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3674, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -38171,7 +39167,7 @@ static PyObject *__pyx_pf_9pywrapfst_34equivalent(CYTHON_UNUSED PyObject *__pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3636
+/* "pywrapfst.pyx":3695
  * 
  * 
  * cpdef _MutableFst intersect(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -38179,11 +39175,11 @@ static PyObject *__pyx_pf_9pywrapfst_34equivalent(CYTHON_UNUSED PyObject *__pyx_
  *                             compose_filter=b"auto",
  */
 
-static PyObject *__pyx_pw_9pywrapfst_37intersect(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_39intersect(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 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":3639
+  /* "pywrapfst.pyx":3698
  *                             _Fst ifst2,
  *                             compose_filter=b"auto",
  *                             bool connect=True):             # <<<<<<<<<<<<<<
@@ -38208,70 +39204,70 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_intersect(str
     }
   }
 
-  /* "pywrapfst.pyx":3662
+  /* "pywrapfst.pyx":3721
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))             # <<<<<<<<<<<<<<
  *   cdef unique_ptr[fst.ComposeOptions] opts
- *   opts.reset(new fst.ComposeOptions(connect,
+ *   opts.reset(new fst.ComposeOptions(
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3662, __pyx_L1_error)
+    __PYX_ERR(0, 3721, __pyx_L1_error)
   }
   __pyx_v_tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst1->__pyx_vtab)->arc_type(__pyx_v_ifst1, 0)));
 
-  /* "pywrapfst.pyx":3665
- *   cdef unique_ptr[fst.ComposeOptions] opts
- *   opts.reset(new fst.ComposeOptions(connect,
- *         _get_compose_filter(tostring(compose_filter))))             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":3725
+ *   opts.reset(new fst.ComposeOptions(
+ *       connect,
+ *       _get_compose_filter(tostring(compose_filter))))             # <<<<<<<<<<<<<<
  *   fst.Intersect(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))
  *   return _init_MutableFst(tfst.release())
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_compose_filter); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3665, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3665, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_compose_filter); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3725, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3725, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3664
+  /* "pywrapfst.pyx":3723
  *   tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))
  *   cdef unique_ptr[fst.ComposeOptions] opts
- *   opts.reset(new fst.ComposeOptions(connect,             # <<<<<<<<<<<<<<
- *         _get_compose_filter(tostring(compose_filter))))
- *   fst.Intersect(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))
+ *   opts.reset(new fst.ComposeOptions(             # <<<<<<<<<<<<<<
+ *       connect,
+ *       _get_compose_filter(tostring(compose_filter))))
  */
   __pyx_v_opts.reset(new fst::ComposeOptions(__pyx_v_connect, __pyx_t_2));
 
-  /* "pywrapfst.pyx":3666
- *   opts.reset(new fst.ComposeOptions(connect,
- *         _get_compose_filter(tostring(compose_filter))))
+  /* "pywrapfst.pyx":3726
+ *       connect,
+ *       _get_compose_filter(tostring(compose_filter))))
  *   fst.Intersect(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))             # <<<<<<<<<<<<<<
  *   return _init_MutableFst(tfst.release())
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3666, __pyx_L1_error)
+    __PYX_ERR(0, 3726, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ifst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3666, __pyx_L1_error)
+    __PYX_ERR(0, 3726, __pyx_L1_error)
   }
   fst::script::Intersect((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_tfst.get(), (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":3667
- *         _get_compose_filter(tostring(compose_filter))))
+  /* "pywrapfst.pyx":3727
+ *       _get_compose_filter(tostring(compose_filter))))
  *   fst.Intersect(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3667, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3727, __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":3636
+  /* "pywrapfst.pyx":3695
  * 
  * 
  * cpdef _MutableFst intersect(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -38291,9 +39287,9 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_intersect(str
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_37intersect(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_36intersect[] = "\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\", \"no_match\", \"null\", \"sequence\",\n        \"trivial\".\n    connect: Should output be trimmed?\n\n  Returns:\n    An intersected FST.\n  ";
-static PyObject *__pyx_pw_9pywrapfst_37intersect(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_39intersect(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_38intersect[] = "\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\", \"no_match\", \"null\", \"sequence\",\n        \"trivial\".\n    connect: Should output be trimmed?\n\n  Returns:\n    An intersected FST.\n  ";
+static PyObject *__pyx_pw_9pywrapfst_39intersect(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;
   PyObject *__pyx_v_compose_filter = 0;
@@ -38329,7 +39325,7 @@ static PyObject *__pyx_pw_9pywrapfst_37intersect(PyObject *__pyx_self, PyObject
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ifst2)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("intersect", 0, 2, 4, 1); __PYX_ERR(0, 3636, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("intersect", 0, 2, 4, 1); __PYX_ERR(0, 3695, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -38345,7 +39341,7 @@ static PyObject *__pyx_pw_9pywrapfst_37intersect(PyObject *__pyx_self, PyObject
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "intersect") < 0)) __PYX_ERR(0, 3636, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "intersect") < 0)) __PYX_ERR(0, 3695, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -38363,10 +39359,10 @@ static PyObject *__pyx_pw_9pywrapfst_37intersect(PyObject *__pyx_self, PyObject
     __pyx_v_ifst2 = ((struct __pyx_obj_9pywrapfst__Fst *)values[1]);
     __pyx_v_compose_filter = values[2];
     if (values[3]) {
-      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3639, __pyx_L3_error)
+      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3698, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3639
+      /* "pywrapfst.pyx":3698
  *                             _Fst ifst2,
  *                             compose_filter=b"auto",
  *                             bool connect=True):             # <<<<<<<<<<<<<<
@@ -38378,17 +39374,17 @@ static PyObject *__pyx_pw_9pywrapfst_37intersect(PyObject *__pyx_self, PyObject
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("intersect", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3636, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("intersect", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3695, __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, 3636, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3637, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_36intersect(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_compose_filter, __pyx_v_connect);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst__Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3695, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3696, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_38intersect(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_compose_filter, __pyx_v_connect);
 
-  /* "pywrapfst.pyx":3636
+  /* "pywrapfst.pyx":3695
  * 
  * 
  * cpdef _MutableFst intersect(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -38405,7 +39401,7 @@ static PyObject *__pyx_pw_9pywrapfst_37intersect(PyObject *__pyx_self, PyObject
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_36intersect(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, PyObject *__pyx_v_compose_filter, bool __pyx_v_connect) {
+static PyObject *__pyx_pf_9pywrapfst_38intersect(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, PyObject *__pyx_v_compose_filter, bool __pyx_v_connect) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -38415,7 +39411,7 @@ static PyObject *__pyx_pf_9pywrapfst_36intersect(CYTHON_UNUSED PyObject *__pyx_s
   __pyx_t_2.__pyx_n = 2;
   __pyx_t_2.compose_filter = __pyx_v_compose_filter;
   __pyx_t_2.connect = __pyx_v_connect;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_intersect(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3636, __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, 3695, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -38432,7 +39428,7 @@ static PyObject *__pyx_pf_9pywrapfst_36intersect(CYTHON_UNUSED PyObject *__pyx_s
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3670
+/* "pywrapfst.pyx":3730
  * 
  * 
  * cpdef bool isomorphic(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
@@ -38440,9 +39436,9 @@ static PyObject *__pyx_pf_9pywrapfst_36intersect(CYTHON_UNUSED PyObject *__pyx_s
  *   isomorphic(ifst1, ifst2, delta=0.0009765625)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_39isomorphic(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_41isomorphic(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__39;
+  float __pyx_v_delta = __pyx_k__37;
   bool __pyx_r;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("isomorphic", 0);
@@ -38452,8 +39448,8 @@ static bool __pyx_f_9pywrapfst_isomorphic(struct __pyx_obj_9pywrapfst__Fst *__py
     }
   }
 
-  /* "pywrapfst.pyx":3693
- *   See also: `equal`, `equivalent`, `randequivalent`.
+  /* "pywrapfst.pyx":3751
+ *     True if the two transducers satisfy the above condition, else False.
  *   """
  *   return fst.Isomorphic(deref(ifst1._fst), deref(ifst2._fst), delta)             # <<<<<<<<<<<<<<
  * 
@@ -38461,16 +39457,16 @@ static bool __pyx_f_9pywrapfst_isomorphic(struct __pyx_obj_9pywrapfst__Fst *__py
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3693, __pyx_L1_error)
+    __PYX_ERR(0, 3751, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ifst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3693, __pyx_L1_error)
+    __PYX_ERR(0, 3751, __pyx_L1_error)
   }
   __pyx_r = fst::script::Isomorphic((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_delta);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3670
+  /* "pywrapfst.pyx":3730
  * 
  * 
  * cpdef bool isomorphic(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
@@ -38488,9 +39484,9 @@ static bool __pyx_f_9pywrapfst_isomorphic(struct __pyx_obj_9pywrapfst__Fst *__py
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_39isomorphic(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_38isomorphic[] = "\n  isomorphic(ifst1, ifst2, delta=0.0009765625)\n\n  Are the two acceptors isomorphic?\n\n  This operation determines if two transducers with a certain required\n  determinism have the same states, irrespective of numbering, and the same\n  transitions with the same labels and weights, irrespective of ordering. In\n  other words, FSTs A, B are isomorphic if and only if the states of A can be\n  renumbered and the transitions leaving each state reordered so the two are\n  equal (according to the definition given in `equal`).\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: `equal`, `equivalent`, `randequivalent`.\n  ";
-static PyObject *__pyx_pw_9pywrapfst_39isomorphic(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_41isomorphic(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_40isomorphic[] = "\n  isomorphic(ifst1, ifst2, delta=0.0009765625)\n\n  Are the two acceptors isomorphic?\n\n  This operation determines if two transducers with a certain required\n  determinism have the same states, irrespective of numbering, and the same\n  transitions with the same labels and weights, irrespective of ordering. In\n  other words, FSTs A, B are isomorphic if and only if the states of A can be\n  renumbered and the transitions leaving each state reordered so the two are\n  equal (according to the definition given in `equal`).\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  ";
+static PyObject *__pyx_pw_9pywrapfst_41isomorphic(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;
   float __pyx_v_delta;
@@ -38522,7 +39518,7 @@ static PyObject *__pyx_pw_9pywrapfst_39isomorphic(PyObject *__pyx_self, PyObject
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ifst2)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("isomorphic", 0, 2, 3, 1); __PYX_ERR(0, 3670, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("isomorphic", 0, 2, 3, 1); __PYX_ERR(0, 3730, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -38532,7 +39528,7 @@ static PyObject *__pyx_pw_9pywrapfst_39isomorphic(PyObject *__pyx_self, PyObject
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "isomorphic") < 0)) __PYX_ERR(0, 3670, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "isomorphic") < 0)) __PYX_ERR(0, 3730, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -38547,22 +39543,22 @@ static PyObject *__pyx_pw_9pywrapfst_39isomorphic(PyObject *__pyx_self, PyObject
     __pyx_v_ifst1 = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
     __pyx_v_ifst2 = ((struct __pyx_obj_9pywrapfst__Fst *)values[1]);
     if (values[2]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3670, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3730, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__39;
+      __pyx_v_delta = __pyx_k__37;
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("isomorphic", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3670, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("isomorphic", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3730, __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, 3670, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3670, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_38isomorphic(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_delta);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst__Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3730, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3730, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_40isomorphic(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_delta);
 
   /* function exit code */
   goto __pyx_L0;
@@ -38573,7 +39569,7 @@ static PyObject *__pyx_pw_9pywrapfst_39isomorphic(PyObject *__pyx_self, PyObject
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_38isomorphic(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, float __pyx_v_delta) {
+static PyObject *__pyx_pf_9pywrapfst_40isomorphic(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, float __pyx_v_delta) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   bool __pyx_t_1;
@@ -38584,7 +39580,7 @@ static PyObject *__pyx_pf_9pywrapfst_38isomorphic(CYTHON_UNUSED PyObject *__pyx_
   __pyx_t_2.__pyx_n = 1;
   __pyx_t_2.delta = __pyx_v_delta;
   __pyx_t_1 = __pyx_f_9pywrapfst_isomorphic(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2); 
-  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3670, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3730, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -38601,7 +39597,7 @@ static PyObject *__pyx_pf_9pywrapfst_38isomorphic(CYTHON_UNUSED PyObject *__pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3696
+/* "pywrapfst.pyx":3754
  * 
  * 
  * cpdef _MutableFst prune(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -38609,12 +39605,12 @@ static PyObject *__pyx_pf_9pywrapfst_38isomorphic(CYTHON_UNUSED PyObject *__pyx_
  *                         int64 nstate=fst.kNoStateId,
  */
 
-static PyObject *__pyx_pw_9pywrapfst_41prune(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_43prune(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__40;
-  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__41;
+  float __pyx_v_delta = __pyx_k__38;
+  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__39;
 
-  /* "pywrapfst.pyx":3699
+  /* "pywrapfst.pyx":3757
  *                         float delta=fst.kDelta,
  *                         int64 nstate=fst.kNoStateId,
  *                         weight=None):             # <<<<<<<<<<<<<<
@@ -38641,7 +39637,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_prune(struct
     }
   }
 
-  /* "pywrapfst.pyx":3723
+  /* "pywrapfst.pyx":3779
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -38650,11 +39646,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_prune(struct
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3723, __pyx_L1_error)
+    __PYX_ERR(0, 3779, __pyx_L1_error)
   }
   __pyx_v_tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
 
-  /* "pywrapfst.pyx":3724
+  /* "pywrapfst.pyx":3780
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)             # <<<<<<<<<<<<<<
@@ -38663,12 +39659,12 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_prune(struct
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 3724, __pyx_L1_error)
+    __PYX_ERR(0, 3780, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_Zero(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3724, __pyx_L1_error)
+  __pyx_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, 3780, __pyx_L1_error)
   __pyx_v_wc = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3725
+  /* "pywrapfst.pyx":3781
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)
  *   fst.Prune(deref(ifst._fst), tfst.get(), wc, nstate, delta)             # <<<<<<<<<<<<<<
@@ -38677,11 +39673,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_prune(struct
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3725, __pyx_L1_error)
+    __PYX_ERR(0, 3781, __pyx_L1_error)
   }
   fst::script::Prune((*__pyx_v_ifst->_fst), __pyx_v_tfst.get(), __pyx_v_wc, __pyx_v_nstate, __pyx_v_delta);
 
-  /* "pywrapfst.pyx":3726
+  /* "pywrapfst.pyx":3782
  *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)
  *   fst.Prune(deref(ifst._fst), tfst.get(), wc, nstate, delta)
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -38689,13 +39685,13 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_prune(struct
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3726, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3782, __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":3696
+  /* "pywrapfst.pyx":3754
  * 
  * 
  * cpdef _MutableFst prune(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -38715,9 +39711,9 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_prune(struct
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_41prune(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_40prune[] = "\n  prune(ifst, delta=0.0009765625, nstate=NO_STATE_ID, weight=None)\n\n  Constructively removes paths with weights below a certain threshold.\n\n  This operation deletes states and arcs in the input FST that do not belong\n  to a successful path whose weight is no more (w.r.t the natural semiring\n  order) than the threshold t \\otimes-times the weight of the shortest path in\n  the input FST. Weights must be commutative and have the path property.\n\n  Args:\n    ifst: The input FST.\n    delta: Comparison/quantization delta.\n    nstate: State number threshold.\n    weight: A Weight or weight string indicating the desired weight threshold\n        below which paths are pruned; if omitted, no paths are pruned.\n\n  Returns:\n    A pruned FST.\n\n  See also: The destructive variant.\n  ";
-static PyObject *__pyx_pw_9pywrapfst_41prune(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_43prune(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_42prune[] = "\n  prune(ifst, delta=0.0009765625, nstate=NO_STATE_ID, weight=None)\n\n  Constructively removes paths with weights below a certain threshold.\n\n  This operation deletes states and arcs in the input FST that do not belong\n  to a successful path whose weight is no more (w.r.t the natural semiring\n  order) than the threshold t \\otimes-times the weight of the shortest path in\n  the input FST. Weights must be commutative and have the path property.\n\n  Args:\n    ifst: The input FST.\n    delta: Comparison/quantization delta.\n    nstate: State number threshold.\n    weight: A Weight or weight string indicating the desired weight threshold\n        below which paths are pruned; if omitted, no paths are pruned.\n\n  Returns:\n    A pruned FST.\n  ";
+static PyObject *__pyx_pw_9pywrapfst_43prune(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst = 0;
   float __pyx_v_delta;
   __pyx_t_10basictypes_int64 __pyx_v_nstate;
@@ -38729,7 +39725,7 @@ static PyObject *__pyx_pw_9pywrapfst_41prune(PyObject *__pyx_self, PyObject *__p
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_ifst,&__pyx_n_s_delta,&__pyx_n_s_nstate,&__pyx_n_s_weight,0};
     PyObject* values[4] = {0,0,0,0};
 
-    /* "pywrapfst.pyx":3699
+    /* "pywrapfst.pyx":3757
  *                         float delta=fst.kDelta,
  *                         int64 nstate=fst.kNoStateId,
  *                         weight=None):             # <<<<<<<<<<<<<<
@@ -38777,7 +39773,7 @@ static PyObject *__pyx_pw_9pywrapfst_41prune(PyObject *__pyx_self, PyObject *__p
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "prune") < 0)) __PYX_ERR(0, 3696, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "prune") < 0)) __PYX_ERR(0, 3754, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -38794,29 +39790,29 @@ static PyObject *__pyx_pw_9pywrapfst_41prune(PyObject *__pyx_self, PyObject *__p
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
     if (values[1]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3697, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3755, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__40;
+      __pyx_v_delta = __pyx_k__38;
     }
     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, 3698, __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, 3756, __pyx_L3_error)
     } else {
-      __pyx_v_nstate = __pyx_k__41;
+      __pyx_v_nstate = __pyx_k__39;
     }
     __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, 3696, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("prune", 0, 1, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3754, __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, 3696, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_40prune(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_nstate, __pyx_v_weight);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3754, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_42prune(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_nstate, __pyx_v_weight);
 
-  /* "pywrapfst.pyx":3696
+  /* "pywrapfst.pyx":3754
  * 
  * 
  * cpdef _MutableFst prune(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -38833,7 +39829,7 @@ static PyObject *__pyx_pw_9pywrapfst_41prune(PyObject *__pyx_self, PyObject *__p
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_40prune(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, __pyx_t_10basictypes_int64 __pyx_v_nstate, PyObject *__pyx_v_weight) {
+static PyObject *__pyx_pf_9pywrapfst_42prune(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, __pyx_t_10basictypes_int64 __pyx_v_nstate, PyObject *__pyx_v_weight) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -38844,7 +39840,7 @@ static PyObject *__pyx_pf_9pywrapfst_40prune(CYTHON_UNUSED PyObject *__pyx_self,
   __pyx_t_2.delta = __pyx_v_delta;
   __pyx_t_2.nstate = __pyx_v_nstate;
   __pyx_t_2.weight = __pyx_v_weight;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_prune(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3696, __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, 3754, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -38861,7 +39857,7 @@ static PyObject *__pyx_pf_9pywrapfst_40prune(CYTHON_UNUSED PyObject *__pyx_self,
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3729
+/* "pywrapfst.pyx":3785
  * 
  * 
  * cpdef _MutableFst push(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -38869,11 +39865,11 @@ static PyObject *__pyx_pf_9pywrapfst_40prune(CYTHON_UNUSED PyObject *__pyx_self,
  *                        bool push_weights=False,
  */
 
-static PyObject *__pyx_pw_9pywrapfst_43push(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_45push(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__42;
+  float __pyx_v_delta = __pyx_k__40;
 
-  /* "pywrapfst.pyx":3731
+  /* "pywrapfst.pyx":3787
  * cpdef _MutableFst push(_Fst ifst,
  *                        float delta=fst.kDelta,
  *                        bool push_weights=False,             # <<<<<<<<<<<<<<
@@ -38882,7 +39878,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_push(struct _
  */
   bool __pyx_v_push_weights = ((bool)0);
 
-  /* "pywrapfst.pyx":3732
+  /* "pywrapfst.pyx":3788
  *                        float delta=fst.kDelta,
  *                        bool push_weights=False,
  *                        bool push_labels=False,             # <<<<<<<<<<<<<<
@@ -38891,7 +39887,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_push(struct _
  */
   bool __pyx_v_push_labels = ((bool)0);
 
-  /* "pywrapfst.pyx":3733
+  /* "pywrapfst.pyx":3789
  *                        bool push_weights=False,
  *                        bool push_labels=False,
  *                        bool remove_common_affix=False,             # <<<<<<<<<<<<<<
@@ -38900,7 +39896,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_push(struct _
  */
   bool __pyx_v_remove_common_affix = ((bool)0);
 
-  /* "pywrapfst.pyx":3734
+  /* "pywrapfst.pyx":3790
  *                        bool push_labels=False,
  *                        bool remove_common_affix=False,
  *                        bool remove_total_weight=False,             # <<<<<<<<<<<<<<
@@ -38909,7 +39905,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_push(struct _
  */
   bool __pyx_v_remove_total_weight = ((bool)0);
 
-  /* "pywrapfst.pyx":3735
+  /* "pywrapfst.pyx":3791
  *                        bool remove_common_affix=False,
  *                        bool remove_total_weight=False,
  *                        bool to_final=False):             # <<<<<<<<<<<<<<
@@ -38918,7 +39914,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_push(struct _
  */
   bool __pyx_v_to_final = ((bool)0);
   std::unique_ptr<fst::script::VectorFstClass>  __pyx_v_tfst;
-  __pyx_t_10basictypes_uint32 __pyx_v_flags;
+  __pyx_t_10basictypes_uint8 __pyx_v_flags;
   struct __pyx_obj_9pywrapfst__MutableFst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -38944,64 +39940,64 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_push(struct _
     }
   }
 
-  /* "pywrapfst.pyx":3775
+  /* "pywrapfst.pyx":3829
  *   # This is copied, almost verbatim, from nlp/fst/bin/fstpush.cc.
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
- *   cdef uint32 flags = fst.GetPushFlags(push_weights, push_labels,
- *                                        remove_common_affix, remove_total_weight)
+ *   cdef uint8 flags = fst.GetPushFlags(push_weights,
+ *                                       push_labels,
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3775, __pyx_L1_error)
+    __PYX_ERR(0, 3829, __pyx_L1_error)
   }
   __pyx_v_tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
 
-  /* "pywrapfst.pyx":3776
+  /* "pywrapfst.pyx":3830
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
- *   cdef uint32 flags = fst.GetPushFlags(push_weights, push_labels,             # <<<<<<<<<<<<<<
- *                                        remove_common_affix, remove_total_weight)
- *   fst.Push(deref(ifst._fst), tfst.get(), flags, fst.GetReweightType(to_final),
+ *   cdef uint8 flags = fst.GetPushFlags(push_weights,             # <<<<<<<<<<<<<<
+ *                                       push_labels,
+ *                                       remove_common_affix,
  */
   __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":3778
- *   cdef uint32 flags = fst.GetPushFlags(push_weights, push_labels,
- *                                        remove_common_affix, remove_total_weight)
- *   fst.Push(deref(ifst._fst), tfst.get(), flags, fst.GetReweightType(to_final),             # <<<<<<<<<<<<<<
- *            delta)
- *   return _init_MutableFst(tfst.release())
+  /* "pywrapfst.pyx":3834
+ *                                       remove_common_affix,
+ *                                       remove_total_weight)
+ *   fst.Push(deref(ifst._fst),             # <<<<<<<<<<<<<<
+ *            tfst.get(),
+ *            flags,
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3778, __pyx_L1_error)
+    __PYX_ERR(0, 3834, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3779
- *                                        remove_common_affix, remove_total_weight)
- *   fst.Push(deref(ifst._fst), tfst.get(), flags, fst.GetReweightType(to_final),
+  /* "pywrapfst.pyx":3838
+ *            flags,
+ *            fst.GetReweightType(to_final),
  *            delta)             # <<<<<<<<<<<<<<
  *   return _init_MutableFst(tfst.release())
  * 
  */
   fst::script::Push((*__pyx_v_ifst->_fst), __pyx_v_tfst.get(), __pyx_v_flags, fst::script::GetReweightType(__pyx_v_to_final), __pyx_v_delta);
 
-  /* "pywrapfst.pyx":3780
- *   fst.Push(deref(ifst._fst), tfst.get(), flags, fst.GetReweightType(to_final),
+  /* "pywrapfst.pyx":3839
+ *            fst.GetReweightType(to_final),
  *            delta)
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3780, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3839, __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":3729
+  /* "pywrapfst.pyx":3785
  * 
  * 
  * cpdef _MutableFst push(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -39021,9 +40017,9 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_push(struct _
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_43push(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_42push[] = "\n  push(ifst, delta=0.0009765625, push_weights=False, push_labels=False,\n       remove_common_affix=False, remove_total_weight=False, to_final=False)\n\n  Constructively pushes weights/labels towards initial or final states.\n\n  This operation produces an equivalent transducer by pushing the weights\n  and/or the labels towards the initial state or toward the final states.\n\n  When pushing weights towards the initial state, the sum of the weight of the\n  outgoing transitions and final weight at any non-initial state is equal to 1\n  in the resulting machine. When pushing weights towards the final states, the\n  sum of the weight of the incoming transitions at any state is equal to 1.\n  Weights need to be left distributive when pushing towards the initial state\n  and right distributive when pushing towards the final states.\n\n  Pushing labels towards the initial state consists in minimizing at every\n  state the length of the longest common prefix of the output labels of the\n  outgoing paths. Pushing labels towards the final states consists in\n  minimizing at every state the length of the longest common suffix of the\n  output labels of the incoming paths.\n\n  Args:\n    ifst: The input FST.\n    delta: Comparison/quantization delta.\n    push_weights: Should weights be pushed?\n    push_labels: Should labels be pushed?\n    remove_common_affix: If pushing labels, should common prefix/suffix be\n        removed?\n    remove_total_weight: If pushing weights, should total weight be removed?\n    to_final: Push towards final states?\n\n  Returns:\n    An equivalent pushed FST.\n\n  See also: The destructive variant.\n  ";
-static PyObject *__pyx_pw_9pywrapfst_43push(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_45push(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_44push[] = "\n  push(ifst, delta=0.0009765625, push_weights=False, push_labels=False,\n       remove_common_affix=False, remove_total_weight=False, to_final=False)\n\n  Constructively pushes weights/labels towards initial or final states.\n\n  This operation produces an equivalent transducer by pushing the weights\n  and/or the labels towards the initial state or toward the final states.\n\n  When pushing weights towards the initial state, the sum of the weight of the\n  outgoing transitions and final weight at any non-initial state is equal to 1\n  in the resulting machine. When pushing weights towards the final states, the\n  sum of the weight of the incoming transitions at any state is equal to 1.\n  Weights need to be left distributive when pushing towards the initial state\n  and right distributive when pushing towards the final states.\n\n  Pushing labels towards the initial state consists in minimizing at every\n  state the length of the longest common prefix of the output labels of the\n  outgoing paths. Pushing labels towards the final states consists in\n  minimizing at every state the length of the longest common suffix of the\n  output labels of the incoming paths.\n\n  Args:\n    ifst: The input FST.\n    delta: Comparison/quantization delta.\n    push_weights: Should weights be pushed?\n    push_labels: Should labels be pushed?\n    remove_common_affix: If pushing labels, should common prefix/suffix be\n        removed?\n    remove_total_weight: If pushing weights, should total weight be removed?\n    to_final: Push towards final states?\n\n  Returns:\n    An equivalent pushed FST.\n  ";
+static PyObject *__pyx_pw_9pywrapfst_45push(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst = 0;
   float __pyx_v_delta;
   bool __pyx_v_push_weights;
@@ -39101,7 +40097,7 @@ static PyObject *__pyx_pw_9pywrapfst_43push(PyObject *__pyx_self, PyObject *__py
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "push") < 0)) __PYX_ERR(0, 3729, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "push") < 0)) __PYX_ERR(0, 3785, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -39124,15 +40120,15 @@ static PyObject *__pyx_pw_9pywrapfst_43push(PyObject *__pyx_self, PyObject *__py
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
     if (values[1]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3730, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3786, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__42;
+      __pyx_v_delta = __pyx_k__40;
     }
     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, 3731, __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, 3787, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3731
+      /* "pywrapfst.pyx":3787
  * cpdef _MutableFst push(_Fst ifst,
  *                        float delta=fst.kDelta,
  *                        bool push_weights=False,             # <<<<<<<<<<<<<<
@@ -39142,10 +40138,10 @@ static PyObject *__pyx_pw_9pywrapfst_43push(PyObject *__pyx_self, PyObject *__py
       __pyx_v_push_weights = ((bool)0);
     }
     if (values[3]) {
-      __pyx_v_push_labels = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_push_labels == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3732, __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, 3788, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3732
+      /* "pywrapfst.pyx":3788
  *                        float delta=fst.kDelta,
  *                        bool push_weights=False,
  *                        bool push_labels=False,             # <<<<<<<<<<<<<<
@@ -39155,10 +40151,10 @@ static PyObject *__pyx_pw_9pywrapfst_43push(PyObject *__pyx_self, PyObject *__py
       __pyx_v_push_labels = ((bool)0);
     }
     if (values[4]) {
-      __pyx_v_remove_common_affix = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_remove_common_affix == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3733, __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, 3789, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3733
+      /* "pywrapfst.pyx":3789
  *                        bool push_weights=False,
  *                        bool push_labels=False,
  *                        bool remove_common_affix=False,             # <<<<<<<<<<<<<<
@@ -39168,10 +40164,10 @@ static PyObject *__pyx_pw_9pywrapfst_43push(PyObject *__pyx_self, PyObject *__py
       __pyx_v_remove_common_affix = ((bool)0);
     }
     if (values[5]) {
-      __pyx_v_remove_total_weight = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_remove_total_weight == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3734, __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, 3790, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3734
+      /* "pywrapfst.pyx":3790
  *                        bool push_labels=False,
  *                        bool remove_common_affix=False,
  *                        bool remove_total_weight=False,             # <<<<<<<<<<<<<<
@@ -39181,10 +40177,10 @@ static PyObject *__pyx_pw_9pywrapfst_43push(PyObject *__pyx_self, PyObject *__py
       __pyx_v_remove_total_weight = ((bool)0);
     }
     if (values[6]) {
-      __pyx_v_to_final = __Pyx_PyObject_IsTrue(values[6]); if (unlikely((__pyx_v_to_final == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3735, __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, 3791, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3735
+      /* "pywrapfst.pyx":3791
  *                        bool remove_common_affix=False,
  *                        bool remove_total_weight=False,
  *                        bool to_final=False):             # <<<<<<<<<<<<<<
@@ -39196,16 +40192,16 @@ static PyObject *__pyx_pw_9pywrapfst_43push(PyObject *__pyx_self, PyObject *__py
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("push", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3729, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("push", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3785, __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, 3729, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_42push(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_push_weights, __pyx_v_push_labels, __pyx_v_remove_common_affix, __pyx_v_remove_total_weight, __pyx_v_to_final);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3785, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_44push(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_push_weights, __pyx_v_push_labels, __pyx_v_remove_common_affix, __pyx_v_remove_total_weight, __pyx_v_to_final);
 
-  /* "pywrapfst.pyx":3729
+  /* "pywrapfst.pyx":3785
  * 
  * 
  * cpdef _MutableFst push(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -39222,7 +40218,7 @@ static PyObject *__pyx_pw_9pywrapfst_43push(PyObject *__pyx_self, PyObject *__py
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_42push(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, bool __pyx_v_push_weights, bool __pyx_v_push_labels, bool __pyx_v_remove_common_affix, bool __pyx_v_remove_total_weight, bool __pyx_v_to_final) {
+static PyObject *__pyx_pf_9pywrapfst_44push(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, bool __pyx_v_push_weights, bool __pyx_v_push_labels, bool __pyx_v_remove_common_affix, bool __pyx_v_remove_total_weight, bool __pyx_v_to_final) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -39236,7 +40232,7 @@ static PyObject *__pyx_pf_9pywrapfst_42push(CYTHON_UNUSED PyObject *__pyx_self,
   __pyx_t_2.remove_common_affix = __pyx_v_remove_common_affix;
   __pyx_t_2.remove_total_weight = __pyx_v_remove_total_weight;
   __pyx_t_2.to_final = __pyx_v_to_final;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_push(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3729, __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, 3785, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -39253,7 +40249,7 @@ static PyObject *__pyx_pf_9pywrapfst_42push(CYTHON_UNUSED PyObject *__pyx_self,
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3783
+/* "pywrapfst.pyx":3842
  * 
  * 
  * cpdef bool randequivalent(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -39261,13 +40257,13 @@ static PyObject *__pyx_pf_9pywrapfst_42push(CYTHON_UNUSED PyObject *__pyx_self,
  *                           int32 npath=1,
  */
 
-static PyObject *__pyx_pw_9pywrapfst_45randequivalent(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_47randequivalent(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__43;
+  float __pyx_v_delta = __pyx_k__41;
   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__44;
+  __pyx_t_10basictypes_int32 __pyx_v_max_length = __pyx_k__42;
   enum fst::script::RandArcSelection __pyx_v_ras;
   std::unique_ptr<fst::RandGenOptions<enum fst::script::RandArcSelection> >  __pyx_v_opts;
   bool __pyx_r;
@@ -39294,81 +40290,89 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst__Fst *
     }
   }
 
-  /* "pywrapfst.pyx":3818
- *   See also: `equal`, `equivalent`, `isomorphic`, `randgen`.
+  /* "pywrapfst.pyx":3875
+ *     True if the two transducers satisfy the above condition, else False.
  *   """
  *   cdef fst.RandArcSelection ras = _get_rand_arc_selection(tostring(select))             # <<<<<<<<<<<<<<
  *   cdef unique_ptr[fst.RandGenOptions[fst.RandArcSelection]] opts
  *   # The three trailing options will be ignored by RandEquivalent.
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_select); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3818, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_rand_arc_selection(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3818, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_select); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3875, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst__get_rand_arc_selection(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3875, __pyx_L1_error)
   __pyx_v_ras = __pyx_t_2;
 
-  /* "pywrapfst.pyx":3821
+  /* "pywrapfst.pyx":3878
  *   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,             # <<<<<<<<<<<<<<
- *                                                           1, False, False))
- *   if seed == 0:
+ *   opts.reset(new fst.RandGenOptions[fst.RandArcSelection](ras,             # <<<<<<<<<<<<<<
+ *                                                           max_length,
+ *                                                           1,
  */
   __pyx_v_opts.reset(new fst::RandGenOptions<enum fst::script::RandArcSelection> (__pyx_v_ras, __pyx_v_max_length, 1, 0, 0));
 
-  /* "pywrapfst.pyx":3823
- *   opts.reset(new fst.RandGenOptions[fst.RandArcSelection](ras, max_length,
- *                                                           1, False, False))
+  /* "pywrapfst.pyx":3883
+ *                                                           False,
+ *                                                           False))
  *   if seed == 0:             # <<<<<<<<<<<<<<
  *     seed = time(NULL) + getpid()
- *   return fst.RandEquivalent(deref(ifst1._fst), deref(ifst2._fst), npath, delta,
+ *   return fst.RandEquivalent(deref(ifst1._fst),
  */
   __pyx_t_3 = ((__pyx_v_seed == 0) != 0);
   if (__pyx_t_3) {
 
-    /* "pywrapfst.pyx":3824
- *                                                           1, False, False))
+    /* "pywrapfst.pyx":3884
+ *                                                           False))
  *   if seed == 0:
  *     seed = time(NULL) + getpid()             # <<<<<<<<<<<<<<
- *   return fst.RandEquivalent(deref(ifst1._fst), deref(ifst2._fst), npath, delta,
- *                            seed, deref(opts))
+ *   return fst.RandEquivalent(deref(ifst1._fst),
+ *                             deref(ifst2._fst),
  */
     __pyx_v_seed = (time(NULL) + getpid());
 
-    /* "pywrapfst.pyx":3823
- *   opts.reset(new fst.RandGenOptions[fst.RandArcSelection](ras, max_length,
- *                                                           1, False, False))
+    /* "pywrapfst.pyx":3883
+ *                                                           False,
+ *                                                           False))
  *   if seed == 0:             # <<<<<<<<<<<<<<
  *     seed = time(NULL) + getpid()
- *   return fst.RandEquivalent(deref(ifst1._fst), deref(ifst2._fst), npath, delta,
+ *   return fst.RandEquivalent(deref(ifst1._fst),
  */
   }
 
-  /* "pywrapfst.pyx":3825
+  /* "pywrapfst.pyx":3885
  *   if seed == 0:
  *     seed = time(NULL) + getpid()
- *   return fst.RandEquivalent(deref(ifst1._fst), deref(ifst2._fst), npath, delta,             # <<<<<<<<<<<<<<
- *                            seed, deref(opts))
- * 
+ *   return fst.RandEquivalent(deref(ifst1._fst),             # <<<<<<<<<<<<<<
+ *                             deref(ifst2._fst),
+ *                             npath,
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3825, __pyx_L1_error)
+    __PYX_ERR(0, 3885, __pyx_L1_error)
   }
+
+  /* "pywrapfst.pyx":3886
+ *     seed = time(NULL) + getpid()
+ *   return fst.RandEquivalent(deref(ifst1._fst),
+ *                             deref(ifst2._fst),             # <<<<<<<<<<<<<<
+ *                             npath,
+ *                             delta,
+ */
   if (unlikely(((PyObject *)__pyx_v_ifst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3825, __pyx_L1_error)
+    __PYX_ERR(0, 3886, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3826
+  /* "pywrapfst.pyx":3885
+ *   if seed == 0:
  *     seed = time(NULL) + getpid()
- *   return fst.RandEquivalent(deref(ifst1._fst), deref(ifst2._fst), npath, delta,
- *                            seed, deref(opts))             # <<<<<<<<<<<<<<
- * 
- * 
+ *   return fst.RandEquivalent(deref(ifst1._fst),             # <<<<<<<<<<<<<<
+ *                             deref(ifst2._fst),
+ *                             npath,
  */
   __pyx_r = fst::script::RandEquivalent((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_npath, __pyx_v_delta, __pyx_v_seed, (*__pyx_v_opts));
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3783
+  /* "pywrapfst.pyx":3842
  * 
  * 
  * cpdef bool randequivalent(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -39386,9 +40390,9 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst__Fst *
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_45randequivalent(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_44randequivalent[] = "\n  randequivalent(ifst1, ifst2, npath=1, delta=0.0009765625, seed=0,\n                 select=\"uniform\", max_length=2147483647)\n\n  Are two acceptors stochastically equivalent?\n\n  This operation tests whether two FSTs are equivalent by randomly generating\n  paths alternatively in each of the two FSTs. For each randomly generated path,\n  the algorithm computes for each of the two FSTs the sum of the weights of all\n  the successful paths sharing the same input and output labels as the randomly\n  generated path and checks that these two values are within `delta`.\n\n  Args:\n    ifst1: The first input FST.\n    ifst2: The second input FST.\n    npath: The number of random paths to generate.\n    delta: Comparison/quantization delta.\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\n  Returns:\n    True if the two transducers satisfy the above condition, else False.\n\n  See also: `equal`, `equivalent`, `isomorphic`, `randgen`.\n  ";
-static PyObject *__pyx_pw_9pywrapfst_45randequivalent(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_47randequivalent(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_46randequivalent[] = "\n  randequivalent(ifst1, ifst2, npath=1, delta=0.0009765625, seed=0,\n                 select=\"uniform\", max_length=2147483647)\n\n  Are two acceptors stochastically equivalent?\n\n  This operation tests whether two FSTs are equivalent by randomly generating\n  paths alternatively in each of the two FSTs. For each randomly generated path,\n  the algorithm computes for each of the two FSTs the sum of the weights of all\n  the successful paths sharing the same input and output labels as the randomly\n  generated path and checks that these two values are within `delta`.\n\n  Args:\n    ifst1: The first input FST.\n    ifst2: The second input FST.\n    npath: The number of random paths to generate.\n    delta: Comparison/quantization delta.\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\n  Returns:\n    True if the two transducers satisfy the above condition, else False.\n  ";
+static PyObject *__pyx_pw_9pywrapfst_47randequivalent(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;
   __pyx_t_10basictypes_int32 __pyx_v_npath;
@@ -39433,7 +40437,7 @@ static PyObject *__pyx_pw_9pywrapfst_45randequivalent(PyObject *__pyx_self, PyOb
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ifst2)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("randequivalent", 0, 2, 7, 1); __PYX_ERR(0, 3783, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("randequivalent", 0, 2, 7, 1); __PYX_ERR(0, 3842, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -39467,7 +40471,7 @@ static PyObject *__pyx_pw_9pywrapfst_45randequivalent(PyObject *__pyx_self, PyOb
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "randequivalent") < 0)) __PYX_ERR(0, 3783, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "randequivalent") < 0)) __PYX_ERR(0, 3842, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -39490,38 +40494,38 @@ static PyObject *__pyx_pw_9pywrapfst_45randequivalent(PyObject *__pyx_self, PyOb
     __pyx_v_ifst1 = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
     __pyx_v_ifst2 = ((struct __pyx_obj_9pywrapfst__Fst *)values[1]);
     if (values[2]) {
-      __pyx_v_npath = __Pyx_PyInt_As_int32_t(values[2]); if (unlikely((__pyx_v_npath == ((int32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3785, __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, 3844, __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, 3786, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[3]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3845, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__43;
+      __pyx_v_delta = __pyx_k__41;
     }
     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, 3787, __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, 3846, __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, 3789, __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, 3848, __pyx_L3_error)
     } else {
-      __pyx_v_max_length = __pyx_k__44;
+      __pyx_v_max_length = __pyx_k__42;
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("randequivalent", 0, 2, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3783, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("randequivalent", 0, 2, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3842, __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, 3783, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3784, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_44randequivalent(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_npath, __pyx_v_delta, __pyx_v_seed, __pyx_v_select, __pyx_v_max_length);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst__Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3842, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3843, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_46randequivalent(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_npath, __pyx_v_delta, __pyx_v_seed, __pyx_v_select, __pyx_v_max_length);
 
   /* function exit code */
   goto __pyx_L0;
@@ -39532,7 +40536,7 @@ static PyObject *__pyx_pw_9pywrapfst_45randequivalent(PyObject *__pyx_self, PyOb
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_44randequivalent(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, __pyx_t_10basictypes_int32 __pyx_v_npath, float __pyx_v_delta, time_t __pyx_v_seed, PyObject *__pyx_v_select, __pyx_t_10basictypes_int32 __pyx_v_max_length) {
+static PyObject *__pyx_pf_9pywrapfst_46randequivalent(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, __pyx_t_10basictypes_int32 __pyx_v_npath, float __pyx_v_delta, time_t __pyx_v_seed, PyObject *__pyx_v_select, __pyx_t_10basictypes_int32 __pyx_v_max_length) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   bool __pyx_t_1;
@@ -39546,8 +40550,8 @@ static PyObject *__pyx_pf_9pywrapfst_44randequivalent(CYTHON_UNUSED PyObject *__
   __pyx_t_2.seed = __pyx_v_seed;
   __pyx_t_2.select = __pyx_v_select;
   __pyx_t_2.max_length = __pyx_v_max_length;
-  __pyx_t_1 = __pyx_f_9pywrapfst_randequivalent(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2); if (unlikely(__pyx_t_1 == ((bool)-1) && PyErr_Occurred())) __PYX_ERR(0, 3783, __pyx_L1_error)
-  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3783, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_randequivalent(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2); if (unlikely(__pyx_t_1 == ((bool)-1) && PyErr_Occurred())) __PYX_ERR(0, 3842, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3842, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -39564,7 +40568,7 @@ static PyObject *__pyx_pf_9pywrapfst_44randequivalent(CYTHON_UNUSED PyObject *__
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3829
+/* "pywrapfst.pyx":3893
  * 
  * 
  * cpdef _MutableFst randgen(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -39572,14 +40576,14 @@ static PyObject *__pyx_pf_9pywrapfst_44randequivalent(CYTHON_UNUSED PyObject *__
  *                           time_t seed=0,
  */
 
-static PyObject *__pyx_pw_9pywrapfst_47randgen(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_49randgen(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_randgen *__pyx_optional_args) {
   __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__45;
+  __pyx_t_10basictypes_int32 __pyx_v_max_length = __pyx_k__43;
 
-  /* "pywrapfst.pyx":3834
+  /* "pywrapfst.pyx":3898
  *                           select=b"uniform",
  *                           int32 max_length=INT32_MAX,
  *                           bool weighted=False,             # <<<<<<<<<<<<<<
@@ -39588,7 +40592,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
  */
   bool __pyx_v_weighted = ((bool)0);
 
-  /* "pywrapfst.pyx":3835
+  /* "pywrapfst.pyx":3899
  *                           int32 max_length=INT32_MAX,
  *                           bool weighted=False,
  *                           bool remove_total_weight=False):             # <<<<<<<<<<<<<<
@@ -39627,27 +40631,27 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
     }
   }
 
-  /* "pywrapfst.pyx":3867
- *   See also: `randequivalent`.
+  /* "pywrapfst.pyx":3929
+ *     An FST containing one or more random paths.
  *   """
  *   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,
+ *   opts.reset(new fst.RandGenOptions[fst.RandArcSelection](ras,
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_select); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3867, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_rand_arc_selection(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3867, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_select); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3929, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst__get_rand_arc_selection(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3929, __pyx_L1_error)
   __pyx_v_ras = __pyx_t_2;
 
-  /* "pywrapfst.pyx":3869
+  /* "pywrapfst.pyx":3931
  *   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,             # <<<<<<<<<<<<<<
- *                                                           npath, weighted,
- *                                                           remove_total_weight))
+ *   opts.reset(new fst.RandGenOptions[fst.RandArcSelection](ras,             # <<<<<<<<<<<<<<
+ *                                                           max_length,
+ *                                                           npath,
  */
   __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":3873
+  /* "pywrapfst.pyx":3937
  *                                                           remove_total_weight))
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -39656,11 +40660,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3873, __pyx_L1_error)
+    __PYX_ERR(0, 3937, __pyx_L1_error)
   }
   __pyx_v_tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
 
-  /* "pywrapfst.pyx":3874
+  /* "pywrapfst.pyx":3938
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   if seed == 0:             # <<<<<<<<<<<<<<
@@ -39670,7 +40674,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":3875
+    /* "pywrapfst.pyx":3939
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   if seed == 0:
  *     seed = time(NULL) + getpid()             # <<<<<<<<<<<<<<
@@ -39679,7 +40683,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
  */
     __pyx_v_seed = (time(NULL) + getpid());
 
-    /* "pywrapfst.pyx":3874
+    /* "pywrapfst.pyx":3938
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   if seed == 0:             # <<<<<<<<<<<<<<
@@ -39688,7 +40692,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
  */
   }
 
-  /* "pywrapfst.pyx":3876
+  /* "pywrapfst.pyx":3940
  *   if seed == 0:
  *     seed = time(NULL) + getpid()
  *   fst.RandGen(deref(ifst._fst), tfst.get(), seed, deref(opts))             # <<<<<<<<<<<<<<
@@ -39697,11 +40701,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3876, __pyx_L1_error)
+    __PYX_ERR(0, 3940, __pyx_L1_error)
   }
   fst::script::RandGen((*__pyx_v_ifst->_fst), __pyx_v_tfst.get(), __pyx_v_seed, (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":3877
+  /* "pywrapfst.pyx":3941
  *     seed = time(NULL) + getpid()
  *   fst.RandGen(deref(ifst._fst), tfst.get(), seed, deref(opts))
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -39709,13 +40713,13 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_4 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3877, __pyx_L1_error)
+  __pyx_t_4 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3941, __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":3829
+  /* "pywrapfst.pyx":3893
  * 
  * 
  * cpdef _MutableFst randgen(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -39735,9 +40739,9 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_47randgen(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_46randgen[] = "\n  randgen(ifst, npath=1, seed=0, select=\"uniform\", max_length=2147483647,\n          weighted=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_47randgen(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_49randgen(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_48randgen[] = "\n  randgen(ifst, npath=1, seed=0, select=\"uniform\", max_length=2147483647,\n          weighted=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  ";
+static PyObject *__pyx_pw_9pywrapfst_49randgen(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;
   time_t __pyx_v_seed;
@@ -39816,7 +40820,7 @@ static PyObject *__pyx_pw_9pywrapfst_47randgen(PyObject *__pyx_self, PyObject *_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "randgen") < 0)) __PYX_ERR(0, 3829, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "randgen") < 0)) __PYX_ERR(0, 3893, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -39839,26 +40843,26 @@ static PyObject *__pyx_pw_9pywrapfst_47randgen(PyObject *__pyx_self, PyObject *_
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
     if (values[1]) {
-      __pyx_v_npath = __Pyx_PyInt_As_int32_t(values[1]); if (unlikely((__pyx_v_npath == ((int32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3830, __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, 3894, __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, 3831, __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, 3895, __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, 3833, __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, 3897, __pyx_L3_error)
     } else {
-      __pyx_v_max_length = __pyx_k__45;
+      __pyx_v_max_length = __pyx_k__43;
     }
     if (values[5]) {
-      __pyx_v_weighted = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_weighted == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3834, __pyx_L3_error)
+      __pyx_v_weighted = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_weighted == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3898, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3834
+      /* "pywrapfst.pyx":3898
  *                           select=b"uniform",
  *                           int32 max_length=INT32_MAX,
  *                           bool weighted=False,             # <<<<<<<<<<<<<<
@@ -39868,10 +40872,10 @@ static PyObject *__pyx_pw_9pywrapfst_47randgen(PyObject *__pyx_self, PyObject *_
       __pyx_v_weighted = ((bool)0);
     }
     if (values[6]) {
-      __pyx_v_remove_total_weight = __Pyx_PyObject_IsTrue(values[6]); if (unlikely((__pyx_v_remove_total_weight == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3835, __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, 3899, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3835
+      /* "pywrapfst.pyx":3899
  *                           int32 max_length=INT32_MAX,
  *                           bool weighted=False,
  *                           bool remove_total_weight=False):             # <<<<<<<<<<<<<<
@@ -39883,16 +40887,16 @@ static PyObject *__pyx_pw_9pywrapfst_47randgen(PyObject *__pyx_self, PyObject *_
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("randgen", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3829, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("randgen", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3893, __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, 3829, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_46randgen(__pyx_self, __pyx_v_ifst, __pyx_v_npath, __pyx_v_seed, __pyx_v_select, __pyx_v_max_length, __pyx_v_weighted, __pyx_v_remove_total_weight);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3893, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_48randgen(__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":3829
+  /* "pywrapfst.pyx":3893
  * 
  * 
  * cpdef _MutableFst randgen(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -39909,7 +40913,7 @@ static PyObject *__pyx_pw_9pywrapfst_47randgen(PyObject *__pyx_self, PyObject *_
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_46randgen(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, __pyx_t_10basictypes_int32 __pyx_v_npath, time_t __pyx_v_seed, PyObject *__pyx_v_select, __pyx_t_10basictypes_int32 __pyx_v_max_length, bool __pyx_v_weighted, bool __pyx_v_remove_total_weight) {
+static PyObject *__pyx_pf_9pywrapfst_48randgen(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, __pyx_t_10basictypes_int32 __pyx_v_npath, time_t __pyx_v_seed, PyObject *__pyx_v_select, __pyx_t_10basictypes_int32 __pyx_v_max_length, bool __pyx_v_weighted, bool __pyx_v_remove_total_weight) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -39923,7 +40927,7 @@ static PyObject *__pyx_pf_9pywrapfst_46randgen(CYTHON_UNUSED PyObject *__pyx_sel
   __pyx_t_2.max_length = __pyx_v_max_length;
   __pyx_t_2.remove_total_weight = __pyx_v_weighted;
   __pyx_t_2.weighted = __pyx_v_remove_total_weight;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_randgen(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3829, __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, 3893, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -39940,7 +40944,7 @@ static PyObject *__pyx_pf_9pywrapfst_46randgen(CYTHON_UNUSED PyObject *__pyx_sel
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3880
+/* "pywrapfst.pyx":3944
  * 
  * 
  * cpdef _MutableFst replace(pairs,             # <<<<<<<<<<<<<<
@@ -39948,12 +40952,12 @@ static PyObject *__pyx_pf_9pywrapfst_46randgen(CYTHON_UNUSED PyObject *__pyx_sel
  *                           return_arc_labeling=b"neither",
  */
 
-static PyObject *__pyx_pw_9pywrapfst_49replace(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_51replace(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObject *__pyx_v_pairs, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_replace *__pyx_optional_args) {
   PyObject *__pyx_v_call_arc_labeling = ((PyObject *)__pyx_n_b_input);
   PyObject *__pyx_v_return_arc_labeling = ((PyObject *)__pyx_n_b_neither);
 
-  /* "pywrapfst.pyx":3883
+  /* "pywrapfst.pyx":3947
  *                           call_arc_labeling=b"input",
  *                           return_arc_labeling=b"neither",
  *                           bool epsilon_on_replace=False,             # <<<<<<<<<<<<<<
@@ -39963,10 +40967,8 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
   bool __pyx_v_epsilon_on_replace = ((bool)0);
   __pyx_t_10basictypes_int64 __pyx_v_return_label = ((__pyx_t_10basictypes_int64)0);
   std::vector<__pyx_t_3fst_LabelFstClassPair>  __pyx_v__pairs;
-  __pyx_t_10basictypes_int64 __pyx_v_root_label;
   __pyx_t_10basictypes_int64 __pyx_v_label;
-  struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst = 0;
-  PyObject *__pyx_v_it = NULL;
+  struct __pyx_obj_9pywrapfst__Fst *__pyx_v_pfst = 0;
   std::unique_ptr<fst::script::VectorFstClass>  __pyx_v_tfst;
   enum fst::ReplaceLabelType __pyx_v_cal;
   enum fst::ReplaceLabelType __pyx_v_ral;
@@ -39974,15 +40976,15 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
   struct __pyx_obj_9pywrapfst__MutableFst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
+  Py_ssize_t __pyx_t_2;
+  PyObject *(*__pyx_t_3)(PyObject *);
   PyObject *__pyx_t_4 = NULL;
-  PyObject *(*__pyx_t_5)(PyObject *);
-  __pyx_t_10basictypes_int64 __pyx_t_6;
-  __pyx_t_3fst_LabelFstClassPair __pyx_t_7;
-  Py_ssize_t __pyx_t_8;
-  PyObject *(*__pyx_t_9)(PyObject *);
-  PyObject *__pyx_t_10 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  PyObject *(*__pyx_t_8)(PyObject *);
+  __pyx_t_10basictypes_int64 __pyx_t_9;
+  __pyx_t_3fst_LabelFstClassPair __pyx_t_10;
   std::string __pyx_t_11;
   enum fst::ReplaceLabelType __pyx_t_12;
   __Pyx_RefNannySetupContext("replace", 0);
@@ -40001,321 +41003,219 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
     }
   }
 
-  /* "pywrapfst.pyx":3925
+  /* "pywrapfst.pyx":3988
  *   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, 3925, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_v_it = __pyx_t_1;
-  __pyx_t_1 = 0;
-
-  /* "pywrapfst.pyx":3926
- *   cdef _Fst ifst
- *   it = iter(pairs)
- *   (root_label, ifst) = next(it)             # <<<<<<<<<<<<<<
- *   _pairs.push_back(fst.LabelFstClassPair(root_label, ifst._fst.get()))
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- */
-  __pyx_t_1 = __Pyx_PyIter_Next(__pyx_v_it); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3926, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) {
-    PyObject* sequence = __pyx_t_1;
-    Py_ssize_t size = __Pyx_PySequence_SIZE(sequence);
-    if (unlikely(size != 2)) {
-      if (size > 2) __Pyx_RaiseTooManyValuesError(2);
-      else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-      __PYX_ERR(0, 3926, __pyx_L1_error)
-    }
-    #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-    if (likely(PyTuple_CheckExact(sequence))) {
-      __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); 
-      __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1); 
-    } else {
-      __pyx_t_2 = PyList_GET_ITEM(sequence, 0); 
-      __pyx_t_3 = PyList_GET_ITEM(sequence, 1); 
-    }
-    __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, 3926, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3926, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_3);
-    #endif
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  } else {
-    Py_ssize_t index = -1;
-    __pyx_t_4 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3926, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_4);
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __pyx_t_5 = Py_TYPE(__pyx_t_4)->tp_iternext;
-    index = 0; __pyx_t_2 = __pyx_t_5(__pyx_t_4); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed;
-    __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, 3926, __pyx_L1_error)
-    __pyx_t_5 = NULL;
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    goto __pyx_L4_unpacking_done;
-    __pyx_L3_unpacking_failed:;
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_5 = NULL;
-    if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-    __PYX_ERR(0, 3926, __pyx_L1_error)
-    __pyx_L4_unpacking_done:;
-  }
-  __pyx_t_6 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_6 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3926, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_9pywrapfst__Fst))))) __PYX_ERR(0, 3926, __pyx_L1_error)
-  __pyx_v_root_label = __pyx_t_6;
-  __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_t_3);
-  __pyx_t_3 = 0;
-
-  /* "pywrapfst.pyx":3927
- *   it = iter(pairs)
- *   (root_label, ifst) = next(it)
- *   _pairs.push_back(fst.LabelFstClassPair(root_label, ifst._fst.get()))             # <<<<<<<<<<<<<<
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
- */
-  if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3927, __pyx_L1_error)
-  }
-  try {
-    __pyx_t_7 = __pyx_t_3fst_LabelFstClassPair(__pyx_v_root_label, __pyx_v_ifst->_fst.get());
-  } catch(...) {
-    __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 3927, __pyx_L1_error)
-  }
-  try {
-    __pyx_v__pairs.push_back(__pyx_t_7);
-  } catch(...) {
-    __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 3927, __pyx_L1_error)
-  }
-
-  /* "pywrapfst.pyx":3929
- *   _pairs.push_back(fst.LabelFstClassPair(root_label, ifst._fst.get()))
+ *   cdef _Fst pfst
+ *   for (label, pfst) in pairs:             # <<<<<<<<<<<<<<
+ *     _pairs.push_back(fst.LabelFstClassPair(label, pfst._fst.get()))
  *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
- *   for (label, ifst) in it:
- *     _pairs.push_back(fst.LabelFstClassPair(label, ifst._fst.get()))
  */
-  if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3929, __pyx_L1_error)
-  }
-  __pyx_v_tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
-
-  /* "pywrapfst.pyx":3930
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
- *   for (label, ifst) in it:             # <<<<<<<<<<<<<<
- *     _pairs.push_back(fst.LabelFstClassPair(label, ifst._fst.get()))
- *   cdef fst.ReplaceLabelType cal = _get_replace_label_type(
- */
-  if (likely(PyList_CheckExact(__pyx_v_it)) || PyTuple_CheckExact(__pyx_v_it)) {
-    __pyx_t_1 = __pyx_v_it; __Pyx_INCREF(__pyx_t_1); __pyx_t_8 = 0;
-    __pyx_t_9 = NULL;
+  if (likely(PyList_CheckExact(__pyx_v_pairs)) || PyTuple_CheckExact(__pyx_v_pairs)) {
+    __pyx_t_1 = __pyx_v_pairs; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
+    __pyx_t_3 = NULL;
   } else {
-    __pyx_t_8 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_it); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3930, __pyx_L1_error)
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_pairs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3988, __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, 3930, __pyx_L1_error)
+    __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3988, __pyx_L1_error)
   }
   for (;;) {
-    if (likely(!__pyx_t_9)) {
+    if (likely(!__pyx_t_3)) {
       if (likely(PyList_CheckExact(__pyx_t_1))) {
-        if (__pyx_t_8 >= PyList_GET_SIZE(__pyx_t_1)) break;
+        if (__pyx_t_2 >= 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, 3930, __pyx_L1_error)
+        __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 3988, __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, 3930, __pyx_L1_error)
-        __Pyx_GOTREF(__pyx_t_3);
+        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3988, __pyx_L1_error)
+        __Pyx_GOTREF(__pyx_t_4);
         #endif
       } else {
-        if (__pyx_t_8 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+        if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
         #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-        __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_8); __Pyx_INCREF(__pyx_t_3); __pyx_t_8++; if (unlikely(0 < 0)) __PYX_ERR(0, 3930, __pyx_L1_error)
+        __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 3988, __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, 3930, __pyx_L1_error)
-        __Pyx_GOTREF(__pyx_t_3);
+        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3988, __pyx_L1_error)
+        __Pyx_GOTREF(__pyx_t_4);
         #endif
       }
     } else {
-      __pyx_t_3 = __pyx_t_9(__pyx_t_1);
-      if (unlikely(!__pyx_t_3)) {
+      __pyx_t_4 = __pyx_t_3(__pyx_t_1);
+      if (unlikely(!__pyx_t_4)) {
         PyObject* exc_type = PyErr_Occurred();
         if (exc_type) {
           if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
-          else __PYX_ERR(0, 3930, __pyx_L1_error)
+          else __PYX_ERR(0, 3988, __pyx_L1_error)
         }
         break;
       }
-      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_GOTREF(__pyx_t_4);
     }
-    if ((likely(PyTuple_CheckExact(__pyx_t_3))) || (PyList_CheckExact(__pyx_t_3))) {
-      PyObject* sequence = __pyx_t_3;
+    if ((likely(PyTuple_CheckExact(__pyx_t_4))) || (PyList_CheckExact(__pyx_t_4))) {
+      PyObject* sequence = __pyx_t_4;
       Py_ssize_t size = __Pyx_PySequence_SIZE(sequence);
       if (unlikely(size != 2)) {
         if (size > 2) __Pyx_RaiseTooManyValuesError(2);
         else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-        __PYX_ERR(0, 3930, __pyx_L1_error)
+        __PYX_ERR(0, 3988, __pyx_L1_error)
       }
       #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
       if (likely(PyTuple_CheckExact(sequence))) {
-        __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); 
-        __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); 
+        __pyx_t_5 = PyTuple_GET_ITEM(sequence, 0); 
+        __pyx_t_6 = PyTuple_GET_ITEM(sequence, 1); 
       } else {
-        __pyx_t_2 = PyList_GET_ITEM(sequence, 0); 
-        __pyx_t_4 = PyList_GET_ITEM(sequence, 1); 
+        __pyx_t_5 = PyList_GET_ITEM(sequence, 0); 
+        __pyx_t_6 = PyList_GET_ITEM(sequence, 1); 
       }
-      __Pyx_INCREF(__pyx_t_2);
-      __Pyx_INCREF(__pyx_t_4);
+      __Pyx_INCREF(__pyx_t_5);
+      __Pyx_INCREF(__pyx_t_6);
       #else
-      __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3930, __pyx_L1_error)
-      __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3930, __pyx_L1_error)
-      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3988, __pyx_L1_error)
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3988, __pyx_L1_error)
+      __Pyx_GOTREF(__pyx_t_6);
       #endif
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     } else {
       Py_ssize_t index = -1;
-      __pyx_t_10 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 3930, __pyx_L1_error)
-      __Pyx_GOTREF(__pyx_t_10);
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_5 = Py_TYPE(__pyx_t_10)->tp_iternext;
-      index = 0; __pyx_t_2 = __pyx_t_5(__pyx_t_10); if (unlikely(!__pyx_t_2)) goto __pyx_L7_unpacking_failed;
-      __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, 3930, __pyx_L1_error)
-      __pyx_t_5 = NULL;
-      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-      goto __pyx_L8_unpacking_done;
-      __pyx_L7_unpacking_failed:;
-      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-      __pyx_t_5 = NULL;
+      __pyx_t_7 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 3988, __pyx_L1_error)
+      __Pyx_GOTREF(__pyx_t_7);
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_8 = Py_TYPE(__pyx_t_7)->tp_iternext;
+      index = 0; __pyx_t_5 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_5)) goto __pyx_L5_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_5);
+      index = 1; __pyx_t_6 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_6)) goto __pyx_L5_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_6);
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 2) < 0) __PYX_ERR(0, 3988, __pyx_L1_error)
+      __pyx_t_8 = NULL;
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      goto __pyx_L6_unpacking_done;
+      __pyx_L5_unpacking_failed:;
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      __pyx_t_8 = NULL;
       if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-      __PYX_ERR(0, 3930, __pyx_L1_error)
-      __pyx_L8_unpacking_done:;
+      __PYX_ERR(0, 3988, __pyx_L1_error)
+      __pyx_L6_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, 3930, __pyx_L1_error)
-    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_9pywrapfst__Fst))))) __PYX_ERR(0, 3930, __pyx_L1_error)
-    __pyx_v_label = __pyx_t_6;
-    __Pyx_DECREF_SET(__pyx_v_ifst, ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_t_4));
-    __pyx_t_4 = 0;
-
-    /* "pywrapfst.pyx":3931
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
- *   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)
+    __pyx_t_9 = __Pyx_PyInt_As_int64_t(__pyx_t_5); if (unlikely((__pyx_t_9 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3988, __pyx_L1_error)
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    if (!(likely(((__pyx_t_6) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_6, __pyx_ptype_9pywrapfst__Fst))))) __PYX_ERR(0, 3988, __pyx_L1_error)
+    __pyx_v_label = __pyx_t_9;
+    __Pyx_XDECREF_SET(__pyx_v_pfst, ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_t_6));
+    __pyx_t_6 = 0;
+
+    /* "pywrapfst.pyx":3989
+ *   cdef _Fst pfst
+ *   for (label, pfst) in pairs:
+ *     _pairs.push_back(fst.LabelFstClassPair(label, pfst._fst.get()))             # <<<<<<<<<<<<<<
+ *   cdef unique_ptr[fst.VectorFstClass] tfst
+ *   tfst.reset(new fst.VectorFstClass(_pairs[0].second.ArcType()))
  */
-    if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
+    if (unlikely(((PyObject *)__pyx_v_pfst) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-      __PYX_ERR(0, 3931, __pyx_L1_error)
+      __PYX_ERR(0, 3989, __pyx_L1_error)
     }
     try {
-      __pyx_t_7 = __pyx_t_3fst_LabelFstClassPair(__pyx_v_label, __pyx_v_ifst->_fst.get());
+      __pyx_t_10 = __pyx_t_3fst_LabelFstClassPair(__pyx_v_label, __pyx_v_pfst->_fst.get());
     } catch(...) {
       __Pyx_CppExn2PyErr();
-      __PYX_ERR(0, 3931, __pyx_L1_error)
+      __PYX_ERR(0, 3989, __pyx_L1_error)
     }
     try {
-      __pyx_v__pairs.push_back(__pyx_t_7);
+      __pyx_v__pairs.push_back(__pyx_t_10);
     } catch(...) {
       __Pyx_CppExn2PyErr();
-      __PYX_ERR(0, 3931, __pyx_L1_error)
+      __PYX_ERR(0, 3989, __pyx_L1_error)
     }
 
-    /* "pywrapfst.pyx":3930
+    /* "pywrapfst.pyx":3988
+ *   cdef int64 label
+ *   cdef _Fst pfst
+ *   for (label, pfst) in pairs:             # <<<<<<<<<<<<<<
+ *     _pairs.push_back(fst.LabelFstClassPair(label, pfst._fst.get()))
  *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
- *   for (label, ifst) in it:             # <<<<<<<<<<<<<<
- *     _pairs.push_back(fst.LabelFstClassPair(label, ifst._fst.get()))
- *   cdef fst.ReplaceLabelType cal = _get_replace_label_type(
  */
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":3933
- *     _pairs.push_back(fst.LabelFstClassPair(label, ifst._fst.get()))
+  /* "pywrapfst.pyx":3991
+ *     _pairs.push_back(fst.LabelFstClassPair(label, pfst._fst.get()))
+ *   cdef unique_ptr[fst.VectorFstClass] tfst
+ *   tfst.reset(new fst.VectorFstClass(_pairs[0].second.ArcType()))             # <<<<<<<<<<<<<<
+ *   cdef fst.ReplaceLabelType cal = _get_replace_label_type(
+ *       tostring(call_arc_labeling),
+ */
+  __pyx_v_tfst.reset(new fst::script::VectorFstClass((__pyx_v__pairs[0]).second->ArcType()));
+
+  /* "pywrapfst.pyx":3993
+ *   tfst.reset(new fst.VectorFstClass(_pairs[0].second.ArcType()))
  *   cdef fst.ReplaceLabelType cal = _get_replace_label_type(
- *       tostring(call_arc_labeling), epsilon_on_replace)             # <<<<<<<<<<<<<<
+ *       tostring(call_arc_labeling),             # <<<<<<<<<<<<<<
+ *       epsilon_on_replace)
  *   cdef fst.ReplaceLabelType ral = _get_replace_label_type(
- *       tostring(return_arc_labeling), epsilon_on_replace)
  */
-  __pyx_t_11 = __pyx_f_9pywrapfst_tostring(__pyx_v_call_arc_labeling); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3933, __pyx_L1_error)
+  __pyx_t_11 = __pyx_f_9pywrapfst_tostring(__pyx_v_call_arc_labeling); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3993, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3932
- *   for (label, ifst) in it:
- *     _pairs.push_back(fst.LabelFstClassPair(label, ifst._fst.get()))
+  /* "pywrapfst.pyx":3992
+ *   cdef unique_ptr[fst.VectorFstClass] tfst
+ *   tfst.reset(new fst.VectorFstClass(_pairs[0].second.ArcType()))
  *   cdef fst.ReplaceLabelType cal = _get_replace_label_type(             # <<<<<<<<<<<<<<
- *       tostring(call_arc_labeling), epsilon_on_replace)
- *   cdef fst.ReplaceLabelType ral = _get_replace_label_type(
+ *       tostring(call_arc_labeling),
+ *       epsilon_on_replace)
  */
-  __pyx_t_12 = __pyx_f_9pywrapfst__get_replace_label_type(__pyx_t_11, __pyx_v_epsilon_on_replace); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3932, __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, 3992, __pyx_L1_error)
   __pyx_v_cal = __pyx_t_12;
 
-  /* "pywrapfst.pyx":3935
- *       tostring(call_arc_labeling), epsilon_on_replace)
+  /* "pywrapfst.pyx":3996
+ *       epsilon_on_replace)
  *   cdef fst.ReplaceLabelType ral = _get_replace_label_type(
- *       tostring(return_arc_labeling), epsilon_on_replace)             # <<<<<<<<<<<<<<
+ *       tostring(return_arc_labeling),             # <<<<<<<<<<<<<<
+ *       epsilon_on_replace)
  *   cdef unique_ptr[fst.ReplaceOptions] opts
- *   opts.reset(new fst.ReplaceOptions(root_label, cal, ral, return_label))
  */
-  __pyx_t_11 = __pyx_f_9pywrapfst_tostring(__pyx_v_return_arc_labeling); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3935, __pyx_L1_error)
+  __pyx_t_11 = __pyx_f_9pywrapfst_tostring(__pyx_v_return_arc_labeling); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3996, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3934
- *   cdef fst.ReplaceLabelType cal = _get_replace_label_type(
- *       tostring(call_arc_labeling), epsilon_on_replace)
+  /* "pywrapfst.pyx":3995
+ *       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
+ *       tostring(return_arc_labeling),
+ *       epsilon_on_replace)
  */
-  __pyx_t_12 = __pyx_f_9pywrapfst__get_replace_label_type(__pyx_t_11, __pyx_v_epsilon_on_replace); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3934, __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, 3995, __pyx_L1_error)
   __pyx_v_ral = __pyx_t_12;
 
-  /* "pywrapfst.pyx":3937
- *       tostring(return_arc_labeling), epsilon_on_replace)
+  /* "pywrapfst.pyx":3999
+ *       epsilon_on_replace)
  *   cdef unique_ptr[fst.ReplaceOptions] opts
- *   opts.reset(new fst.ReplaceOptions(root_label, cal, ral, return_label))             # <<<<<<<<<<<<<<
+ *   opts.reset(new fst.ReplaceOptions(_pairs[0].first, cal, ral, return_label))             # <<<<<<<<<<<<<<
  *   fst.Replace(_pairs, tfst.get(), deref(opts))
  *   return _init_MutableFst(tfst.release())
  */
-  __pyx_v_opts.reset(new fst::script::ReplaceOptions(__pyx_v_root_label, __pyx_v_cal, __pyx_v_ral, __pyx_v_return_label));
+  __pyx_v_opts.reset(new fst::script::ReplaceOptions((__pyx_v__pairs[0]).first, __pyx_v_cal, __pyx_v_ral, __pyx_v_return_label));
 
-  /* "pywrapfst.pyx":3938
+  /* "pywrapfst.pyx":4000
  *   cdef unique_ptr[fst.ReplaceOptions] opts
- *   opts.reset(new fst.ReplaceOptions(root_label, cal, ral, return_label))
+ *   opts.reset(new fst.ReplaceOptions(_pairs[0].first, cal, ral, return_label))
  *   fst.Replace(_pairs, tfst.get(), deref(opts))             # <<<<<<<<<<<<<<
  *   return _init_MutableFst(tfst.release())
  * 
  */
   fst::script::Replace(__pyx_v__pairs, __pyx_v_tfst.get(), (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":3939
- *   opts.reset(new fst.ReplaceOptions(root_label, cal, ral, return_label))
+  /* "pywrapfst.pyx":4001
+ *   opts.reset(new fst.ReplaceOptions(_pairs[0].first, cal, ral, return_label))
  *   fst.Replace(_pairs, tfst.get(), deref(opts))
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3939, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4001, __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":3880
+  /* "pywrapfst.pyx":3944
  * 
  * 
  * cpdef _MutableFst replace(pairs,             # <<<<<<<<<<<<<<
@@ -40326,24 +41226,23 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
   /* 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_10);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
   __Pyx_AddTraceback("pywrapfst.replace", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_ifst);
-  __Pyx_XDECREF(__pyx_v_it);
+  __Pyx_XDECREF((PyObject *)__pyx_v_pfst);
   __Pyx_XGIVEREF((PyObject *)__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_49replace(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_48replace[] = "\n  replace(pairs, call_arc_labeling=\"input\", return_arc_labeling=\"neither\",\n          epsilon_on_replace=False, return_label=0)\n\n  Recursively replaces arcs in the FST with other FST(s).\n\n  This operation performs the dynamic replacement of arcs in one FST with\n  another FST, allowing the definition of FSTs analogous to RTNs. It takes as\n  input a set of pairs of a set of pairs formed by a non-terminal label and\n  its corresponding FST, and a label identifying the root FST in that set.\n  The resulting FST is obtained by taking the root FST and recursively replacing\n  each arc having a nonterminal as output label by its corresponding FST. More\n  precisely, an arc from state s to state d with (nonterminal) output label n in\n  this FST is replaced by redirecting this \"call\" arc to the initial state of a\n  copy F of the FST for n, and adding \"return\" arcs from each final state of F\n  to d. Optional arguments control how the call and return arcs are labeled; by\n  default, the only non-epsilon label is placed on the call arc.\n\n  Args:\n\n    pairs: An iterable of (nonterminal label, FST) pairs, where the former is an\n        unsigned integer and the latter is an Fst instance.\n    call_arc_labeling: A string indicating which call arc labels should be\n        non-epsilon. One of: \"input\" (default), \"output\", \"both\", \"neither\".\n        This value is set to \"neither\" if epsilon_on_replace is True.\n    return_arc_labeling: A string indicating which return arc labels should be\n        non-epsilon. One of: \"input\", \"output\", \"both\", \"neither\" (default).\n        This value is set to \"neither\" if epsilon_on_replace is True.\n    epsilon_on_replace: Should call and return arcs be epsilon arcs? If True,\n        this effectively overrides call_arc_labeling and return_arc_labeling,\n        setting both to \"neither\".\n    return_label: The integer label for return arcs.\n\n  Returns:\n    An FST resulting from expanding the input"" RTN.\n  ";
-static PyObject *__pyx_pw_9pywrapfst_49replace(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_51replace(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_50replace[] = "\n  replace(pairs, call_arc_labeling=\"input\", return_arc_labeling=\"neither\",\n          epsilon_on_replace=False, return_label=0)\n\n  Recursively replaces arcs in the FST with other FST(s).\n\n  This operation performs the dynamic replacement of arcs in one FST with\n  another FST, allowing the definition of FSTs analogous to RTNs. It takes as\n  input a set of pairs of a set of pairs formed by a non-terminal label and\n  its corresponding FST, and a label identifying the root FST in that set.\n  The resulting FST is obtained by taking the root FST and recursively replacing\n  each arc having a nonterminal as output label by its corresponding FST. More\n  precisely, an arc from state s to state d with (nonterminal) output label n in\n  this FST is replaced by redirecting this \"call\" arc to the initial state of a\n  copy F of the FST for n, and adding \"return\" arcs from each final state of F\n  to d. Optional arguments control how the call and return arcs are labeled; by\n  default, the only non-epsilon label is placed on the call arc.\n\n  Args:\n\n    pairs: An iterable of (nonterminal label, FST) pairs, where the former is an\n        unsigned integer and the latter is an Fst instance.\n    call_arc_labeling: A string indicating which call arc labels should be\n        non-epsilon. One of: \"input\" (default), \"output\", \"both\", \"neither\".\n        This value is set to \"neither\" if epsilon_on_replace is True.\n    return_arc_labeling: A string indicating which return arc labels should be\n        non-epsilon. One of: \"input\", \"output\", \"both\", \"neither\" (default).\n        This value is set to \"neither\" if epsilon_on_replace is True.\n    epsilon_on_replace: Should call and return arcs be epsilon arcs? If True,\n        this effectively overrides call_arc_labeling and return_arc_labeling,\n        setting both to \"neither\".\n    return_label: The integer label for return arcs.\n\n  Returns:\n    An FST resulting from expanding the input"" RTN.\n  ";
+static PyObject *__pyx_pw_9pywrapfst_51replace(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_pairs = 0;
   PyObject *__pyx_v_call_arc_labeling = 0;
   PyObject *__pyx_v_return_arc_labeling = 0;
@@ -40405,7 +41304,7 @@ static PyObject *__pyx_pw_9pywrapfst_49replace(PyObject *__pyx_self, PyObject *_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "replace") < 0)) __PYX_ERR(0, 3880, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "replace") < 0)) __PYX_ERR(0, 3944, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -40426,10 +41325,10 @@ static PyObject *__pyx_pw_9pywrapfst_49replace(PyObject *__pyx_self, PyObject *_
     __pyx_v_call_arc_labeling = values[1];
     __pyx_v_return_arc_labeling = values[2];
     if (values[3]) {
-      __pyx_v_epsilon_on_replace = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_epsilon_on_replace == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3883, __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, 3947, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3883
+      /* "pywrapfst.pyx":3947
  *                           call_arc_labeling=b"input",
  *                           return_arc_labeling=b"neither",
  *                           bool epsilon_on_replace=False,             # <<<<<<<<<<<<<<
@@ -40439,22 +41338,22 @@ static PyObject *__pyx_pw_9pywrapfst_49replace(PyObject *__pyx_self, PyObject *_
       __pyx_v_epsilon_on_replace = ((bool)0);
     }
     if (values[4]) {
-      __pyx_v_return_label = __Pyx_PyInt_As_int64_t(values[4]); if (unlikely((__pyx_v_return_label == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3884, __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, 3948, __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, 3880, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("replace", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3944, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.replace", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_48replace(__pyx_self, __pyx_v_pairs, __pyx_v_call_arc_labeling, __pyx_v_return_arc_labeling, __pyx_v_epsilon_on_replace, __pyx_v_return_label);
+  __pyx_r = __pyx_pf_9pywrapfst_50replace(__pyx_self, __pyx_v_pairs, __pyx_v_call_arc_labeling, __pyx_v_return_arc_labeling, __pyx_v_epsilon_on_replace, __pyx_v_return_label);
 
-  /* "pywrapfst.pyx":3880
+  /* "pywrapfst.pyx":3944
  * 
  * 
  * cpdef _MutableFst replace(pairs,             # <<<<<<<<<<<<<<
@@ -40467,7 +41366,7 @@ static PyObject *__pyx_pw_9pywrapfst_49replace(PyObject *__pyx_self, PyObject *_
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_48replace(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pairs, PyObject *__pyx_v_call_arc_labeling, PyObject *__pyx_v_return_arc_labeling, bool __pyx_v_epsilon_on_replace, __pyx_t_10basictypes_int64 __pyx_v_return_label) {
+static PyObject *__pyx_pf_9pywrapfst_50replace(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pairs, PyObject *__pyx_v_call_arc_labeling, PyObject *__pyx_v_return_arc_labeling, bool __pyx_v_epsilon_on_replace, __pyx_t_10basictypes_int64 __pyx_v_return_label) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -40479,7 +41378,7 @@ static PyObject *__pyx_pf_9pywrapfst_48replace(CYTHON_UNUSED PyObject *__pyx_sel
   __pyx_t_2.return_arc_labeling = __pyx_v_return_arc_labeling;
   __pyx_t_2.epsilon_on_replace = __pyx_v_epsilon_on_replace;
   __pyx_t_2.return_label = __pyx_v_return_label;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_replace(__pyx_v_pairs, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3880, __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, 3944, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -40496,7 +41395,7 @@ static PyObject *__pyx_pf_9pywrapfst_48replace(CYTHON_UNUSED PyObject *__pyx_sel
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3942
+/* "pywrapfst.pyx":4004
  * 
  * 
  * cpdef _MutableFst reverse(_Fst ifst, bool require_superinitial=True):             # <<<<<<<<<<<<<<
@@ -40504,7 +41403,7 @@ static PyObject *__pyx_pf_9pywrapfst_48replace(CYTHON_UNUSED PyObject *__pyx_sel
  *   reverse(ifst, require_superinitial=True)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_51reverse(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_53reverse(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_reverse(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_reverse *__pyx_optional_args) {
   bool __pyx_v_require_superinitial = ((bool)1);
   std::unique_ptr<fst::script::VectorFstClass>  __pyx_v_tfst;
@@ -40518,7 +41417,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_reverse(struc
     }
   }
 
-  /* "pywrapfst.pyx":3962
+  /* "pywrapfst.pyx":4024
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -40527,11 +41426,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_reverse(struc
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3962, __pyx_L1_error)
+    __PYX_ERR(0, 4024, __pyx_L1_error)
   }
   __pyx_v_tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
 
-  /* "pywrapfst.pyx":3963
+  /* "pywrapfst.pyx":4025
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   fst.Reverse(deref(ifst._fst), tfst.get(), require_superinitial)             # <<<<<<<<<<<<<<
@@ -40540,11 +41439,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_reverse(struc
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3963, __pyx_L1_error)
+    __PYX_ERR(0, 4025, __pyx_L1_error)
   }
   fst::script::Reverse((*__pyx_v_ifst->_fst), __pyx_v_tfst.get(), __pyx_v_require_superinitial);
 
-  /* "pywrapfst.pyx":3964
+  /* "pywrapfst.pyx":4026
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   fst.Reverse(deref(ifst._fst), tfst.get(), require_superinitial)
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -40552,13 +41451,13 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_reverse(struc
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3964, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4026, __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":3942
+  /* "pywrapfst.pyx":4004
  * 
  * 
  * cpdef _MutableFst reverse(_Fst ifst, bool require_superinitial=True):             # <<<<<<<<<<<<<<
@@ -40578,9 +41477,9 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_reverse(struc
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_51reverse(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_50reverse[] = "\n  reverse(ifst, require_superinitial=True)\n\n  Constructively reverses an FST's transduction.\n\n  This operation reverses an FST. If A transduces string x to y with weight a,\n  then the reverse of A transduces the reverse of x to the reverse of y with\n  weight a.Reverse(). (Typically, a = a.Reverse() and Arc = RevArc, e.g.,\n  TropicalWeight and LogWeight.) In general, e.g., when the weights only form a\n  left or right semiring, the output arc type must match the input arc type.\n\n  Args:\n    ifst: The input FST.\n    require_superinitial: Should a superinitial state be created?\n\n  Returns:\n    A reversed FST.\n  ";
-static PyObject *__pyx_pw_9pywrapfst_51reverse(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_53reverse(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_52reverse[] = "\n  reverse(ifst, require_superinitial=True)\n\n  Constructively reverses an FST's transduction.\n\n  This operation reverses an FST. If A transduces string x to y with weight a,\n  then the reverse of A transduces the reverse of x to the reverse of y with\n  weight a.Reverse(). (Typically, a = a.Reverse() and Arc = RevArc, e.g.,\n  TropicalWeight and LogWeight.) In general, e.g., when the weights only form a\n  left or right semiring, the output arc type must match the input arc type.\n\n  Args:\n    ifst: The input FST.\n    require_superinitial: Should a superinitial state be created?\n\n  Returns:\n    A reversed FST.\n  ";
+static PyObject *__pyx_pw_9pywrapfst_53reverse(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst = 0;
   bool __pyx_v_require_superinitial;
   PyObject *__pyx_r = 0;
@@ -40613,7 +41512,7 @@ static PyObject *__pyx_pw_9pywrapfst_51reverse(PyObject *__pyx_self, PyObject *_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reverse") < 0)) __PYX_ERR(0, 3942, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reverse") < 0)) __PYX_ERR(0, 4004, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -40626,21 +41525,21 @@ static PyObject *__pyx_pw_9pywrapfst_51reverse(PyObject *__pyx_self, PyObject *_
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
     if (values[1]) {
-      __pyx_v_require_superinitial = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_require_superinitial == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3942, __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, 4004, __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, 3942, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("reverse", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4004, __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, 3942, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_50reverse(__pyx_self, __pyx_v_ifst, __pyx_v_require_superinitial);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 4004, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_52reverse(__pyx_self, __pyx_v_ifst, __pyx_v_require_superinitial);
 
   /* function exit code */
   goto __pyx_L0;
@@ -40651,7 +41550,7 @@ static PyObject *__pyx_pw_9pywrapfst_51reverse(PyObject *__pyx_self, PyObject *_
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_50reverse(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, bool __pyx_v_require_superinitial) {
+static PyObject *__pyx_pf_9pywrapfst_52reverse(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, bool __pyx_v_require_superinitial) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -40660,7 +41559,7 @@ static PyObject *__pyx_pf_9pywrapfst_50reverse(CYTHON_UNUSED PyObject *__pyx_sel
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_2.__pyx_n = 1;
   __pyx_t_2.require_superinitial = __pyx_v_require_superinitial;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_reverse(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3942, __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, 4004, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -40677,7 +41576,7 @@ static PyObject *__pyx_pf_9pywrapfst_50reverse(CYTHON_UNUSED PyObject *__pyx_sel
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3970
+/* "pywrapfst.pyx":4032
  * 
  * 
  * cdef vector[fst.WeightClass] *_shortestdistance(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -40686,11 +41585,11 @@ static PyObject *__pyx_pf_9pywrapfst_50reverse(CYTHON_UNUSED PyObject *__pyx_sel
  */
 
 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__46;
-  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__47;
+  float __pyx_v_delta = __pyx_k__44;
+  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__45;
   PyObject *__pyx_v_queue_type = ((PyObject *)__pyx_n_b_auto);
 
-  /* "pywrapfst.pyx":3974
+  /* "pywrapfst.pyx":4036
  *                                                 int64 nstate=fst.kNoStateId,
  *                                                 queue_type=b"auto",
  *                                                 bool reverse=False) except *:             # <<<<<<<<<<<<<<
@@ -40722,7 +41621,7 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
     }
   }
 
-  /* "pywrapfst.pyx":3976
+  /* "pywrapfst.pyx":4038
  *                                                 bool reverse=False) except *:
  *   cdef unique_ptr[vector[fst.WeightClass]] distance
  *   distance.reset(new vector[fst.WeightClass]())             # <<<<<<<<<<<<<<
@@ -40733,11 +41632,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, 3976, __pyx_L1_error)
+    __PYX_ERR(0, 4038, __pyx_L1_error)
   }
   __pyx_v_distance.reset(__pyx_t_1);
 
-  /* "pywrapfst.pyx":3980
+  /* "pywrapfst.pyx":4042
  *   # not be used in all cases.
  *   cdef unique_ptr[fst.ShortestDistanceOptions] opts
  *   if reverse:             # <<<<<<<<<<<<<<
@@ -40747,7 +41646,7 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
   __pyx_t_2 = (__pyx_v_reverse != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":3983
+    /* "pywrapfst.pyx":4045
  *     # 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)             # <<<<<<<<<<<<<<
@@ -40756,11 +41655,11 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
  */
     if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-      __PYX_ERR(0, 3983, __pyx_L1_error)
+      __PYX_ERR(0, 4045, __pyx_L1_error)
     }
     fst::script::ShortestDistance((*__pyx_v_ifst->_fst), __pyx_v_distance.get(), 1, __pyx_v_delta);
 
-    /* "pywrapfst.pyx":3980
+    /* "pywrapfst.pyx":4042
  *   # not be used in all cases.
  *   cdef unique_ptr[fst.ShortestDistanceOptions] opts
  *   if reverse:             # <<<<<<<<<<<<<<
@@ -40770,36 +41669,36 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
     goto __pyx_L3;
   }
 
-  /* "pywrapfst.pyx":3985
+  /* "pywrapfst.pyx":4047
  *     fst.ShortestDistance(deref(ifst._fst), distance.get(), True, delta)
  *   else:
  *     opts.reset(new fst.ShortestDistanceOptions(             # <<<<<<<<<<<<<<
- *         _get_queue_type(tostring(queue_type)), fst.ANY_ARC_FILTER, nstate,
- *         delta))
+ *         _get_queue_type(tostring(queue_type)),
+ *         fst.ANY_ARC_FILTER,
  */
   /*else*/ {
 
-    /* "pywrapfst.pyx":3986
+    /* "pywrapfst.pyx":4048
  *   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))
+ *         _get_queue_type(tostring(queue_type)),             # <<<<<<<<<<<<<<
+ *         fst.ANY_ARC_FILTER,
+ *         nstate,
  */
-    __pyx_t_3 = __pyx_f_9pywrapfst_tostring(__pyx_v_queue_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3986, __pyx_L1_error)
-    __pyx_t_4 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3986, __pyx_L1_error)
+    __pyx_t_3 = __pyx_f_9pywrapfst_tostring(__pyx_v_queue_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4048, __pyx_L1_error)
+    __pyx_t_4 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4048, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3985
+    /* "pywrapfst.pyx":4047
  *     fst.ShortestDistance(deref(ifst._fst), distance.get(), True, delta)
  *   else:
  *     opts.reset(new fst.ShortestDistanceOptions(             # <<<<<<<<<<<<<<
- *         _get_queue_type(tostring(queue_type)), fst.ANY_ARC_FILTER, nstate,
- *         delta))
+ *         _get_queue_type(tostring(queue_type)),
+ *         fst.ANY_ARC_FILTER,
  */
     __pyx_v_opts.reset(new fst::script::ShortestDistanceOptions(__pyx_t_4, fst::script::ANY_ARC_FILTER, __pyx_v_nstate, __pyx_v_delta));
 
-    /* "pywrapfst.pyx":3988
- *         _get_queue_type(tostring(queue_type)), fst.ANY_ARC_FILTER, nstate,
+    /* "pywrapfst.pyx":4052
+ *         nstate,
  *         delta))
  *     fst.ShortestDistance(deref(ifst._fst), distance.get(), deref(opts))             # <<<<<<<<<<<<<<
  *   return distance.release()
@@ -40807,13 +41706,13 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
  */
     if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-      __PYX_ERR(0, 3988, __pyx_L1_error)
+      __PYX_ERR(0, 4052, __pyx_L1_error)
     }
     fst::script::ShortestDistance((*__pyx_v_ifst->_fst), __pyx_v_distance.get(), (*__pyx_v_opts));
   }
   __pyx_L3:;
 
-  /* "pywrapfst.pyx":3989
+  /* "pywrapfst.pyx":4053
  *         delta))
  *     fst.ShortestDistance(deref(ifst._fst), distance.get(), deref(opts))
  *   return distance.release()             # <<<<<<<<<<<<<<
@@ -40823,7 +41722,7 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
   __pyx_r = __pyx_v_distance.release();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3970
+  /* "pywrapfst.pyx":4032
  * 
  * 
  * cdef vector[fst.WeightClass] *_shortestdistance(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -40840,7 +41739,7 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3992
+/* "pywrapfst.pyx":4056
  * 
  * 
  * def shortestdistance(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -40849,10 +41748,10 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_53shortestdistance(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_52shortestdistance[] = "\n  shortestdistance(ifst, delta=1e-6, nstate=NO_STATE_ID,\n                   queue_type=\"auto\", reverse=False)\n\n  Compute the shortest distance from the initial or final state.\n\n  This operation computes the shortest distance from the initial state (when\n  `reverse` is False) or from every state to the final state (when `reverse` is\n  True). The shortest distance from p to q is the \\otimes-sum of the weights of\n  all the paths between p and q. The weights must be right (if `reverse` is\n  False) or left (if `reverse` is True) distributive, and k-closed (i.e., 1\n  \\otimes x \\otimes x^2 \\otimes ... \\otimes x^{k + 1} = 1 \\otimes x \\otimes x^2\n  \\otimes ... \\otimes x^k; e.g., TropicalWeight).\n\n  Args:\n    ifst: The input FST.\n    delta: Comparison/quantization delta.\n    nstate: State number threshold (ignored if `reverse` is True).\n    queue_type: A string matching a known queue type; one of: \"auto\", \"fifo\",\n        \"lifo\", \"shortest\", \"state\", \"top\" (ignored if `reverse` is True).\n    reverse: Should the reverse distance (from each state to the final state)\n        be computed?\n\n  Returns:\n    A list of Weight objects representing the shortest distance for each state.\n  ";
-static PyMethodDef __pyx_mdef_9pywrapfst_53shortestdistance = {"shortestdistance", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_53shortestdistance, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_52shortestdistance};
-static PyObject *__pyx_pw_9pywrapfst_53shortestdistance(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_55shortestdistance(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_54shortestdistance[] = "\n  shortestdistance(ifst, delta=1e-6, nstate=NO_STATE_ID,\n                   queue_type=\"auto\", reverse=False)\n\n  Compute the shortest distance from the initial or final state.\n\n  This operation computes the shortest distance from the initial state (when\n  `reverse` is False) or from every state to the final state (when `reverse` is\n  True). The shortest distance from p to q is the \\otimes-sum of the weights of\n  all the paths between p and q. The weights must be right (if `reverse` is\n  False) or left (if `reverse` is True) distributive, and k-closed (i.e., 1\n  \\otimes x \\otimes x^2 \\otimes ... \\otimes x^{k + 1} = 1 \\otimes x \\otimes x^2\n  \\otimes ... \\otimes x^k; e.g., TropicalWeight).\n\n  Args:\n    ifst: The input FST.\n    delta: Comparison/quantization delta.\n    nstate: State number threshold (ignored if `reverse` is True).\n    queue_type: A string matching a known queue type; one of: \"auto\", \"fifo\",\n        \"lifo\", \"shortest\", \"state\", \"top\" (ignored if `reverse` is True).\n    reverse: Should the reverse distance (from each state to the final state)\n        be computed?\n\n  Returns:\n    A list of Weight objects representing the shortest distance for each state.\n  ";
+static PyMethodDef __pyx_mdef_9pywrapfst_55shortestdistance = {"shortestdistance", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_55shortestdistance, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_54shortestdistance};
+static PyObject *__pyx_pw_9pywrapfst_55shortestdistance(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst = 0;
   float __pyx_v_delta;
   __pyx_t_10basictypes_int64 __pyx_v_nstate;
@@ -40913,7 +41812,7 @@ static PyObject *__pyx_pw_9pywrapfst_53shortestdistance(PyObject *__pyx_self, Py
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "shortestdistance") < 0)) __PYX_ERR(0, 3992, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "shortestdistance") < 0)) __PYX_ERR(0, 4056, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -40932,21 +41831,21 @@ static PyObject *__pyx_pw_9pywrapfst_53shortestdistance(PyObject *__pyx_self, Py
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
     if (values[1]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3993, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 4057, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__48;
+      __pyx_v_delta = __pyx_k__46;
     }
     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, 3994, __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, 4058, __pyx_L3_error)
     } else {
-      __pyx_v_nstate = __pyx_k__49;
+      __pyx_v_nstate = __pyx_k__47;
     }
     __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, 3996, __pyx_L3_error)
+      __pyx_v_reverse = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_reverse == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4060, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3996
+      /* "pywrapfst.pyx":4060
  *                      int64 nstate=fst.kNoStateId,
  *                      queue_type=b"auto",
  *                      bool reverse=False):             # <<<<<<<<<<<<<<
@@ -40958,16 +41857,16 @@ static PyObject *__pyx_pw_9pywrapfst_53shortestdistance(PyObject *__pyx_self, Py
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("shortestdistance", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3992, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("shortestdistance", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4056, __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, 3992, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_52shortestdistance(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_nstate, __pyx_v_queue_type, __pyx_v_reverse);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 4056, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_54shortestdistance(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_nstate, __pyx_v_queue_type, __pyx_v_reverse);
 
-  /* "pywrapfst.pyx":3992
+  /* "pywrapfst.pyx":4056
  * 
  * 
  * def shortestdistance(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -40984,7 +41883,7 @@ static PyObject *__pyx_pw_9pywrapfst_53shortestdistance(PyObject *__pyx_self, Py
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_52shortestdistance(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, __pyx_t_10basictypes_int64 __pyx_v_nstate, PyObject *__pyx_v_queue_type, bool __pyx_v_reverse) {
+static PyObject *__pyx_pf_9pywrapfst_54shortestdistance(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, __pyx_t_10basictypes_int64 __pyx_v_nstate, PyObject *__pyx_v_queue_type, bool __pyx_v_reverse) {
   std::unique_ptr<std::vector<fst::script::WeightClass> >  __pyx_v_distance;
   std::string __pyx_v_weight_type;
   fst::script::WeightClass __pyx_7genexpr__pyx_v_weight;
@@ -41000,7 +41899,7 @@ static PyObject *__pyx_pf_9pywrapfst_52shortestdistance(CYTHON_UNUSED PyObject *
   PyObject *__pyx_t_8 = NULL;
   __Pyx_RefNannySetupContext("shortestdistance", 0);
 
-  /* "pywrapfst.pyx":4024
+  /* "pywrapfst.pyx":4088
  *   """
  *   cdef unique_ptr[vector[fst.WeightClass]] distance
  *   distance.reset(_shortestdistance(ifst, delta, nstate, queue_type, reverse))             # <<<<<<<<<<<<<<
@@ -41012,10 +41911,10 @@ static PyObject *__pyx_pf_9pywrapfst_52shortestdistance(CYTHON_UNUSED PyObject *
   __pyx_t_2.nstate = __pyx_v_nstate;
   __pyx_t_2.queue_type = __pyx_v_queue_type;
   __pyx_t_2.reverse = __pyx_v_reverse;
-  __pyx_t_1 = __pyx_f_9pywrapfst__shortestdistance(__pyx_v_ifst, &__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4024, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst__shortestdistance(__pyx_v_ifst, &__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4088, __pyx_L1_error)
   __pyx_v_distance.reset(__pyx_t_1);
 
-  /* "pywrapfst.pyx":4025
+  /* "pywrapfst.pyx":4089
  *   cdef unique_ptr[vector[fst.WeightClass]] distance
  *   distance.reset(_shortestdistance(ifst, delta, nstate, queue_type, reverse))
  *   cdef string weight_type = ifst.weight_type()             # <<<<<<<<<<<<<<
@@ -41024,11 +41923,11 @@ static PyObject *__pyx_pf_9pywrapfst_52shortestdistance(CYTHON_UNUSED PyObject *
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 4025, __pyx_L1_error)
+    __PYX_ERR(0, 4089, __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":4026
+  /* "pywrapfst.pyx":4090
  *   distance.reset(_shortestdistance(ifst, delta, nstate, queue_type, reverse))
  *   cdef string weight_type = ifst.weight_type()
  *   return [Weight(weight_type, weight.ToString()) for weight in deref(distance)]             # <<<<<<<<<<<<<<
@@ -41037,7 +41936,7 @@ static PyObject *__pyx_pf_9pywrapfst_52shortestdistance(CYTHON_UNUSED PyObject *
  */
   __Pyx_XDECREF(__pyx_r);
   { /* enter inner scope */
-    __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4026, __pyx_L1_error)
+    __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4090, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_1 = &(*__pyx_v_distance);
     __pyx_t_4 = __pyx_t_1->begin();
@@ -41046,11 +41945,11 @@ static PyObject *__pyx_pf_9pywrapfst_52shortestdistance(CYTHON_UNUSED PyObject *
       __pyx_t_5 = *__pyx_t_4;
       ++__pyx_t_4;
       __pyx_7genexpr__pyx_v_weight = __pyx_t_5;
-      __pyx_t_6 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_weight_type); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4026, __pyx_L1_error)
+      __pyx_t_6 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_weight_type); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4090, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_6);
-      __pyx_t_7 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_7genexpr__pyx_v_weight.ToString()); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4026, __pyx_L1_error)
+      __pyx_t_7 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_7genexpr__pyx_v_weight.ToString()); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4090, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_7);
-      __pyx_t_8 = PyTuple_New(2); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 4026, __pyx_L1_error)
+      __pyx_t_8 = PyTuple_New(2); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 4090, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_GIVEREF(__pyx_t_6);
       PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6);
@@ -41058,10 +41957,10 @@ static PyObject *__pyx_pf_9pywrapfst_52shortestdistance(CYTHON_UNUSED PyObject *
       PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_7);
       __pyx_t_6 = 0;
       __pyx_t_7 = 0;
-      __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_t_8, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4026, __pyx_L1_error)
+      __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_t_8, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4090, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_7);
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-      if (unlikely(__Pyx_ListComp_Append(__pyx_t_3, (PyObject*)__pyx_t_7))) __PYX_ERR(0, 4026, __pyx_L1_error)
+      if (unlikely(__Pyx_ListComp_Append(__pyx_t_3, (PyObject*)__pyx_t_7))) __PYX_ERR(0, 4090, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     }
   } /* exit inner scope */
@@ -41069,7 +41968,7 @@ static PyObject *__pyx_pf_9pywrapfst_52shortestdistance(CYTHON_UNUSED PyObject *
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3992
+  /* "pywrapfst.pyx":4056
  * 
  * 
  * def shortestdistance(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -41091,7 +41990,7 @@ static PyObject *__pyx_pf_9pywrapfst_52shortestdistance(CYTHON_UNUSED PyObject *
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4029
+/* "pywrapfst.pyx":4093
  * 
  * 
  * cpdef _MutableFst shortestpath(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -41099,14 +41998,14 @@ static PyObject *__pyx_pf_9pywrapfst_52shortestdistance(CYTHON_UNUSED PyObject *
  *                                int32 nshortest=1,
  */
 
-static PyObject *__pyx_pw_9pywrapfst_55shortestpath(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_57shortestpath(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__50;
+  float __pyx_v_delta = __pyx_k__48;
   __pyx_t_10basictypes_int32 __pyx_v_nshortest = ((__pyx_t_10basictypes_int32)1);
-  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__51;
+  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__49;
   PyObject *__pyx_v_queue_type = ((PyObject *)__pyx_n_b_auto);
 
-  /* "pywrapfst.pyx":4034
+  /* "pywrapfst.pyx":4098
  *                                int64 nstate=fst.kNoStateId,
  *                                queue_type=b"auto",
  *                                bool unique=False,             # <<<<<<<<<<<<<<
@@ -41115,7 +42014,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_shortestpath(
  */
   bool __pyx_v_unique = ((bool)0);
 
-  /* "pywrapfst.pyx":4035
+  /* "pywrapfst.pyx":4099
  *                                queue_type=b"auto",
  *                                bool unique=False,
  *                                weight=None):             # <<<<<<<<<<<<<<
@@ -41154,7 +42053,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_shortestpath(
     }
   }
 
-  /* "pywrapfst.pyx":4067
+  /* "pywrapfst.pyx":4131
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -41163,11 +42062,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_shortestpath(
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 4067, __pyx_L1_error)
+    __PYX_ERR(0, 4131, __pyx_L1_error)
   }
   __pyx_v_tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
 
-  /* "pywrapfst.pyx":4069
+  /* "pywrapfst.pyx":4133
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   # Threshold is set to semiring Zero (no pruning) if no weight is specified.
  *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)             # <<<<<<<<<<<<<<
@@ -41176,58 +42075,58 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_shortestpath(
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 4069, __pyx_L1_error)
+    __PYX_ERR(0, 4133, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_Zero(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4069, __pyx_L1_error)
+  __pyx_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, 4133, __pyx_L1_error)
   __pyx_v_wc = __pyx_t_1;
 
-  /* "pywrapfst.pyx":4071
+  /* "pywrapfst.pyx":4135
  *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)
  *   cdef unique_ptr[fst.ShortestPathOptions] opts
  *   opts.reset(new fst.ShortestPathOptions(_get_queue_type(tostring(queue_type)),             # <<<<<<<<<<<<<<
- *                                          nshortest, unique, delta, wc, nstate))
- *   fst.ShortestPath(deref(ifst._fst), tfst.get(), deref(opts))
+ *                                          nshortest,
+ *                                          unique,
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_queue_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4071, __pyx_L1_error)
-  __pyx_t_3 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4071, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_queue_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4135, __pyx_L1_error)
+  __pyx_t_3 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4135, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4072
- *   cdef unique_ptr[fst.ShortestPathOptions] opts
- *   opts.reset(new fst.ShortestPathOptions(_get_queue_type(tostring(queue_type)),
- *                                          nshortest, unique, delta, wc, nstate))             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":4140
+ *                                          delta,
+ *                                          wc,
+ *                                          nstate))             # <<<<<<<<<<<<<<
  *   fst.ShortestPath(deref(ifst._fst), tfst.get(), deref(opts))
  *   return _init_MutableFst(tfst.release())
  */
   __pyx_v_opts.reset(new fst::script::ShortestPathOptions(__pyx_t_3, __pyx_v_nshortest, __pyx_v_unique, __pyx_v_delta, __pyx_v_wc, __pyx_v_nstate));
 
-  /* "pywrapfst.pyx":4073
- *   opts.reset(new fst.ShortestPathOptions(_get_queue_type(tostring(queue_type)),
- *                                          nshortest, unique, delta, wc, nstate))
+  /* "pywrapfst.pyx":4141
+ *                                          wc,
+ *                                          nstate))
  *   fst.ShortestPath(deref(ifst._fst), tfst.get(), deref(opts))             # <<<<<<<<<<<<<<
  *   return _init_MutableFst(tfst.release())
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 4073, __pyx_L1_error)
+    __PYX_ERR(0, 4141, __pyx_L1_error)
   }
   fst::script::ShortestPath((*__pyx_v_ifst->_fst), __pyx_v_tfst.get(), (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":4074
- *                                          nshortest, unique, delta, wc, nstate))
+  /* "pywrapfst.pyx":4142
+ *                                          nstate))
  *   fst.ShortestPath(deref(ifst._fst), tfst.get(), deref(opts))
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_4 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4074, __pyx_L1_error)
+  __pyx_t_4 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4142, __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":4029
+  /* "pywrapfst.pyx":4093
  * 
  * 
  * cpdef _MutableFst shortestpath(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -41247,9 +42146,9 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_shortestpath(
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_55shortestpath(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_54shortestpath[] = "\n  shortestpath(ifst, delta=1e-6, nshortest=1, nstate=NO_STATE_ID,\n               queue_type=\"auto\", unique=False, weight=None)\n\n  Construct an FST containing the shortest path(s) in the input FST.\n\n  This operation produces an FST containing the n-shortest paths in the input\n  FST. The n-shortest paths are the n-lowest weight paths w.r.t. the natural\n  semiring order. The single path that can be read from the ith of at most n\n  transitions leaving the initial state of the resulting FST is the ith\n  shortest path. The weights need to be right distributive and have the path\n  property. They also need to be left distributive as well for n-shortest with\n  n > 1 (e.g., TropicalWeight).\n\n  Args:\n    ifst: The input FST.\n    delta: Comparison/quantization delta.\n    nshortest: The number of paths to return.\n    nstate: State number threshold.\n    queue_type: A string matching a known queue type; one of: \"auto\", \"fifo\",\n        \"lifo\", \"shortest\", \"state\", \"top\".\n    unique: Should the resulting FST only contain distinct paths? (Requires\n        the input FST to be an acceptor; epsilons are treated as if they are\n        regular symbols.)\n    weight: A Weight or weight string indicating the desired weight threshold\n        below which paths are pruned; if omitted, no paths are pruned.\n\n  Returns:\n    An FST containing the n-shortest paths.\n  ";
-static PyObject *__pyx_pw_9pywrapfst_55shortestpath(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_57shortestpath(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_56shortestpath[] = "\n  shortestpath(ifst, delta=1e-6, nshortest=1, nstate=NO_STATE_ID,\n               queue_type=\"auto\", unique=False, weight=None)\n\n  Construct an FST containing the shortest path(s) in the input FST.\n\n  This operation produces an FST containing the n-shortest paths in the input\n  FST. The n-shortest paths are the n-lowest weight paths w.r.t. the natural\n  semiring order. The single path that can be read from the ith of at most n\n  transitions leaving the initial state of the resulting FST is the ith\n  shortest path. The weights need to be right distributive and have the path\n  property. They also need to be left distributive as well for n-shortest with\n  n > 1 (e.g., TropicalWeight).\n\n  Args:\n    ifst: The input FST.\n    delta: Comparison/quantization delta.\n    nshortest: The number of paths to return.\n    nstate: State number threshold.\n    queue_type: A string matching a known queue type; one of: \"auto\", \"fifo\",\n        \"lifo\", \"shortest\", \"state\", \"top\".\n    unique: Should the resulting FST only contain distinct paths? (Requires\n        the input FST to be an acceptor; epsilons are treated as if they are\n        regular symbols.)\n    weight: A Weight or weight string indicating the desired weight threshold\n        below which paths are pruned; if omitted, no paths are pruned.\n\n  Returns:\n    An FST containing the n-shortest paths.\n  ";
+static PyObject *__pyx_pw_9pywrapfst_57shortestpath(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst = 0;
   float __pyx_v_delta;
   __pyx_t_10basictypes_int32 __pyx_v_nshortest;
@@ -41265,7 +42164,7 @@ static PyObject *__pyx_pw_9pywrapfst_55shortestpath(PyObject *__pyx_self, PyObje
     PyObject* values[7] = {0,0,0,0,0,0,0};
     values[4] = ((PyObject *)__pyx_n_b_auto);
 
-    /* "pywrapfst.pyx":4035
+    /* "pywrapfst.pyx":4099
  *                                queue_type=b"auto",
  *                                bool unique=False,
  *                                weight=None):             # <<<<<<<<<<<<<<
@@ -41337,7 +42236,7 @@ static PyObject *__pyx_pw_9pywrapfst_55shortestpath(PyObject *__pyx_self, PyObje
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "shortestpath") < 0)) __PYX_ERR(0, 4029, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "shortestpath") < 0)) __PYX_ERR(0, 4093, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -41360,26 +42259,26 @@ static PyObject *__pyx_pw_9pywrapfst_55shortestpath(PyObject *__pyx_self, PyObje
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
     if (values[1]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 4030, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 4094, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__50;
+      __pyx_v_delta = __pyx_k__48;
     }
     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, 4031, __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, 4095, __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, 4032, __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, 4096, __pyx_L3_error)
     } else {
-      __pyx_v_nstate = __pyx_k__51;
+      __pyx_v_nstate = __pyx_k__49;
     }
     __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, 4034, __pyx_L3_error)
+      __pyx_v_unique = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_unique == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4098, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4034
+      /* "pywrapfst.pyx":4098
  *                                int64 nstate=fst.kNoStateId,
  *                                queue_type=b"auto",
  *                                bool unique=False,             # <<<<<<<<<<<<<<
@@ -41392,16 +42291,16 @@ static PyObject *__pyx_pw_9pywrapfst_55shortestpath(PyObject *__pyx_self, PyObje
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("shortestpath", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4029, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("shortestpath", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4093, __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, 4029, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_54shortestpath(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_nshortest, __pyx_v_nstate, __pyx_v_queue_type, __pyx_v_unique, __pyx_v_weight);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 4093, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_56shortestpath(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_nshortest, __pyx_v_nstate, __pyx_v_queue_type, __pyx_v_unique, __pyx_v_weight);
 
-  /* "pywrapfst.pyx":4029
+  /* "pywrapfst.pyx":4093
  * 
  * 
  * cpdef _MutableFst shortestpath(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -41418,7 +42317,7 @@ static PyObject *__pyx_pw_9pywrapfst_55shortestpath(PyObject *__pyx_self, PyObje
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_54shortestpath(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, __pyx_t_10basictypes_int32 __pyx_v_nshortest, __pyx_t_10basictypes_int64 __pyx_v_nstate, PyObject *__pyx_v_queue_type, bool __pyx_v_unique, PyObject *__pyx_v_weight) {
+static PyObject *__pyx_pf_9pywrapfst_56shortestpath(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, __pyx_t_10basictypes_int32 __pyx_v_nshortest, __pyx_t_10basictypes_int64 __pyx_v_nstate, PyObject *__pyx_v_queue_type, bool __pyx_v_unique, PyObject *__pyx_v_weight) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -41432,7 +42331,7 @@ static PyObject *__pyx_pf_9pywrapfst_54shortestpath(CYTHON_UNUSED PyObject *__py
   __pyx_t_2.queue_type = __pyx_v_queue_type;
   __pyx_t_2.unique = __pyx_v_unique;
   __pyx_t_2.weight = __pyx_v_weight;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_shortestpath(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4029, __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, 4093, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -41449,7 +42348,7 @@ static PyObject *__pyx_pf_9pywrapfst_54shortestpath(CYTHON_UNUSED PyObject *__py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4077
+/* "pywrapfst.pyx":4145
  * 
  * 
  * cpdef _Fst statemap(_Fst ifst, map_type):             # <<<<<<<<<<<<<<
@@ -41457,7 +42356,7 @@ static PyObject *__pyx_pf_9pywrapfst_54shortestpath(CYTHON_UNUSED PyObject *__py
  *   state_map(ifst, map_type)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_57statemap(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_59statemap(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_statemap(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, PyObject *__pyx_v_map_type, CYTHON_UNUSED int __pyx_skip_dispatch) {
   struct __pyx_obj_9pywrapfst__Fst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
@@ -41465,8 +42364,8 @@ 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":4102
- *   See also: `arcmap`.
+  /* "pywrapfst.pyx":4168
+ *     FstArgError: Unknown map type.
  *   """
  *   return _map(ifst, fst.kDelta, map_type, 1., None)             # <<<<<<<<<<<<<<
  * 
@@ -41478,13 +42377,13 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_statemap(struct __py
   __pyx_t_2.map_type = __pyx_v_map_type;
   __pyx_t_2.power = 1.;
   __pyx_t_2.weight = Py_None;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__map(__pyx_v_ifst, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4102, __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, 4168, __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":4077
+  /* "pywrapfst.pyx":4145
  * 
  * 
  * cpdef _Fst statemap(_Fst ifst, map_type):             # <<<<<<<<<<<<<<
@@ -41504,9 +42403,9 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_statemap(struct __py
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_57statemap(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_56statemap[] = "\n  state_map(ifst, map_type)\n\n  Constructively applies a transform to all states.\n\n  This operation transforms each state using one of the following:\n\n    * arc_sum: sums weights of identically-labeled multi-arcs.\n    * arc_unique: deletes non-unique identically-labeled multi-arcs.\n    * identity: maps to self.\n\n  Args:\n    ifst: The input FST.\n    map_type: A string matching a known mapping operation; one of: \"arc_sum\",\n        \"arc_unique\", \"identity\".\n\n  Returns:\n    An FST with states remapped.\n\n  Raises:\n    FstArgError: Unknown map type.\n\n  See also: `arcmap`.\n  ";
-static PyObject *__pyx_pw_9pywrapfst_57statemap(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_59statemap(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_58statemap[] = "\n  state_map(ifst, map_type)\n\n  Constructively applies a transform to all states.\n\n  This operation transforms each state using one of the following:\n\n    * arc_sum: sums weights of identically-labeled multi-arcs.\n    * arc_unique: deletes non-unique identically-labeled multi-arcs.\n    * identity: maps to self.\n\n  Args:\n    ifst: The input FST.\n    map_type: A string matching a known mapping operation; one of: \"arc_sum\",\n        \"arc_unique\", \"identity\".\n\n  Returns:\n    An FST with states remapped.\n\n  Raises:\n    FstArgError: Unknown map type.\n  ";
+static PyObject *__pyx_pw_9pywrapfst_59statemap(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst = 0;
   PyObject *__pyx_v_map_type = 0;
   PyObject *__pyx_r = 0;
@@ -41535,11 +42434,11 @@ static PyObject *__pyx_pw_9pywrapfst_57statemap(PyObject *__pyx_self, PyObject *
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_map_type)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("statemap", 1, 2, 2, 1); __PYX_ERR(0, 4077, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("statemap", 1, 2, 2, 1); __PYX_ERR(0, 4145, __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, 4077, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "statemap") < 0)) __PYX_ERR(0, 4145, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -41552,14 +42451,14 @@ static PyObject *__pyx_pw_9pywrapfst_57statemap(PyObject *__pyx_self, PyObject *
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("statemap", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4077, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("statemap", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4145, __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, 4077, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_56statemap(__pyx_self, __pyx_v_ifst, __pyx_v_map_type);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 4145, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_58statemap(__pyx_self, __pyx_v_ifst, __pyx_v_map_type);
 
   /* function exit code */
   goto __pyx_L0;
@@ -41570,13 +42469,13 @@ static PyObject *__pyx_pw_9pywrapfst_57statemap(PyObject *__pyx_self, PyObject *
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_56statemap(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, PyObject *__pyx_v_map_type) {
+static PyObject *__pyx_pf_9pywrapfst_58statemap(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, PyObject *__pyx_v_map_type) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   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, 4077, __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, 4145, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -41593,7 +42492,7 @@ static PyObject *__pyx_pf_9pywrapfst_56statemap(CYTHON_UNUSED PyObject *__pyx_se
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4105
+/* "pywrapfst.pyx":4171
  * 
  * 
  * cpdef _MutableFst synchronize(_Fst ifst):             # <<<<<<<<<<<<<<
@@ -41601,7 +42500,7 @@ static PyObject *__pyx_pf_9pywrapfst_56statemap(CYTHON_UNUSED PyObject *__pyx_se
  *   synchronize(ifst)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_59synchronize(PyObject *__pyx_self, PyObject *__pyx_v_ifst); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_61synchronize(PyObject *__pyx_self, PyObject *__pyx_v_ifst); /*proto*/
 static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_synchronize(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, CYTHON_UNUSED int __pyx_skip_dispatch) {
   std::unique_ptr<fst::script::VectorFstClass>  __pyx_v_tfst;
   struct __pyx_obj_9pywrapfst__MutableFst *__pyx_r = NULL;
@@ -41609,7 +42508,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_synchronize(s
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("synchronize", 0);
 
-  /* "pywrapfst.pyx":4125
+  /* "pywrapfst.pyx":4191
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -41618,11 +42517,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_synchronize(s
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 4125, __pyx_L1_error)
+    __PYX_ERR(0, 4191, __pyx_L1_error)
   }
   __pyx_v_tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
 
-  /* "pywrapfst.pyx":4126
+  /* "pywrapfst.pyx":4192
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   fst.Synchronize(deref(ifst._fst), tfst.get())             # <<<<<<<<<<<<<<
@@ -41631,11 +42530,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_synchronize(s
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 4126, __pyx_L1_error)
+    __PYX_ERR(0, 4192, __pyx_L1_error)
   }
   fst::script::Synchronize((*__pyx_v_ifst->_fst), __pyx_v_tfst.get());
 
-  /* "pywrapfst.pyx":4127
+  /* "pywrapfst.pyx":4193
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   fst.Synchronize(deref(ifst._fst), tfst.get())
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -41643,13 +42542,13 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_synchronize(s
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4127, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4193, __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":4105
+  /* "pywrapfst.pyx":4171
  * 
  * 
  * cpdef _MutableFst synchronize(_Fst ifst):             # <<<<<<<<<<<<<<
@@ -41669,14 +42568,14 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_synchronize(s
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_59synchronize(PyObject *__pyx_self, PyObject *__pyx_v_ifst); /*proto*/
-static char __pyx_doc_9pywrapfst_58synchronize[] = "\n  synchronize(ifst)\n\n  Constructively synchronizes an FST.\n\n  This operation synchronizes a transducer. The result will be an equivalent\n  FST that has the property that during the traversal of a path, the delay is\n  either zero or strictly increasing, where the delay is the difference between\n  the number of non-epsilon output labels and input labels along the path. For\n  the algorithm to terminate, the input transducer must have bounded delay,\n  i.e., the delay of every cycle must be zero.\n\n  Args:\n    ifst: The input FST.\n\n  Returns:\n    An equivalent synchronized FST.\n  ";
-static PyObject *__pyx_pw_9pywrapfst_59synchronize(PyObject *__pyx_self, PyObject *__pyx_v_ifst) {
+static PyObject *__pyx_pw_9pywrapfst_61synchronize(PyObject *__pyx_self, PyObject *__pyx_v_ifst); /*proto*/
+static char __pyx_doc_9pywrapfst_60synchronize[] = "\n  synchronize(ifst)\n\n  Constructively synchronizes an FST.\n\n  This operation synchronizes a transducer. The result will be an equivalent\n  FST that has the property that during the traversal of a path, the delay is\n  either zero or strictly increasing, where the delay is the difference between\n  the number of non-epsilon output labels and input labels along the path. For\n  the algorithm to terminate, the input transducer must have bounded delay,\n  i.e., the delay of every cycle must be zero.\n\n  Args:\n    ifst: The input FST.\n\n  Returns:\n    An equivalent synchronized FST.\n  ";
+static PyObject *__pyx_pw_9pywrapfst_61synchronize(PyObject *__pyx_self, PyObject *__pyx_v_ifst) {
   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, 4105, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_58synchronize(__pyx_self, ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_ifst));
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 4171, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_60synchronize(__pyx_self, ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_ifst));
 
   /* function exit code */
   goto __pyx_L0;
@@ -41687,13 +42586,13 @@ static PyObject *__pyx_pw_9pywrapfst_59synchronize(PyObject *__pyx_self, PyObjec
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_58synchronize(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst) {
+static PyObject *__pyx_pf_9pywrapfst_60synchronize(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   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, 4105, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_synchronize(__pyx_v_ifst, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4171, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -41710,7 +42609,7 @@ static PyObject *__pyx_pf_9pywrapfst_58synchronize(CYTHON_UNUSED PyObject *__pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4184
+/* "pywrapfst.pyx":4250
  *   """
  * 
  *   def __cinit__(self,             # <<<<<<<<<<<<<<
@@ -41738,7 +42637,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":4187
+    /* "pywrapfst.pyx":4253
  *                 string fst_type=b"vector",
  *                 string arc_type=b"standard",
  *                 SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
@@ -41747,7 +42646,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":4188
+    /* "pywrapfst.pyx":4254
  *                 string arc_type=b"standard",
  *                 SymbolTable isymbols=None,
  *                 SymbolTable osymbols=None,             # <<<<<<<<<<<<<<
@@ -41756,7 +42655,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":4189
+    /* "pywrapfst.pyx":4255
  *                 SymbolTable isymbols=None,
  *                 SymbolTable osymbols=None,
  *                 SymbolTable ssymbols=None,             # <<<<<<<<<<<<<<
@@ -41854,7 +42753,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, 4184, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(0, 4250, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -41883,23 +42782,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, 4185, __pyx_L3_error)
+      __pyx_v_fst_type = __pyx_convert_string_from_py_std__in_string(values[0]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4251, __pyx_L3_error)
     } else {
-      __pyx_v_fst_type = __pyx_k__52;
+      __pyx_v_fst_type = __pyx_k__50;
     }
     if (values[1]) {
-      __pyx_v_arc_type = __pyx_convert_string_from_py_std__in_string(values[1]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4186, __pyx_L3_error)
+      __pyx_v_arc_type = __pyx_convert_string_from_py_std__in_string(values[1]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4252, __pyx_L3_error)
     } else {
-      __pyx_v_arc_type = __pyx_k__53;
+      __pyx_v_arc_type = __pyx_k__51;
     }
     __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, 4190, __pyx_L3_error)
+      __pyx_v_acceptor = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_acceptor == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4256, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4190
+      /* "pywrapfst.pyx":4256
  *                 SymbolTable osymbols=None,
  *                 SymbolTable ssymbols=None,
  *                 bool acceptor=False,             # <<<<<<<<<<<<<<
@@ -41909,10 +42808,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, 4191, __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, 4257, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4191
+      /* "pywrapfst.pyx":4257
  *                 SymbolTable ssymbols=None,
  *                 bool acceptor=False,
  *                 bool keep_isymbols=False,             # <<<<<<<<<<<<<<
@@ -41922,10 +42821,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, 4192, __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, 4258, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4192
+      /* "pywrapfst.pyx":4258
  *                 bool acceptor=False,
  *                 bool keep_isymbols=False,
  *                 bool keep_osymbols=False,             # <<<<<<<<<<<<<<
@@ -41935,10 +42834,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, 4193, __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, 4259, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4193
+      /* "pywrapfst.pyx":4259
  *                 bool keep_isymbols=False,
  *                 bool keep_osymbols=False,
  *                 bool keep_state_numbering=False,             # <<<<<<<<<<<<<<
@@ -41948,10 +42847,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, 4194, __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, 4260, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4194
+      /* "pywrapfst.pyx":4260
  *                 bool keep_osymbols=False,
  *                 bool keep_state_numbering=False,
  *                 bool allow_negative_labels=False):             # <<<<<<<<<<<<<<
@@ -41963,18 +42862,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, 4184, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 0, 10, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4250, __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, 4187, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_osymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "osymbols", 0))) __PYX_ERR(0, 4188, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ssymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "ssymbols", 0))) __PYX_ERR(0, 4189, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_isymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "isymbols", 0))) __PYX_ERR(0, 4253, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_osymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "osymbols", 0))) __PYX_ERR(0, 4254, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ssymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "ssymbols", 0))) __PYX_ERR(0, 4255, __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":4184
+  /* "pywrapfst.pyx":4250
  *   """
  * 
  *   def __cinit__(self,             # <<<<<<<<<<<<<<
@@ -42001,7 +42900,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
   fst::SymbolTable *__pyx_t_5;
   __Pyx_RefNannySetupContext("__cinit__", 0);
 
-  /* "pywrapfst.pyx":4195
+  /* "pywrapfst.pyx":4261
  *                 bool keep_state_numbering=False,
  *                 bool allow_negative_labels=False):
  *     self._sstrm.reset(new stringstream())             # <<<<<<<<<<<<<<
@@ -42010,45 +42909,45 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_sstrm");
-    __PYX_ERR(0, 4195, __pyx_L1_error)
+    __PYX_ERR(0, 4261, __pyx_L1_error)
   }
   __pyx_v_self->_sstrm.reset(new std::stringstream());
 
-  /* "pywrapfst.pyx":4196
+  /* "pywrapfst.pyx":4262
  *                 bool allow_negative_labels=False):
  *     self._sstrm.reset(new stringstream())
  *     self._fst_type = tostring(fst_type)             # <<<<<<<<<<<<<<
  *     self._arc_type = tostring(arc_type)
  *     self._isymbols = NULL
  */
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_fst_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4196, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_fst_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4262, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4196, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4262, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst_type");
-    __PYX_ERR(0, 4196, __pyx_L1_error)
+    __PYX_ERR(0, 4262, __pyx_L1_error)
   }
   __pyx_v_self->_fst_type = __pyx_t_2;
 
-  /* "pywrapfst.pyx":4197
+  /* "pywrapfst.pyx":4263
  *     self._sstrm.reset(new stringstream())
  *     self._fst_type = tostring(fst_type)
  *     self._arc_type = tostring(arc_type)             # <<<<<<<<<<<<<<
  *     self._isymbols = NULL
  *     if isymbols is not None:
  */
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4197, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4263, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4197, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4263, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc_type");
-    __PYX_ERR(0, 4197, __pyx_L1_error)
+    __PYX_ERR(0, 4263, __pyx_L1_error)
   }
   __pyx_v_self->_arc_type = __pyx_t_2;
 
-  /* "pywrapfst.pyx":4198
+  /* "pywrapfst.pyx":4264
  *     self._fst_type = tostring(fst_type)
  *     self._arc_type = tostring(arc_type)
  *     self._isymbols = NULL             # <<<<<<<<<<<<<<
@@ -42057,11 +42956,11 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_isymbols");
-    __PYX_ERR(0, 4198, __pyx_L1_error)
+    __PYX_ERR(0, 4264, __pyx_L1_error)
   }
   __pyx_v_self->_isymbols = NULL;
 
-  /* "pywrapfst.pyx":4199
+  /* "pywrapfst.pyx":4265
  *     self._arc_type = tostring(arc_type)
  *     self._isymbols = NULL
  *     if isymbols is not None:             # <<<<<<<<<<<<<<
@@ -42072,7 +42971,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":4200
+    /* "pywrapfst.pyx":4266
  *     self._isymbols = NULL
  *     if isymbols is not None:
  *       self._isymbols = isymbols._table             # <<<<<<<<<<<<<<
@@ -42081,16 +42980,16 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
     if (unlikely(((PyObject *)__pyx_v_isymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 4200, __pyx_L1_error)
+      __PYX_ERR(0, 4266, __pyx_L1_error)
     }
     __pyx_t_5 = __pyx_v_isymbols->__pyx_base.__pyx_base._table;
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_isymbols");
-      __PYX_ERR(0, 4200, __pyx_L1_error)
+      __PYX_ERR(0, 4266, __pyx_L1_error)
     }
     __pyx_v_self->_isymbols = __pyx_t_5;
 
-    /* "pywrapfst.pyx":4199
+    /* "pywrapfst.pyx":4265
  *     self._arc_type = tostring(arc_type)
  *     self._isymbols = NULL
  *     if isymbols is not None:             # <<<<<<<<<<<<<<
@@ -42099,7 +42998,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   }
 
-  /* "pywrapfst.pyx":4201
+  /* "pywrapfst.pyx":4267
  *     if isymbols is not None:
  *       self._isymbols = isymbols._table
  *     self._osymbols = NULL             # <<<<<<<<<<<<<<
@@ -42108,11 +43007,11 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_osymbols");
-    __PYX_ERR(0, 4201, __pyx_L1_error)
+    __PYX_ERR(0, 4267, __pyx_L1_error)
   }
   __pyx_v_self->_osymbols = NULL;
 
-  /* "pywrapfst.pyx":4202
+  /* "pywrapfst.pyx":4268
  *       self._isymbols = isymbols._table
  *     self._osymbols = NULL
  *     if osymbols is not None:             # <<<<<<<<<<<<<<
@@ -42123,7 +43022,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":4203
+    /* "pywrapfst.pyx":4269
  *     self._osymbols = NULL
  *     if osymbols is not None:
  *       self._osymbols = osymbols._table             # <<<<<<<<<<<<<<
@@ -42132,16 +43031,16 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
     if (unlikely(((PyObject *)__pyx_v_osymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 4203, __pyx_L1_error)
+      __PYX_ERR(0, 4269, __pyx_L1_error)
     }
     __pyx_t_5 = __pyx_v_osymbols->__pyx_base.__pyx_base._table;
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_osymbols");
-      __PYX_ERR(0, 4203, __pyx_L1_error)
+      __PYX_ERR(0, 4269, __pyx_L1_error)
     }
     __pyx_v_self->_osymbols = __pyx_t_5;
 
-    /* "pywrapfst.pyx":4202
+    /* "pywrapfst.pyx":4268
  *       self._isymbols = isymbols._table
  *     self._osymbols = NULL
  *     if osymbols is not None:             # <<<<<<<<<<<<<<
@@ -42150,7 +43049,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   }
 
-  /* "pywrapfst.pyx":4204
+  /* "pywrapfst.pyx":4270
  *     if osymbols is not None:
  *       self._osymbols = osymbols._table
  *     self._ssymbols = NULL             # <<<<<<<<<<<<<<
@@ -42159,11 +43058,11 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_ssymbols");
-    __PYX_ERR(0, 4204, __pyx_L1_error)
+    __PYX_ERR(0, 4270, __pyx_L1_error)
   }
   __pyx_v_self->_ssymbols = NULL;
 
-  /* "pywrapfst.pyx":4205
+  /* "pywrapfst.pyx":4271
  *       self._osymbols = osymbols._table
  *     self._ssymbols = NULL
  *     if ssymbols is not None:             # <<<<<<<<<<<<<<
@@ -42174,7 +43073,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":4206
+    /* "pywrapfst.pyx":4272
  *     self._ssymbols = NULL
  *     if ssymbols is not None:
  *       self._ssymbols = ssymbols._table             # <<<<<<<<<<<<<<
@@ -42183,16 +43082,16 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
     if (unlikely(((PyObject *)__pyx_v_ssymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 4206, __pyx_L1_error)
+      __PYX_ERR(0, 4272, __pyx_L1_error)
     }
     __pyx_t_5 = __pyx_v_ssymbols->__pyx_base.__pyx_base._table;
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_ssymbols");
-      __PYX_ERR(0, 4206, __pyx_L1_error)
+      __PYX_ERR(0, 4272, __pyx_L1_error)
     }
     __pyx_v_self->_ssymbols = __pyx_t_5;
 
-    /* "pywrapfst.pyx":4205
+    /* "pywrapfst.pyx":4271
  *       self._osymbols = osymbols._table
  *     self._ssymbols = NULL
  *     if ssymbols is not None:             # <<<<<<<<<<<<<<
@@ -42201,7 +43100,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   }
 
-  /* "pywrapfst.pyx":4207
+  /* "pywrapfst.pyx":4273
  *     if ssymbols is not None:
  *       self._ssymbols = ssymbols._table
  *     self._acceptor = acceptor             # <<<<<<<<<<<<<<
@@ -42210,11 +43109,11 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_acceptor");
-    __PYX_ERR(0, 4207, __pyx_L1_error)
+    __PYX_ERR(0, 4273, __pyx_L1_error)
   }
   __pyx_v_self->_acceptor = __pyx_v_acceptor;
 
-  /* "pywrapfst.pyx":4208
+  /* "pywrapfst.pyx":4274
  *       self._ssymbols = ssymbols._table
  *     self._acceptor = acceptor
  *     self._keep_isymbols = keep_isymbols             # <<<<<<<<<<<<<<
@@ -42223,11 +43122,11 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_keep_isymbols");
-    __PYX_ERR(0, 4208, __pyx_L1_error)
+    __PYX_ERR(0, 4274, __pyx_L1_error)
   }
   __pyx_v_self->_keep_isymbols = __pyx_v_keep_isymbols;
 
-  /* "pywrapfst.pyx":4209
+  /* "pywrapfst.pyx":4275
  *     self._acceptor = acceptor
  *     self._keep_isymbols = keep_isymbols
  *     self._keep_osymbols = keep_osymbols             # <<<<<<<<<<<<<<
@@ -42236,11 +43135,11 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_keep_osymbols");
-    __PYX_ERR(0, 4209, __pyx_L1_error)
+    __PYX_ERR(0, 4275, __pyx_L1_error)
   }
   __pyx_v_self->_keep_osymbols = __pyx_v_keep_osymbols;
 
-  /* "pywrapfst.pyx":4210
+  /* "pywrapfst.pyx":4276
  *     self._keep_isymbols = keep_isymbols
  *     self._keep_osymbols = keep_osymbols
  *     self._keep_state_numbering = keep_state_numbering             # <<<<<<<<<<<<<<
@@ -42249,11 +43148,11 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_keep_state_numbering");
-    __PYX_ERR(0, 4210, __pyx_L1_error)
+    __PYX_ERR(0, 4276, __pyx_L1_error)
   }
   __pyx_v_self->_keep_state_numbering = __pyx_v_keep_state_numbering;
 
-  /* "pywrapfst.pyx":4211
+  /* "pywrapfst.pyx":4277
  *     self._keep_osymbols = keep_osymbols
  *     self._keep_state_numbering = keep_state_numbering
  *     self._allow_negative_labels = allow_negative_labels             # <<<<<<<<<<<<<<
@@ -42262,11 +43161,11 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_allow_negative_labels");
-    __PYX_ERR(0, 4211, __pyx_L1_error)
+    __PYX_ERR(0, 4277, __pyx_L1_error)
   }
   __pyx_v_self->_allow_negative_labels = __pyx_v_allow_negative_labels;
 
-  /* "pywrapfst.pyx":4184
+  /* "pywrapfst.pyx":4250
  *   """
  * 
  *   def __cinit__(self,             # <<<<<<<<<<<<<<
@@ -42286,7 +43185,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4213
+/* "pywrapfst.pyx":4279
  *     self._allow_negative_labels = allow_negative_labels
  * 
  *   cpdef _Fst compile(self):             # <<<<<<<<<<<<<<
@@ -42314,7 +43213,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_compile); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4213, __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, 4279, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_8Compiler_3compile)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -42331,10 +43230,10 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4213, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4279, __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, 4213, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__Fst))))) __PYX_ERR(0, 4279, __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;
@@ -42353,114 +43252,162 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
     #endif
   }
 
-  /* "pywrapfst.pyx":4228
+  /* "pywrapfst.pyx":4294
  *     """
  *     cdef unique_ptr[fst.FstClass] tfst
  *     tfst.reset(fst.CompileFstInternal(deref(self._sstrm),             # <<<<<<<<<<<<<<
- *         b"<pywrapfst>", self._fst_type, self._arc_type, self._isymbols,
- *         self._osymbols, self._ssymbols, self._acceptor, self._keep_isymbols,
+ *                                       b"<pywrapfst>",
+ *                                       self._fst_type,
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_sstrm");
-    __PYX_ERR(0, 4228, __pyx_L1_error)
+    __PYX_ERR(0, 4294, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4229
- *     cdef unique_ptr[fst.FstClass] tfst
+  /* "pywrapfst.pyx":4296
  *     tfst.reset(fst.CompileFstInternal(deref(self._sstrm),
- *         b"<pywrapfst>", self._fst_type, self._arc_type, self._isymbols,             # <<<<<<<<<<<<<<
- *         self._osymbols, self._ssymbols, self._acceptor, self._keep_isymbols,
- *         self._keep_osymbols, self._keep_state_numbering,
+ *                                       b"<pywrapfst>",
+ *                                       self._fst_type,             # <<<<<<<<<<<<<<
+ *                                       self._arc_type,
+ *                                       self._isymbols,
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst_type");
-    __PYX_ERR(0, 4229, __pyx_L1_error)
+    __PYX_ERR(0, 4296, __pyx_L1_error)
   }
+
+  /* "pywrapfst.pyx":4297
+ *                                       b"<pywrapfst>",
+ *                                       self._fst_type,
+ *                                       self._arc_type,             # <<<<<<<<<<<<<<
+ *                                       self._isymbols,
+ *                                       self._osymbols,
+ */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc_type");
-    __PYX_ERR(0, 4229, __pyx_L1_error)
+    __PYX_ERR(0, 4297, __pyx_L1_error)
   }
+
+  /* "pywrapfst.pyx":4298
+ *                                       self._fst_type,
+ *                                       self._arc_type,
+ *                                       self._isymbols,             # <<<<<<<<<<<<<<
+ *                                       self._osymbols,
+ *                                       self._ssymbols,
+ */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_isymbols");
-    __PYX_ERR(0, 4229, __pyx_L1_error)
+    __PYX_ERR(0, 4298, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4230
- *     tfst.reset(fst.CompileFstInternal(deref(self._sstrm),
- *         b"<pywrapfst>", self._fst_type, self._arc_type, self._isymbols,
- *         self._osymbols, self._ssymbols, self._acceptor, self._keep_isymbols,             # <<<<<<<<<<<<<<
- *         self._keep_osymbols, self._keep_state_numbering,
- *         self._allow_negative_labels))
+  /* "pywrapfst.pyx":4299
+ *                                       self._arc_type,
+ *                                       self._isymbols,
+ *                                       self._osymbols,             # <<<<<<<<<<<<<<
+ *                                       self._ssymbols,
+ *                                       self._acceptor,
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_osymbols");
-    __PYX_ERR(0, 4230, __pyx_L1_error)
+    __PYX_ERR(0, 4299, __pyx_L1_error)
   }
+
+  /* "pywrapfst.pyx":4300
+ *                                       self._isymbols,
+ *                                       self._osymbols,
+ *                                       self._ssymbols,             # <<<<<<<<<<<<<<
+ *                                       self._acceptor,
+ *                                       self._keep_isymbols,
+ */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_ssymbols");
-    __PYX_ERR(0, 4230, __pyx_L1_error)
+    __PYX_ERR(0, 4300, __pyx_L1_error)
   }
+
+  /* "pywrapfst.pyx":4301
+ *                                       self._osymbols,
+ *                                       self._ssymbols,
+ *                                       self._acceptor,             # <<<<<<<<<<<<<<
+ *                                       self._keep_isymbols,
+ *                                       self._keep_osymbols,
+ */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_acceptor");
-    __PYX_ERR(0, 4230, __pyx_L1_error)
+    __PYX_ERR(0, 4301, __pyx_L1_error)
   }
+
+  /* "pywrapfst.pyx":4302
+ *                                       self._ssymbols,
+ *                                       self._acceptor,
+ *                                       self._keep_isymbols,             # <<<<<<<<<<<<<<
+ *                                       self._keep_osymbols,
+ *                                       self._keep_state_numbering,
+ */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_keep_isymbols");
-    __PYX_ERR(0, 4230, __pyx_L1_error)
+    __PYX_ERR(0, 4302, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4231
- *         b"<pywrapfst>", self._fst_type, self._arc_type, self._isymbols,
- *         self._osymbols, self._ssymbols, self._acceptor, self._keep_isymbols,
- *         self._keep_osymbols, self._keep_state_numbering,             # <<<<<<<<<<<<<<
- *         self._allow_negative_labels))
- *     self._sstrm.reset(new stringstream())
+  /* "pywrapfst.pyx":4303
+ *                                       self._acceptor,
+ *                                       self._keep_isymbols,
+ *                                       self._keep_osymbols,             # <<<<<<<<<<<<<<
+ *                                       self._keep_state_numbering,
+ *                                       self._allow_negative_labels))
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_keep_osymbols");
-    __PYX_ERR(0, 4231, __pyx_L1_error)
+    __PYX_ERR(0, 4303, __pyx_L1_error)
   }
+
+  /* "pywrapfst.pyx":4304
+ *                                       self._keep_isymbols,
+ *                                       self._keep_osymbols,
+ *                                       self._keep_state_numbering,             # <<<<<<<<<<<<<<
+ *                                       self._allow_negative_labels))
+ *     self._sstrm.reset(new stringstream())
+ */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_keep_state_numbering");
-    __PYX_ERR(0, 4231, __pyx_L1_error)
+    __PYX_ERR(0, 4304, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4232
- *         self._osymbols, self._ssymbols, self._acceptor, self._keep_isymbols,
- *         self._keep_osymbols, self._keep_state_numbering,
- *         self._allow_negative_labels))             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":4305
+ *                                       self._keep_osymbols,
+ *                                       self._keep_state_numbering,
+ *                                       self._allow_negative_labels))             # <<<<<<<<<<<<<<
  *     self._sstrm.reset(new stringstream())
  *     if tfst.get() == NULL:
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_allow_negative_labels");
-    __PYX_ERR(0, 4232, __pyx_L1_error)
+    __PYX_ERR(0, 4305, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4228
+  /* "pywrapfst.pyx":4294
  *     """
  *     cdef unique_ptr[fst.FstClass] tfst
  *     tfst.reset(fst.CompileFstInternal(deref(self._sstrm),             # <<<<<<<<<<<<<<
- *         b"<pywrapfst>", self._fst_type, self._arc_type, self._isymbols,
- *         self._osymbols, self._ssymbols, self._acceptor, self._keep_isymbols,
+ *                                       b"<pywrapfst>",
+ *                                       self._fst_type,
  */
   __pyx_v_tfst.reset(fst::script::CompileFstInternal((*__pyx_v_self->_sstrm), __pyx_k_pywrapfst, __pyx_v_self->_fst_type, __pyx_v_self->_arc_type, __pyx_v_self->_isymbols, __pyx_v_self->_osymbols, __pyx_v_self->_ssymbols, __pyx_v_self->_acceptor, __pyx_v_self->_keep_isymbols, __pyx_v_self->_keep_osymbols, __pyx_v_self->_keep_state_numbering, __pyx_v_self->_allow_negative_labels));
 
-  /* "pywrapfst.pyx":4233
- *         self._keep_osymbols, self._keep_state_numbering,
- *         self._allow_negative_labels))
+  /* "pywrapfst.pyx":4306
+ *                                       self._keep_state_numbering,
+ *                                       self._allow_negative_labels))
  *     self._sstrm.reset(new stringstream())             # <<<<<<<<<<<<<<
  *     if tfst.get() == NULL:
  *       raise FstOpError("Compilation failed")
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_sstrm");
-    __PYX_ERR(0, 4233, __pyx_L1_error)
+    __PYX_ERR(0, 4306, __pyx_L1_error)
   }
   __pyx_v_self->_sstrm.reset(new std::stringstream());
 
-  /* "pywrapfst.pyx":4234
- *         self._allow_negative_labels))
+  /* "pywrapfst.pyx":4307
+ *                                       self._allow_negative_labels))
  *     self._sstrm.reset(new stringstream())
  *     if tfst.get() == NULL:             # <<<<<<<<<<<<<<
  *       raise FstOpError("Compilation failed")
@@ -42469,14 +43416,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
   __pyx_t_5 = ((__pyx_v_tfst.get() == NULL) != 0);
   if (unlikely(__pyx_t_5)) {
 
-    /* "pywrapfst.pyx":4235
+    /* "pywrapfst.pyx":4308
  *     self._sstrm.reset(new stringstream())
  *     if tfst.get() == NULL:
  *       raise FstOpError("Compilation failed")             # <<<<<<<<<<<<<<
  *     return _init_XFst(tfst.release())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4235, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4308, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_3 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -42490,15 +43437,15 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
     }
     __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_kp_u_Compilation_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_Compilation_failed);
     __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4235, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4308, __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, 4235, __pyx_L1_error)
+    __PYX_ERR(0, 4308, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4234
- *         self._allow_negative_labels))
+    /* "pywrapfst.pyx":4307
+ *                                       self._allow_negative_labels))
  *     self._sstrm.reset(new stringstream())
  *     if tfst.get() == NULL:             # <<<<<<<<<<<<<<
  *       raise FstOpError("Compilation failed")
@@ -42506,7 +43453,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
  */
   }
 
-  /* "pywrapfst.pyx":4236
+  /* "pywrapfst.pyx":4309
  *     if tfst.get() == NULL:
  *       raise FstOpError("Compilation failed")
  *     return _init_XFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -42514,13 +43461,13 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
  *   cpdef void write(self, expression):
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4236, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4309, __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":4213
+  /* "pywrapfst.pyx":4279
  *     self._allow_negative_labels = allow_negative_labels
  * 
  *   cpdef _Fst compile(self):             # <<<<<<<<<<<<<<
@@ -42562,7 +43509,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, 4213, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_8Compiler_compile(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4279, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -42579,7 +43526,7 @@ static PyObject *__pyx_pf_9pywrapfst_8Compiler_2compile(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4238
+/* "pywrapfst.pyx":4311
  *     return _init_XFst(tfst.release())
  * 
  *   cpdef void write(self, expression):             # <<<<<<<<<<<<<<
@@ -42608,7 +43555,7 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4238, __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, 4311, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_8Compiler_5write)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -42624,7 +43571,7 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_expression) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_expression);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4238, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4311, __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;
@@ -42644,17 +43591,17 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
     #endif
   }
 
-  /* "pywrapfst.pyx":4254
+  /* "pywrapfst.pyx":4327
  *       expression: A string expression to add to compiler string buffer.
  *     """
  *     cdef string line = tostring(expression)             # <<<<<<<<<<<<<<
  *     if not line.empty() and line.back() != b'\n':
  *       line.append(b'\n')
  */
-  __pyx_t_5 = __pyx_f_9pywrapfst_tostring(__pyx_v_expression); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4254, __pyx_L1_error)
+  __pyx_t_5 = __pyx_f_9pywrapfst_tostring(__pyx_v_expression); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4327, __pyx_L1_error)
   __pyx_v_line = __pyx_t_5;
 
-  /* "pywrapfst.pyx":4255
+  /* "pywrapfst.pyx":4328
  *     """
  *     cdef string line = tostring(expression)
  *     if not line.empty() and line.back() != b'\n':             # <<<<<<<<<<<<<<
@@ -42672,7 +43619,7 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
   __pyx_L4_bool_binop_done:;
   if (__pyx_t_6) {
 
-    /* "pywrapfst.pyx":4256
+    /* "pywrapfst.pyx":4329
  *     cdef string line = tostring(expression)
  *     if not line.empty() and line.back() != b'\n':
  *       line.append(b'\n')             # <<<<<<<<<<<<<<
@@ -42681,7 +43628,7 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
  */
     (void)(__pyx_v_line.append(((char const *)"\n")));
 
-    /* "pywrapfst.pyx":4255
+    /* "pywrapfst.pyx":4328
  *     """
  *     cdef string line = tostring(expression)
  *     if not line.empty() and line.back() != b'\n':             # <<<<<<<<<<<<<<
@@ -42690,7 +43637,7 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
  */
   }
 
-  /* "pywrapfst.pyx":4257
+  /* "pywrapfst.pyx":4330
  *     if not line.empty() and line.back() != b'\n':
  *       line.append(b'\n')
  *     deref(self._sstrm) << line             # <<<<<<<<<<<<<<
@@ -42699,11 +43646,11 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_sstrm");
-    __PYX_ERR(0, 4257, __pyx_L1_error)
+    __PYX_ERR(0, 4330, __pyx_L1_error)
   }
   (void)(((*__pyx_v_self->_sstrm) << __pyx_v_line));
 
-  /* "pywrapfst.pyx":4238
+  /* "pywrapfst.pyx":4311
  *     return _init_XFst(tfst.release())
  * 
  *   cpdef void write(self, expression):             # <<<<<<<<<<<<<<
@@ -42743,7 +43690,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, 4238, __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, 4311, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -42791,7 +43738,7 @@ static PyObject *__pyx_pf_9pywrapfst_8Compiler_6__reduce_cython__(CYTHON_UNUSED
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__54, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__52, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -42844,7 +43791,7 @@ static PyObject *__pyx_pf_9pywrapfst_8Compiler_8__setstate_cython__(CYTHON_UNUSE
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")             # <<<<<<<<<<<<<<
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__55, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__53, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -42867,7 +43814,7 @@ static PyObject *__pyx_pf_9pywrapfst_8Compiler_8__setstate_cython__(CYTHON_UNUSE
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4279
+/* "pywrapfst.pyx":4352
  *   """
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -42902,28 +43849,28 @@ static int __pyx_pf_9pywrapfst_9FarReader___init__(struct __pyx_obj_9pywrapfst_F
   PyObject *__pyx_t_6 = NULL;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":4280
+  /* "pywrapfst.pyx":4353
  * 
  *   def __init__(self):
  *     raise FstDeletedConstructorError(             # <<<<<<<<<<<<<<
  *         "Cannot construct {}".format(self.__class__.__name__))
  * 
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstDeletedConstructorError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4280, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstDeletedConstructorError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4353, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":4281
+  /* "pywrapfst.pyx":4354
  *   def __init__(self):
  *     raise FstDeletedConstructorError(
  *         "Cannot construct {}".format(self.__class__.__name__))             # <<<<<<<<<<<<<<
  * 
  *   def __repr__(self):
  */
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Cannot_construct, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4281, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Cannot_construct, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4354, __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, 4281, __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, 4354, __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, 4281, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_name); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4354, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_t_5 = NULL;
@@ -42939,7 +43886,7 @@ static int __pyx_pf_9pywrapfst_9FarReader___init__(struct __pyx_obj_9pywrapfst_F
   __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6);
   __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4281, __pyx_L1_error)
+  if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4354, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_4 = NULL;
@@ -42955,14 +43902,14 @@ static int __pyx_pf_9pywrapfst_9FarReader___init__(struct __pyx_obj_9pywrapfst_F
   __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4280, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4353, __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, 4280, __pyx_L1_error)
+  __PYX_ERR(0, 4353, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4279
+  /* "pywrapfst.pyx":4352
  *   """
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -42984,7 +43931,7 @@ static int __pyx_pf_9pywrapfst_9FarReader___init__(struct __pyx_obj_9pywrapfst_F
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4283
+/* "pywrapfst.pyx":4356
  *         "Cannot construct {}".format(self.__class__.__name__))
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -43017,7 +43964,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":4284
+  /* "pywrapfst.pyx":4357
  * 
  *   def __repr__(self):
  *     return "<{} FarReader at 0x{:x}>".format(self.far_type(), id(self))             # <<<<<<<<<<<<<<
@@ -43025,15 +43972,15 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
  *   @classmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_FarReader_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4284, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_FarReader_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4357, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "far_type");
-    __PYX_ERR(0, 4284, __pyx_L1_error)
+    __PYX_ERR(0, 4357, __pyx_L1_error)
   }
-  __pyx_t_3 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_FarReader *)__pyx_v_self->__pyx_vtab)->far_type(__pyx_v_self, 0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4284, __pyx_L1_error)
+  __pyx_t_3 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_FarReader *)__pyx_v_self->__pyx_vtab)->far_type(__pyx_v_self, 0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4357, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4284, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4357, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __pyx_t_5 = NULL;
   __pyx_t_6 = 0;
@@ -43050,7 +43997,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
   #if CYTHON_FAST_PYCALL
   if (PyFunction_Check(__pyx_t_2)) {
     PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_t_3, __pyx_t_4};
-    __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4284, __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, 4357, __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;
@@ -43060,7 +44007,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
   #if CYTHON_FAST_PYCCALL
   if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
     PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_t_3, __pyx_t_4};
-    __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4284, __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, 4357, __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;
@@ -43068,7 +44015,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, 4284, __pyx_L1_error)
+    __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4357, __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;
@@ -43079,7 +44026,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
     PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_4);
     __pyx_t_3 = 0;
     __pyx_t_4 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4284, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4357, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
   }
@@ -43088,7 +44035,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4283
+  /* "pywrapfst.pyx":4356
  *         "Cannot construct {}".format(self.__class__.__name__))
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -43112,36 +44059,36 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4287
+/* "pywrapfst.pyx":4360
  * 
  *   @classmethod
- *   def open(cls, *filenames):             # <<<<<<<<<<<<<<
+ *   def open(cls, *sources):             # <<<<<<<<<<<<<<
  *     """
- *     FarReader.open(*filenames)
+ *     FarReader.open(*sources)
  */
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_9FarReader_5open(PyObject *__pyx_v_cls, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_9FarReader_4open[] = "\n    FarReader.open(*filenames)\n\n    Creates a FarReader object.\n\n    This class method creates a FarReader given the string location of one or\n    more FAR files on disk.\n\n    Args:\n      *filenames: The string location of one or more input FAR files.\n\n    Returns:\n      A new FarReader instance.\n\n    Raises:\n      FstIOError: Read failed.\n    ";
+static char __pyx_doc_9pywrapfst_9FarReader_4open[] = "\n    FarReader.open(*sources)\n\n    Creates a FarReader object.\n\n    This class method creates a FarReader given the string location of one or\n    more FAR files on disk.\n\n    Args:\n      *sources: The string location of one or more input FAR files.\n\n    Returns:\n      A new FarReader instance.\n\n    Raises:\n      FstIOError: Read failed.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_9FarReader_5open(PyObject *__pyx_v_cls, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyObject *__pyx_v_filenames = 0;
+  PyObject *__pyx_v_sources = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("open (wrapper)", 0);
   if (unlikely(__pyx_kwds) && unlikely(PyDict_Size(__pyx_kwds) > 0) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "open", 0))) return NULL;
   __Pyx_INCREF(__pyx_args);
-  __pyx_v_filenames = __pyx_args;
-  __pyx_r = __pyx_pf_9pywrapfst_9FarReader_4open(((PyTypeObject*)__pyx_v_cls), __pyx_v_filenames);
+  __pyx_v_sources = __pyx_args;
+  __pyx_r = __pyx_pf_9pywrapfst_9FarReader_4open(((PyTypeObject*)__pyx_v_cls), __pyx_v_sources);
 
   /* function exit code */
-  __Pyx_XDECREF(__pyx_v_filenames);
+  __Pyx_XDECREF(__pyx_v_sources);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_filenames) {
-  std::vector<std::string>  __pyx_v_filename_strings;
-  PyObject *__pyx_v_filename = NULL;
+static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_sources) {
+  std::vector<std::string>  __pyx_v_source_strings;
+  PyObject *__pyx_v_source = NULL;
   std::unique_ptr<fst::script::FarReaderClass>  __pyx_v_tfar;
   struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_result = 0;
   PyObject *__pyx_r = NULL;
@@ -43156,79 +44103,79 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
   PyObject *__pyx_t_8 = NULL;
   __Pyx_RefNannySetupContext("open", 0);
 
-  /* "pywrapfst.pyx":4306
+  /* "pywrapfst.pyx":4379
  *     """
- *     cdef vector[string] filename_strings
- *     for filename in filenames:             # <<<<<<<<<<<<<<
- *       filename_strings.push_back(tostring(filename))
+ *     cdef vector[string] source_strings
+ *     for source in sources:             # <<<<<<<<<<<<<<
+ *       source_strings.push_back(tostring(source))
  *     cdef unique_ptr[fst.FarReaderClass] tfar
  */
-  __pyx_t_1 = __pyx_v_filenames; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
+  __pyx_t_1 = __pyx_v_sources; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
   for (;;) {
     if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
     #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-    __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 4306, __pyx_L1_error)
+    __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 4379, __pyx_L1_error)
     #else
-    __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4306, __pyx_L1_error)
+    __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4379, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     #endif
-    __Pyx_XDECREF_SET(__pyx_v_filename, __pyx_t_3);
+    __Pyx_XDECREF_SET(__pyx_v_source, __pyx_t_3);
     __pyx_t_3 = 0;
 
-    /* "pywrapfst.pyx":4307
- *     cdef vector[string] filename_strings
- *     for filename in filenames:
- *       filename_strings.push_back(tostring(filename))             # <<<<<<<<<<<<<<
+    /* "pywrapfst.pyx":4380
+ *     cdef vector[string] source_strings
+ *     for source in sources:
+ *       source_strings.push_back(tostring(source))             # <<<<<<<<<<<<<<
  *     cdef unique_ptr[fst.FarReaderClass] tfar
- *     tfar.reset(fst.FarReaderClass.Open(filename_strings))
+ *     tfar.reset(fst.FarReaderClass.Open(source_strings))
  */
-    __pyx_t_4 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4307, __pyx_L1_error)
+    __pyx_t_4 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4380, __pyx_L1_error)
     try {
-      __pyx_v_filename_strings.push_back(__pyx_t_4);
+      __pyx_v_source_strings.push_back(__pyx_t_4);
     } catch(...) {
       __Pyx_CppExn2PyErr();
-      __PYX_ERR(0, 4307, __pyx_L1_error)
+      __PYX_ERR(0, 4380, __pyx_L1_error)
     }
 
-    /* "pywrapfst.pyx":4306
+    /* "pywrapfst.pyx":4379
  *     """
- *     cdef vector[string] filename_strings
- *     for filename in filenames:             # <<<<<<<<<<<<<<
- *       filename_strings.push_back(tostring(filename))
+ *     cdef vector[string] source_strings
+ *     for source in sources:             # <<<<<<<<<<<<<<
+ *       source_strings.push_back(tostring(source))
  *     cdef unique_ptr[fst.FarReaderClass] tfar
  */
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":4309
- *       filename_strings.push_back(tostring(filename))
+  /* "pywrapfst.pyx":4382
+ *       source_strings.push_back(tostring(source))
  *     cdef unique_ptr[fst.FarReaderClass] tfar
- *     tfar.reset(fst.FarReaderClass.Open(filename_strings))             # <<<<<<<<<<<<<<
+ *     tfar.reset(fst.FarReaderClass.Open(source_strings))             # <<<<<<<<<<<<<<
  *     if tfar.get() == NULL:
- *       raise FstIOError("Read failed: {!r}".format(filenames))
+ *       raise FstIOError("Read failed: {!r}".format(sources))
  */
-  __pyx_v_tfar.reset(fst::script::FarReaderClass::Open(__pyx_v_filename_strings));
+  __pyx_v_tfar.reset(fst::script::FarReaderClass::Open(__pyx_v_source_strings));
 
-  /* "pywrapfst.pyx":4310
+  /* "pywrapfst.pyx":4383
  *     cdef unique_ptr[fst.FarReaderClass] tfar
- *     tfar.reset(fst.FarReaderClass.Open(filename_strings))
+ *     tfar.reset(fst.FarReaderClass.Open(source_strings))
  *     if tfar.get() == NULL:             # <<<<<<<<<<<<<<
- *       raise FstIOError("Read failed: {!r}".format(filenames))
+ *       raise FstIOError("Read failed: {!r}".format(sources))
  *     cdef FarReader result = FarReader.__new__(FarReader)
  */
   __pyx_t_5 = ((__pyx_v_tfar.get() == NULL) != 0);
   if (unlikely(__pyx_t_5)) {
 
-    /* "pywrapfst.pyx":4311
- *     tfar.reset(fst.FarReaderClass.Open(filename_strings))
+    /* "pywrapfst.pyx":4384
+ *     tfar.reset(fst.FarReaderClass.Open(source_strings))
  *     if tfar.get() == NULL:
- *       raise FstIOError("Read failed: {!r}".format(filenames))             # <<<<<<<<<<<<<<
+ *       raise FstIOError("Read failed: {!r}".format(sources))             # <<<<<<<<<<<<<<
  *     cdef FarReader result = FarReader.__new__(FarReader)
  *     result._reader.reset(tfar.release())
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4311, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4384, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4311, __pyx_L1_error)
+    __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4384, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_7);
     __pyx_t_8 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) {
@@ -43240,9 +44187,9 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
         __Pyx_DECREF_SET(__pyx_t_7, function);
       }
     }
-    __pyx_t_6 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_8, __pyx_v_filenames) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_v_filenames);
+    __pyx_t_6 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_8, __pyx_v_sources) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_v_sources);
     __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
-    if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4311, __pyx_L1_error)
+    if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4384, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     __pyx_t_7 = NULL;
@@ -43258,36 +44205,36 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
     __pyx_t_1 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_7, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_6);
     __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4311, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4384, __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, 4311, __pyx_L1_error)
+    __PYX_ERR(0, 4384, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4310
+    /* "pywrapfst.pyx":4383
  *     cdef unique_ptr[fst.FarReaderClass] tfar
- *     tfar.reset(fst.FarReaderClass.Open(filename_strings))
+ *     tfar.reset(fst.FarReaderClass.Open(source_strings))
  *     if tfar.get() == NULL:             # <<<<<<<<<<<<<<
- *       raise FstIOError("Read failed: {!r}".format(filenames))
+ *       raise FstIOError("Read failed: {!r}".format(sources))
  *     cdef FarReader result = FarReader.__new__(FarReader)
  */
   }
 
-  /* "pywrapfst.pyx":4312
+  /* "pywrapfst.pyx":4385
  *     if tfar.get() == NULL:
- *       raise FstIOError("Read failed: {!r}".format(filenames))
+ *       raise FstIOError("Read failed: {!r}".format(sources))
  *     cdef FarReader result = FarReader.__new__(FarReader)             # <<<<<<<<<<<<<<
  *     result._reader.reset(tfar.release())
  *     return result
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_FarReader(((PyTypeObject *)__pyx_ptype_9pywrapfst_FarReader), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4312, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_FarReader(((PyTypeObject *)__pyx_ptype_9pywrapfst_FarReader), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4385, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_FarReader *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":4313
- *       raise FstIOError("Read failed: {!r}".format(filenames))
+  /* "pywrapfst.pyx":4386
+ *       raise FstIOError("Read failed: {!r}".format(sources))
  *     cdef FarReader result = FarReader.__new__(FarReader)
  *     result._reader.reset(tfar.release())             # <<<<<<<<<<<<<<
  *     return result
@@ -43295,11 +44242,11 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4313, __pyx_L1_error)
+    __PYX_ERR(0, 4386, __pyx_L1_error)
   }
   __pyx_v_result->_reader.reset(__pyx_v_tfar.release());
 
-  /* "pywrapfst.pyx":4314
+  /* "pywrapfst.pyx":4387
  *     cdef FarReader result = FarReader.__new__(FarReader)
  *     result._reader.reset(tfar.release())
  *     return result             # <<<<<<<<<<<<<<
@@ -43311,12 +44258,12 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
   __pyx_r = ((PyObject *)__pyx_v_result);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4287
+  /* "pywrapfst.pyx":4360
  * 
  *   @classmethod
- *   def open(cls, *filenames):             # <<<<<<<<<<<<<<
+ *   def open(cls, *sources):             # <<<<<<<<<<<<<<
  *     """
- *     FarReader.open(*filenames)
+ *     FarReader.open(*sources)
  */
 
   /* function exit code */
@@ -43329,14 +44276,14 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
   __Pyx_AddTraceback("pywrapfst.FarReader.open", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
-  __Pyx_XDECREF(__pyx_v_filename);
+  __Pyx_XDECREF(__pyx_v_source);
   __Pyx_XDECREF((PyObject *)__pyx_v_result);
   __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4316
+/* "pywrapfst.pyx":4389
  *     return result
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
@@ -43363,7 +44310,7 @@ static std::string __pyx_f_9pywrapfst_9FarReader_arc_type(struct __pyx_obj_9pywr
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4316, __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, 4389, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarReader_7arc_type)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -43379,10 +44326,10 @@ static std::string __pyx_f_9pywrapfst_9FarReader_arc_type(struct __pyx_obj_9pywr
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4316, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4389, __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, 4316, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4389, __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;
@@ -43401,7 +44348,7 @@ static std::string __pyx_f_9pywrapfst_9FarReader_arc_type(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":4322
+  /* "pywrapfst.pyx":4395
  *     Returns a string indicating the arc type.
  *     """
  *     return self._reader.get().ArcType()             # <<<<<<<<<<<<<<
@@ -43410,12 +44357,12 @@ static std::string __pyx_f_9pywrapfst_9FarReader_arc_type(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4322, __pyx_L1_error)
+    __PYX_ERR(0, 4395, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_reader.get()->ArcType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4316
+  /* "pywrapfst.pyx":4389
  *     return result
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
@@ -43456,7 +44403,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_6arc_type(struct __pyx_obj_9pywr
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("arc_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarReader_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4316, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarReader_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4389, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -43473,7 +44420,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_6arc_type(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4324
+/* "pywrapfst.pyx":4397
  *     return self._reader.get().ArcType()
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -43500,7 +44447,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_done(struct __pyx_obj_9pywrapfst_FarRe
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_done); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4324, __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, 4397, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarReader_9done)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -43516,10 +44463,10 @@ static bool __pyx_f_9pywrapfst_9FarReader_done(struct __pyx_obj_9pywrapfst_FarRe
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4324, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4397, __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, 4324, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4397, __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;
@@ -43538,7 +44485,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_done(struct __pyx_obj_9pywrapfst_FarRe
     #endif
   }
 
-  /* "pywrapfst.pyx":4333
+  /* "pywrapfst.pyx":4406
  *       True if the iterator is exhausted, False otherwise.
  *     """
  *     return self._reader.get().Done()             # <<<<<<<<<<<<<<
@@ -43547,12 +44494,12 @@ static bool __pyx_f_9pywrapfst_9FarReader_done(struct __pyx_obj_9pywrapfst_FarRe
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4333, __pyx_L1_error)
+    __PYX_ERR(0, 4406, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_reader.get()->Done();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4324
+  /* "pywrapfst.pyx":4397
  *     return self._reader.get().ArcType()
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -43593,7 +44540,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_8done(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("done", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_9FarReader_done(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4324, __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, 4397, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -43610,7 +44557,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_8done(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4335
+/* "pywrapfst.pyx":4408
  *     return self._reader.get().Done()
  * 
  *   cpdef bool error(self):             # <<<<<<<<<<<<<<
@@ -43637,7 +44584,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_error(struct __pyx_obj_9pywrapfst_FarR
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_error); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4335, __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, 4408, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarReader_11error)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -43653,10 +44600,10 @@ static bool __pyx_f_9pywrapfst_9FarReader_error(struct __pyx_obj_9pywrapfst_FarR
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4335, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4408, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4335, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4408, __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;
@@ -43675,7 +44622,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_error(struct __pyx_obj_9pywrapfst_FarR
     #endif
   }
 
-  /* "pywrapfst.pyx":4344
+  /* "pywrapfst.pyx":4417
  *       True if the FarReader is in an errorful state, False otherwise.
  *     """
  *     return self._reader.get().Error()             # <<<<<<<<<<<<<<
@@ -43684,12 +44631,12 @@ static bool __pyx_f_9pywrapfst_9FarReader_error(struct __pyx_obj_9pywrapfst_FarR
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4344, __pyx_L1_error)
+    __PYX_ERR(0, 4417, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_reader.get()->Error();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4335
+  /* "pywrapfst.pyx":4408
  *     return self._reader.get().Done()
  * 
  *   cpdef bool error(self):             # <<<<<<<<<<<<<<
@@ -43730,7 +44677,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_10error(struct __pyx_obj_9pywrap
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("error", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_9FarReader_error(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4335, __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, 4408, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -43747,7 +44694,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_10error(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4346
+/* "pywrapfst.pyx":4419
  *     return self._reader.get().Error()
  * 
  *   cpdef string far_type(self):             # <<<<<<<<<<<<<<
@@ -43774,7 +44721,7 @@ static std::string __pyx_f_9pywrapfst_9FarReader_far_type(struct __pyx_obj_9pywr
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_far_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4346, __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, 4419, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarReader_13far_type)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -43790,10 +44737,10 @@ static std::string __pyx_f_9pywrapfst_9FarReader_far_type(struct __pyx_obj_9pywr
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4346, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4419, __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, 4346, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4419, __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;
@@ -43812,7 +44759,7 @@ static std::string __pyx_f_9pywrapfst_9FarReader_far_type(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":4347
+  /* "pywrapfst.pyx":4420
  * 
  *   cpdef string far_type(self):
  *     return fst.GetFarTypeString(self._reader.get().Type())             # <<<<<<<<<<<<<<
@@ -43821,12 +44768,12 @@ static std::string __pyx_f_9pywrapfst_9FarReader_far_type(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4347, __pyx_L1_error)
+    __PYX_ERR(0, 4420, __pyx_L1_error)
   }
   __pyx_r = fst::GetFarTypeString(__pyx_v_self->_reader.get()->Type());
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4346
+  /* "pywrapfst.pyx":4419
  *     return self._reader.get().Error()
  * 
  *   cpdef string far_type(self):             # <<<<<<<<<<<<<<
@@ -43866,7 +44813,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_12far_type(struct __pyx_obj_9pyw
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("far_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarReader_far_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4346, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarReader_far_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4419, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -43883,7 +44830,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_12far_type(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4349
+/* "pywrapfst.pyx":4422
  *     return fst.GetFarTypeString(self._reader.get().Type())
  * 
  *   cpdef bool find(self, key) except *:             # <<<<<<<<<<<<<<
@@ -43911,7 +44858,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_find(struct __pyx_obj_9pywrapfst_FarRe
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_find); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4349, __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, 4422, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarReader_15find)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -43927,10 +44874,10 @@ static bool __pyx_f_9pywrapfst_9FarReader_find(struct __pyx_obj_9pywrapfst_FarRe
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_key) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_key);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4349, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4422, __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, 4349, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4422, __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;
@@ -43949,7 +44896,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_find(struct __pyx_obj_9pywrapfst_FarRe
     #endif
   }
 
-  /* "pywrapfst.pyx":4362
+  /* "pywrapfst.pyx":4435
  *       True if the key was found, False otherwise.
  *     """
  *     return self._reader.get().Find(tostring(key))             # <<<<<<<<<<<<<<
@@ -43958,13 +44905,13 @@ static bool __pyx_f_9pywrapfst_9FarReader_find(struct __pyx_obj_9pywrapfst_FarRe
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4362, __pyx_L1_error)
+    __PYX_ERR(0, 4435, __pyx_L1_error)
   }
-  __pyx_t_6 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4362, __pyx_L1_error)
+  __pyx_t_6 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4435, __pyx_L1_error)
   __pyx_r = __pyx_v_self->_reader.get()->Find(__pyx_t_6);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4349
+  /* "pywrapfst.pyx":4422
  *     return fst.GetFarTypeString(self._reader.get().Type())
  * 
  *   cpdef bool find(self, key) except *:             # <<<<<<<<<<<<<<
@@ -44006,8 +44953,8 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_14find(struct __pyx_obj_9pywrapf
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("find", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_9FarReader_find(__pyx_v_self, __pyx_v_key, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4349, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4349, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_9FarReader_find(__pyx_v_self, __pyx_v_key, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4422, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4422, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -44024,7 +44971,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_14find(struct __pyx_obj_9pywrapf
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4364
+/* "pywrapfst.pyx":4437
  *     return self._reader.get().Find(tostring(key))
  * 
  *   cpdef _Fst get_fst(self):             # <<<<<<<<<<<<<<
@@ -44050,7 +44997,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(s
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get_fst); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4364, __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, 4437, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarReader_17get_fst)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -44067,10 +45014,10 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(s
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4364, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4437, __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, 4364, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__Fst))))) __PYX_ERR(0, 4437, __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;
@@ -44089,7 +45036,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(s
     #endif
   }
 
-  /* "pywrapfst.pyx":4373
+  /* "pywrapfst.pyx":4446
  *       A copy of the FST at the current position.
  *     """
  *     return _init_XFst(new fst.FstClass(             # <<<<<<<<<<<<<<
@@ -44098,7 +45045,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(s
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
 
-  /* "pywrapfst.pyx":4374
+  /* "pywrapfst.pyx":4447
  *     """
  *     return _init_XFst(new fst.FstClass(
  *         deref(self._reader.get().GetFstClass())))             # <<<<<<<<<<<<<<
@@ -44107,23 +45054,23 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(s
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4374, __pyx_L1_error)
+    __PYX_ERR(0, 4447, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4373
+  /* "pywrapfst.pyx":4446
  *       A copy of the FST at the current position.
  *     """
  *     return _init_XFst(new fst.FstClass(             # <<<<<<<<<<<<<<
  *         deref(self._reader.get().GetFstClass())))
  * 
  */
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(new fst::script::FstClass((*__pyx_v_self->_reader.get()->GetFstClass())))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4373, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(new fst::script::FstClass((*__pyx_v_self->_reader.get()->GetFstClass())))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4446, __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":4364
+  /* "pywrapfst.pyx":4437
  *     return self._reader.get().Find(tostring(key))
  * 
  *   cpdef _Fst get_fst(self):             # <<<<<<<<<<<<<<
@@ -44165,7 +45112,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_16get_fst(struct __pyx_obj_9pywr
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("get_fst", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_9FarReader_get_fst(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4364, __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, 4437, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -44182,7 +45129,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_16get_fst(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4376
+/* "pywrapfst.pyx":4449
  *         deref(self._reader.get().GetFstClass())))
  * 
  *   cpdef string get_key(self):             # <<<<<<<<<<<<<<
@@ -44209,7 +45156,7 @@ static std::string __pyx_f_9pywrapfst_9FarReader_get_key(struct __pyx_obj_9pywra
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get_key); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4376, __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, 4449, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarReader_19get_key)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -44225,10 +45172,10 @@ static std::string __pyx_f_9pywrapfst_9FarReader_get_key(struct __pyx_obj_9pywra
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4376, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4449, __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, 4376, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4449, __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;
@@ -44247,7 +45194,7 @@ static std::string __pyx_f_9pywrapfst_9FarReader_get_key(struct __pyx_obj_9pywra
     #endif
   }
 
-  /* "pywrapfst.pyx":4385
+  /* "pywrapfst.pyx":4458
  *       The string key at the current position.
  *     """
  *     return self._reader.get().GetKey()             # <<<<<<<<<<<<<<
@@ -44256,12 +45203,12 @@ static std::string __pyx_f_9pywrapfst_9FarReader_get_key(struct __pyx_obj_9pywra
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4385, __pyx_L1_error)
+    __PYX_ERR(0, 4458, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_reader.get()->GetKey();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4376
+  /* "pywrapfst.pyx":4449
  *         deref(self._reader.get().GetFstClass())))
  * 
  *   cpdef string get_key(self):             # <<<<<<<<<<<<<<
@@ -44302,7 +45249,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_18get_key(struct __pyx_obj_9pywr
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("get_key", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarReader_get_key(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4376, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarReader_get_key(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4449, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -44319,7 +45266,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_18get_key(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4387
+/* "pywrapfst.pyx":4460
  *     return self._reader.get().GetKey()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -44344,7 +45291,7 @@ static void __pyx_f_9pywrapfst_9FarReader_next(struct __pyx_obj_9pywrapfst_FarRe
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_next); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4387, __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, 4460, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarReader_21next)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -44360,7 +45307,7 @@ static void __pyx_f_9pywrapfst_9FarReader_next(struct __pyx_obj_9pywrapfst_FarRe
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4387, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4460, __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;
@@ -44380,7 +45327,7 @@ static void __pyx_f_9pywrapfst_9FarReader_next(struct __pyx_obj_9pywrapfst_FarRe
     #endif
   }
 
-  /* "pywrapfst.pyx":4393
+  /* "pywrapfst.pyx":4466
  *     Advances the iterator.
  *     """
  *     self._reader.get().Next()             # <<<<<<<<<<<<<<
@@ -44389,11 +45336,11 @@ static void __pyx_f_9pywrapfst_9FarReader_next(struct __pyx_obj_9pywrapfst_FarRe
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4393, __pyx_L1_error)
+    __PYX_ERR(0, 4466, __pyx_L1_error)
   }
   __pyx_v_self->_reader.get()->Next();
 
-  /* "pywrapfst.pyx":4387
+  /* "pywrapfst.pyx":4460
  *     return self._reader.get().GetKey()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -44433,7 +45380,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_20next(struct __pyx_obj_9pywrapf
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("next", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_9FarReader_next(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4387, __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, 4460, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -44450,7 +45397,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_20next(struct __pyx_obj_9pywrapf
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4395
+/* "pywrapfst.pyx":4468
  *     self._reader.get().Next()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -44475,7 +45422,7 @@ static void __pyx_f_9pywrapfst_9FarReader_reset(struct __pyx_obj_9pywrapfst_FarR
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_reset); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4395, __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, 4468, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarReader_23reset)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -44491,7 +45438,7 @@ static void __pyx_f_9pywrapfst_9FarReader_reset(struct __pyx_obj_9pywrapfst_FarR
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4395, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4468, __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;
@@ -44511,7 +45458,7 @@ static void __pyx_f_9pywrapfst_9FarReader_reset(struct __pyx_obj_9pywrapfst_FarR
     #endif
   }
 
-  /* "pywrapfst.pyx":4401
+  /* "pywrapfst.pyx":4474
  *     Resets the iterator to the initial position.
  *     """
  *     self._reader.get().Reset()             # <<<<<<<<<<<<<<
@@ -44520,11 +45467,11 @@ static void __pyx_f_9pywrapfst_9FarReader_reset(struct __pyx_obj_9pywrapfst_FarR
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4401, __pyx_L1_error)
+    __PYX_ERR(0, 4474, __pyx_L1_error)
   }
   __pyx_v_self->_reader.get()->Reset();
 
-  /* "pywrapfst.pyx":4395
+  /* "pywrapfst.pyx":4468
  *     self._reader.get().Next()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -44564,7 +45511,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_22reset(struct __pyx_obj_9pywrap
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("reset", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_9FarReader_reset(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4395, __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, 4468, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -44581,7 +45528,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_22reset(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4403
+/* "pywrapfst.pyx":4476
  *     self._reader.get().Reset()
  * 
  *   def __getitem__(self, key):             # <<<<<<<<<<<<<<
@@ -44610,7 +45557,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_24__getitem__(struct __pyx_obj_9
   PyObject *__pyx_t_3 = NULL;
   __Pyx_RefNannySetupContext("__getitem__", 0);
 
-  /* "pywrapfst.pyx":4404
+  /* "pywrapfst.pyx":4477
  * 
  *   def __getitem__(self, key):
  *     if self._reader.get().Find(tostring(key)):             # <<<<<<<<<<<<<<
@@ -44619,13 +45566,13 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_24__getitem__(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4404, __pyx_L1_error)
+    __PYX_ERR(0, 4477, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4404, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4477, __pyx_L1_error)
   __pyx_t_2 = (__pyx_v_self->_reader.get()->Find(__pyx_t_1) != 0);
   if (likely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":4405
+    /* "pywrapfst.pyx":4478
  *   def __getitem__(self, key):
  *     if self._reader.get().Find(tostring(key)):
  *       return self.get_fst()             # <<<<<<<<<<<<<<
@@ -44635,15 +45582,15 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_24__getitem__(struct __pyx_obj_9
     __Pyx_XDECREF(__pyx_r);
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "get_fst");
-      __PYX_ERR(0, 4405, __pyx_L1_error)
+      __PYX_ERR(0, 4478, __pyx_L1_error)
     }
-    __pyx_t_3 = ((PyObject *)((struct __pyx_vtabstruct_9pywrapfst_FarReader *)__pyx_v_self->__pyx_vtab)->get_fst(__pyx_v_self, 0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4405, __pyx_L1_error)
+    __pyx_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, 4478, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_r = __pyx_t_3;
     __pyx_t_3 = 0;
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":4404
+    /* "pywrapfst.pyx":4477
  * 
  *   def __getitem__(self, key):
  *     if self._reader.get().Find(tostring(key)):             # <<<<<<<<<<<<<<
@@ -44652,7 +45599,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_24__getitem__(struct __pyx_obj_9
  */
   }
 
-  /* "pywrapfst.pyx":4407
+  /* "pywrapfst.pyx":4480
  *       return self.get_fst()
  *     else:
  *       raise KeyError(key)             # <<<<<<<<<<<<<<
@@ -44660,14 +45607,14 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_24__getitem__(struct __pyx_obj_9
  * 
  */
   /*else*/ {
-    __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_KeyError, __pyx_v_key); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4407, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_KeyError, __pyx_v_key); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4480, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 4407, __pyx_L1_error)
+    __PYX_ERR(0, 4480, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4403
+  /* "pywrapfst.pyx":4476
  *     self._reader.get().Reset()
  * 
  *   def __getitem__(self, key):             # <<<<<<<<<<<<<<
@@ -44717,7 +45664,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_26__reduce_cython__(CYTHON_UNUSE
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._reader cannot be converted to a Python object for pickling")
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__56, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__54, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -44770,7 +45717,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_28__setstate_cython__(CYTHON_UNU
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._reader cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__57, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__55, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -44793,7 +45740,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_28__setstate_cython__(CYTHON_UNU
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4430
+/* "pywrapfst.pyx":4503
  *   """
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -44828,28 +45775,28 @@ static int __pyx_pf_9pywrapfst_9FarWriter___init__(struct __pyx_obj_9pywrapfst_F
   PyObject *__pyx_t_6 = NULL;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":4431
+  /* "pywrapfst.pyx":4504
  * 
  *   def __init__(self):
  *     raise FstDeletedConstructorError(             # <<<<<<<<<<<<<<
  *         "Cannot construct {}".format(self.__class__.__name__))
  * 
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstDeletedConstructorError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4431, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstDeletedConstructorError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4504, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":4432
+  /* "pywrapfst.pyx":4505
  *   def __init__(self):
  *     raise FstDeletedConstructorError(
  *         "Cannot construct {}".format(self.__class__.__name__))             # <<<<<<<<<<<<<<
  * 
  *   def __repr__(self):
  */
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Cannot_construct, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4432, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Cannot_construct, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4505, __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, 4432, __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, 4505, __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, 4432, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_name); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4505, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_t_5 = NULL;
@@ -44865,7 +45812,7 @@ static int __pyx_pf_9pywrapfst_9FarWriter___init__(struct __pyx_obj_9pywrapfst_F
   __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6);
   __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4432, __pyx_L1_error)
+  if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4505, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_4 = NULL;
@@ -44881,14 +45828,14 @@ static int __pyx_pf_9pywrapfst_9FarWriter___init__(struct __pyx_obj_9pywrapfst_F
   __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4431, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4504, __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, 4431, __pyx_L1_error)
+  __PYX_ERR(0, 4504, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4430
+  /* "pywrapfst.pyx":4503
  *   """
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -44910,7 +45857,7 @@ static int __pyx_pf_9pywrapfst_9FarWriter___init__(struct __pyx_obj_9pywrapfst_F
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4434
+/* "pywrapfst.pyx":4507
  *         "Cannot construct {}".format(self.__class__.__name__))
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -44943,7 +45890,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":4435
+  /* "pywrapfst.pyx":4508
  * 
  *   def __repr__(self):
  *     return "<{} FarWriter at 0x{:x}>".format(self.far_type(), id(self))             # <<<<<<<<<<<<<<
@@ -44951,15 +45898,15 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
  *   @classmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_FarWriter_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4435, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_FarWriter_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4508, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "far_type");
-    __PYX_ERR(0, 4435, __pyx_L1_error)
+    __PYX_ERR(0, 4508, __pyx_L1_error)
   }
-  __pyx_t_3 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_FarWriter *)__pyx_v_self->__pyx_vtab)->far_type(__pyx_v_self, 0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4435, __pyx_L1_error)
+  __pyx_t_3 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_FarWriter *)__pyx_v_self->__pyx_vtab)->far_type(__pyx_v_self, 0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4508, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4435, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4508, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __pyx_t_5 = NULL;
   __pyx_t_6 = 0;
@@ -44976,7 +45923,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
   #if CYTHON_FAST_PYCALL
   if (PyFunction_Check(__pyx_t_2)) {
     PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_t_3, __pyx_t_4};
-    __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4435, __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, 4508, __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;
@@ -44986,7 +45933,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
   #if CYTHON_FAST_PYCCALL
   if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
     PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_t_3, __pyx_t_4};
-    __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4435, __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, 4508, __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;
@@ -44994,7 +45941,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, 4435, __pyx_L1_error)
+    __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4508, __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;
@@ -45005,7 +45952,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
     PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_4);
     __pyx_t_3 = 0;
     __pyx_t_4 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4435, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4508, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
   }
@@ -45014,7 +45961,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4434
+  /* "pywrapfst.pyx":4507
  *         "Cannot construct {}".format(self.__class__.__name__))
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -45038,26 +45985,26 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4438
+/* "pywrapfst.pyx":4511
  * 
  *   @classmethod
- *   def create(cls, filename, arc_type=b"standard", far_type=b"default"):             # <<<<<<<<<<<<<<
+ *   def create(cls, source, arc_type=b"standard", far_type=b"default"):             # <<<<<<<<<<<<<<
  *     """
  *     FarWriter.
  */
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_9FarWriter_5create(PyObject *__pyx_v_cls, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_9FarWriter_4create[] = "\n    FarWriter.\n\n    Creates a FarWriter object.\n\n    This class method creates a FarWriter given the desired output location,\n    arc type, and FAR type.\n\n    Args:\n      filename: The string location for the output FAR files.\n      arc_type: A string indicating the arc type.\n      far_type: A string indicating the FAR type; one of: \"fst\", \"stlist\",\n          \"sttable\", \"sstable\", \"default\".\n\n    Returns:\n      A new FarWriter instance.\n\n    Raises:\n      FstIOError: Read failed.\n    ";
+static char __pyx_doc_9pywrapfst_9FarWriter_4create[] = "\n    FarWriter.\n\n    Creates a FarWriter object.\n\n    This class method creates a FarWriter given the desired output location,\n    arc type, and FAR type.\n\n    Args:\n      source: The string location for the output FAR files.\n      arc_type: A string indicating the arc type.\n      far_type: A string indicating the FAR type; one of: \"fst\", \"stlist\",\n          \"sttable\", \"sstable\", \"default\".\n\n    Returns:\n      A new FarWriter instance.\n\n    Raises:\n      FstIOError: Read failed.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_9FarWriter_5create(PyObject *__pyx_v_cls, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyObject *__pyx_v_filename = 0;
+  PyObject *__pyx_v_source = 0;
   PyObject *__pyx_v_arc_type = 0;
   PyObject *__pyx_v_far_type = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("create (wrapper)", 0);
   {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_filename,&__pyx_n_s_arc_type,&__pyx_n_s_far_type,0};
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_source,&__pyx_n_s_arc_type,&__pyx_n_s_far_type,0};
     PyObject* values[3] = {0,0,0};
     values[1] = ((PyObject *)__pyx_n_b_standard);
     values[2] = ((PyObject *)__pyx_n_b_default);
@@ -45077,7 +46024,7 @@ static PyObject *__pyx_pw_9pywrapfst_9FarWriter_5create(PyObject *__pyx_v_cls, P
       kw_args = PyDict_Size(__pyx_kwds);
       switch (pos_args) {
         case  0:
-        if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_filename)) != 0)) kw_args--;
+        if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_source)) != 0)) kw_args--;
         else goto __pyx_L5_argtuple_error;
         CYTHON_FALLTHROUGH;
         case  1:
@@ -45093,7 +46040,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, 4438, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "create") < 0)) __PYX_ERR(0, 4511, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -45106,26 +46053,26 @@ static PyObject *__pyx_pw_9pywrapfst_9FarWriter_5create(PyObject *__pyx_v_cls, P
         default: goto __pyx_L5_argtuple_error;
       }
     }
-    __pyx_v_filename = values[0];
+    __pyx_v_source = values[0];
     __pyx_v_arc_type = values[1];
     __pyx_v_far_type = values[2];
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("create", 0, 1, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4438, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("create", 0, 1, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4511, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.FarWriter.create", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_9FarWriter_4create(((PyTypeObject*)__pyx_v_cls), __pyx_v_filename, __pyx_v_arc_type, __pyx_v_far_type);
+  __pyx_r = __pyx_pf_9pywrapfst_9FarWriter_4create(((PyTypeObject*)__pyx_v_cls), __pyx_v_source, __pyx_v_arc_type, __pyx_v_far_type);
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_filename, PyObject *__pyx_v_arc_type, PyObject *__pyx_v_far_type) {
+static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_source, PyObject *__pyx_v_arc_type, PyObject *__pyx_v_far_type) {
   enum fst::FarType __pyx_v_ft;
   fst::script::FarWriterClass *__pyx_v_tfar;
   struct __pyx_obj_9pywrapfst_FarWriter *__pyx_v_result = 0;
@@ -45141,55 +46088,63 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
   PyObject *__pyx_t_8 = NULL;
   __Pyx_RefNannySetupContext("create", 0);
 
-  /* "pywrapfst.pyx":4459
+  /* "pywrapfst.pyx":4532
  *       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)
+ *         tostring(source),
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_far_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4459, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_far_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4532, __pyx_L1_error)
   __pyx_v_ft = fst::script::GetFarType(__pyx_t_1);
 
-  /* "pywrapfst.pyx":4461
+  /* "pywrapfst.pyx":4534
  *     cdef fst.FarType ft = fst.GetFarType(tostring(far_type))
  *     cdef fst.FarWriterClass *tfar = fst.FarWriterClass.Create(
- *         tostring(filename), tostring(arc_type), ft)             # <<<<<<<<<<<<<<
+ *         tostring(source),             # <<<<<<<<<<<<<<
+ *         tostring(arc_type),
+ *         ft)
+ */
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4534, __pyx_L1_error)
+
+  /* "pywrapfst.pyx":4535
+ *     cdef fst.FarWriterClass *tfar = fst.FarWriterClass.Create(
+ *         tostring(source),
+ *         tostring(arc_type),             # <<<<<<<<<<<<<<
+ *         ft)
  *     if tfar == NULL:
- *       raise FstIOError("Open failed: {!r}".format(filename))
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4461, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4461, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4535, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4460
+  /* "pywrapfst.pyx":4533
  *     """
  *     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:
+ *         tostring(source),
+ *         tostring(arc_type),
  */
   __pyx_v_tfar = fst::script::FarWriterClass::Create(__pyx_t_1, __pyx_t_2, __pyx_v_ft);
 
-  /* "pywrapfst.pyx":4462
- *     cdef fst.FarWriterClass *tfar = fst.FarWriterClass.Create(
- *         tostring(filename), tostring(arc_type), ft)
+  /* "pywrapfst.pyx":4537
+ *         tostring(arc_type),
+ *         ft)
  *     if tfar == NULL:             # <<<<<<<<<<<<<<
- *       raise FstIOError("Open failed: {!r}".format(filename))
+ *       raise FstIOError("Open failed: {!r}".format(source))
  *     cdef FarWriter result = FarWriter.__new__(FarWriter)
  */
   __pyx_t_3 = ((__pyx_v_tfar == NULL) != 0);
   if (unlikely(__pyx_t_3)) {
 
-    /* "pywrapfst.pyx":4463
- *         tostring(filename), tostring(arc_type), ft)
+    /* "pywrapfst.pyx":4538
+ *         ft)
  *     if tfar == NULL:
- *       raise FstIOError("Open failed: {!r}".format(filename))             # <<<<<<<<<<<<<<
+ *       raise FstIOError("Open failed: {!r}".format(source))             # <<<<<<<<<<<<<<
  *     cdef FarWriter result = FarWriter.__new__(FarWriter)
  *     result._writer.reset(tfar)
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4463, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4538, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Open_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4463, __pyx_L1_error)
+    __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Open_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4538, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_7);
     __pyx_t_8 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) {
@@ -45201,9 +46156,9 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
         __Pyx_DECREF_SET(__pyx_t_7, function);
       }
     }
-    __pyx_t_6 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_8, __pyx_v_filename) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_v_filename);
+    __pyx_t_6 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_8, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_v_source);
     __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
-    if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4463, __pyx_L1_error)
+    if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4538, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     __pyx_t_7 = NULL;
@@ -45219,36 +46174,36 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
     __pyx_t_4 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_7, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6);
     __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4463, __pyx_L1_error)
+    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4538, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_Raise(__pyx_t_4, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __PYX_ERR(0, 4463, __pyx_L1_error)
+    __PYX_ERR(0, 4538, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4462
- *     cdef fst.FarWriterClass *tfar = fst.FarWriterClass.Create(
- *         tostring(filename), tostring(arc_type), ft)
+    /* "pywrapfst.pyx":4537
+ *         tostring(arc_type),
+ *         ft)
  *     if tfar == NULL:             # <<<<<<<<<<<<<<
- *       raise FstIOError("Open failed: {!r}".format(filename))
+ *       raise FstIOError("Open failed: {!r}".format(source))
  *     cdef FarWriter result = FarWriter.__new__(FarWriter)
  */
   }
 
-  /* "pywrapfst.pyx":4464
+  /* "pywrapfst.pyx":4539
  *     if tfar == NULL:
- *       raise FstIOError("Open failed: {!r}".format(filename))
+ *       raise FstIOError("Open failed: {!r}".format(source))
  *     cdef FarWriter result = FarWriter.__new__(FarWriter)             # <<<<<<<<<<<<<<
  *     result._writer.reset(tfar)
  *     return result
  */
-  __pyx_t_4 = ((PyObject *)__pyx_tp_new_9pywrapfst_FarWriter(((PyTypeObject *)__pyx_ptype_9pywrapfst_FarWriter), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4464, __pyx_L1_error)
+  __pyx_t_4 = ((PyObject *)__pyx_tp_new_9pywrapfst_FarWriter(((PyTypeObject *)__pyx_ptype_9pywrapfst_FarWriter), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4539, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_4));
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_FarWriter *)__pyx_t_4);
   __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":4465
- *       raise FstIOError("Open failed: {!r}".format(filename))
+  /* "pywrapfst.pyx":4540
+ *       raise FstIOError("Open failed: {!r}".format(source))
  *     cdef FarWriter result = FarWriter.__new__(FarWriter)
  *     result._writer.reset(tfar)             # <<<<<<<<<<<<<<
  *     return result
@@ -45256,11 +46211,11 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_writer");
-    __PYX_ERR(0, 4465, __pyx_L1_error)
+    __PYX_ERR(0, 4540, __pyx_L1_error)
   }
   __pyx_v_result->_writer.reset(__pyx_v_tfar);
 
-  /* "pywrapfst.pyx":4466
+  /* "pywrapfst.pyx":4541
  *     cdef FarWriter result = FarWriter.__new__(FarWriter)
  *     result._writer.reset(tfar)
  *     return result             # <<<<<<<<<<<<<<
@@ -45272,10 +46227,10 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
   __pyx_r = ((PyObject *)__pyx_v_result);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4438
+  /* "pywrapfst.pyx":4511
  * 
  *   @classmethod
- *   def create(cls, filename, arc_type=b"standard", far_type=b"default"):             # <<<<<<<<<<<<<<
+ *   def create(cls, source, arc_type=b"standard", far_type=b"default"):             # <<<<<<<<<<<<<<
  *     """
  *     FarWriter.
  */
@@ -45296,7 +46251,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4470
+/* "pywrapfst.pyx":4545
  *   # NB: Invoking this method may be dangerous: calling any other method on the
  *   # instance after this is invoked may result in a null dereference.
  *   cdef void close(self):             # <<<<<<<<<<<<<<
@@ -45308,7 +46263,7 @@ static void __pyx_f_9pywrapfst_9FarWriter_close(struct __pyx_obj_9pywrapfst_FarW
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("close", 0);
 
-  /* "pywrapfst.pyx":4471
+  /* "pywrapfst.pyx":4546
  *   # instance after this is invoked may result in a null dereference.
  *   cdef void close(self):
  *     self._writer.reset()             # <<<<<<<<<<<<<<
@@ -45317,11 +46272,11 @@ static void __pyx_f_9pywrapfst_9FarWriter_close(struct __pyx_obj_9pywrapfst_FarW
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_writer");
-    __PYX_ERR(0, 4471, __pyx_L1_error)
+    __PYX_ERR(0, 4546, __pyx_L1_error)
   }
   __pyx_v_self->_writer.reset();
 
-  /* "pywrapfst.pyx":4470
+  /* "pywrapfst.pyx":4545
  *   # NB: Invoking this method may be dangerous: calling any other method on the
  *   # instance after this is invoked may result in a null dereference.
  *   cdef void close(self):             # <<<<<<<<<<<<<<
@@ -45337,7 +46292,7 @@ static void __pyx_f_9pywrapfst_9FarWriter_close(struct __pyx_obj_9pywrapfst_FarW
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":4473
+/* "pywrapfst.pyx":4548
  *     self._writer.reset()
  * 
  *   cpdef void add(self, key, _Fst ifst) except *:             # <<<<<<<<<<<<<<
@@ -45366,7 +46321,7 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4473, __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, 4548, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarWriter_7add)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -45385,7 +46340,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, 4473, __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, 4548, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
           __Pyx_GOTREF(__pyx_t_2);
         } else
@@ -45393,13 +46348,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, 4473, __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, 4548, __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, 4473, __pyx_L1_error)
+          __pyx_t_6 = PyTuple_New(2+__pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4548, __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;
@@ -45410,7 +46365,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, 4473, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4548, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
         }
@@ -45432,7 +46387,7 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
     #endif
   }
 
-  /* "pywrapfst.pyx":4492
+  /* "pywrapfst.pyx":4567
  *     # 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)):             # <<<<<<<<<<<<<<
@@ -45441,24 +46396,24 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_writer");
-    __PYX_ERR(0, 4492, __pyx_L1_error)
+    __PYX_ERR(0, 4567, __pyx_L1_error)
   }
-  __pyx_t_7 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4492, __pyx_L1_error)
+  __pyx_t_7 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4567, __pyx_L1_error)
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 4492, __pyx_L1_error)
+    __PYX_ERR(0, 4567, __pyx_L1_error)
   }
   __pyx_t_8 = ((!(__pyx_v_self->_writer.get()->Add(__pyx_t_7, (*__pyx_v_ifst->_fst)) != 0)) != 0);
   if (unlikely(__pyx_t_8)) {
 
-    /* "pywrapfst.pyx":4493
+    /* "pywrapfst.pyx":4568
  *     # used by the FAR was initialized to use.
  *     if not self._writer.get().Add(tostring(key), deref(ifst._fst)):
  *       raise FstOpError("Incompatible or invalid arc type")             # <<<<<<<<<<<<<<
  *     # An error here usually indicates a key out of order.
  *     if self._writer.get().Error():
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4493, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4568, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_3 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -45472,14 +46427,14 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
     }
     __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_kp_u_Incompatible_or_invalid_arc_type) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_Incompatible_or_invalid_arc_type);
     __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4493, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4568, __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, 4493, __pyx_L1_error)
+    __PYX_ERR(0, 4568, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4492
+    /* "pywrapfst.pyx":4567
  *     # 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)):             # <<<<<<<<<<<<<<
@@ -45488,7 +46443,7 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
  */
   }
 
-  /* "pywrapfst.pyx":4495
+  /* "pywrapfst.pyx":4570
  *       raise FstOpError("Incompatible or invalid arc type")
  *     # An error here usually indicates a key out of order.
  *     if self._writer.get().Error():             # <<<<<<<<<<<<<<
@@ -45497,19 +46452,19 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_writer");
-    __PYX_ERR(0, 4495, __pyx_L1_error)
+    __PYX_ERR(0, 4570, __pyx_L1_error)
   }
   __pyx_t_8 = (__pyx_v_self->_writer.get()->Error() != 0);
   if (unlikely(__pyx_t_8)) {
 
-    /* "pywrapfst.pyx":4496
+    /* "pywrapfst.pyx":4571
  *     # An error here usually indicates a key out of order.
  *     if self._writer.get().Error():
  *       raise FstArgError("Key out of order")             # <<<<<<<<<<<<<<
  * 
  *   cpdef string arc_type(self):
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4496, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4571, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_3 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -45523,14 +46478,14 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
     }
     __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_kp_u_Key_out_of_order) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_Key_out_of_order);
     __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4496, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4571, __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, 4496, __pyx_L1_error)
+    __PYX_ERR(0, 4571, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4495
+    /* "pywrapfst.pyx":4570
  *       raise FstOpError("Incompatible or invalid arc type")
  *     # An error here usually indicates a key out of order.
  *     if self._writer.get().Error():             # <<<<<<<<<<<<<<
@@ -45539,7 +46494,7 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
  */
   }
 
-  /* "pywrapfst.pyx":4473
+  /* "pywrapfst.pyx":4548
  *     self._writer.reset()
  * 
  *   cpdef void add(self, key, _Fst ifst) except *:             # <<<<<<<<<<<<<<
@@ -45592,11 +46547,11 @@ static PyObject *__pyx_pw_9pywrapfst_9FarWriter_7add(PyObject *__pyx_v_self, PyO
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ifst)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("add", 1, 2, 2, 1); __PYX_ERR(0, 4473, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("add", 1, 2, 2, 1); __PYX_ERR(0, 4548, __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, 4473, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add") < 0)) __PYX_ERR(0, 4548, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -45609,13 +46564,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, 4473, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("add", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4548, __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, 4473, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 4548, __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 */
@@ -45633,8 +46588,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, 4473, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4473, __pyx_L1_error)
+  __pyx_f_9pywrapfst_9FarWriter_add(__pyx_v_self, __pyx_v_key, __pyx_v_ifst, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4548, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4548, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -45651,7 +46606,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_6add(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4498
+/* "pywrapfst.pyx":4573
  *       raise FstArgError("Key out of order")
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
@@ -45678,7 +46633,7 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_arc_type(struct __pyx_obj_9pywr
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4498, __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, 4573, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarWriter_9arc_type)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -45694,10 +46649,10 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_arc_type(struct __pyx_obj_9pywr
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4498, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4573, __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, 4498, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4573, __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;
@@ -45716,7 +46671,7 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_arc_type(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":4504
+  /* "pywrapfst.pyx":4579
  *     Returns a string indicating the arc type.
  *     """
  *     return self._writer.get().ArcType()             # <<<<<<<<<<<<<<
@@ -45725,12 +46680,12 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_arc_type(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_writer");
-    __PYX_ERR(0, 4504, __pyx_L1_error)
+    __PYX_ERR(0, 4579, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_writer.get()->ArcType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4498
+  /* "pywrapfst.pyx":4573
  *       raise FstArgError("Key out of order")
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
@@ -45771,7 +46726,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_8arc_type(struct __pyx_obj_9pywr
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("arc_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarWriter_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4498, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarWriter_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4573, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -45788,7 +46743,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_8arc_type(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4506
+/* "pywrapfst.pyx":4581
  *     return self._writer.get().ArcType()
  * 
  *   cpdef bool error(self):             # <<<<<<<<<<<<<<
@@ -45815,7 +46770,7 @@ static bool __pyx_f_9pywrapfst_9FarWriter_error(struct __pyx_obj_9pywrapfst_FarW
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_error); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4506, __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, 4581, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarWriter_11error)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -45831,10 +46786,10 @@ static bool __pyx_f_9pywrapfst_9FarWriter_error(struct __pyx_obj_9pywrapfst_FarW
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4506, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4581, __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, 4506, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4581, __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;
@@ -45853,7 +46808,7 @@ static bool __pyx_f_9pywrapfst_9FarWriter_error(struct __pyx_obj_9pywrapfst_FarW
     #endif
   }
 
-  /* "pywrapfst.pyx":4515
+  /* "pywrapfst.pyx":4590
  *       True if the FarWriter is in an errorful state, False otherwise.
  *     """
  *     return self._writer.get().Error()             # <<<<<<<<<<<<<<
@@ -45862,12 +46817,12 @@ static bool __pyx_f_9pywrapfst_9FarWriter_error(struct __pyx_obj_9pywrapfst_FarW
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_writer");
-    __PYX_ERR(0, 4515, __pyx_L1_error)
+    __PYX_ERR(0, 4590, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_writer.get()->Error();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4506
+  /* "pywrapfst.pyx":4581
  *     return self._writer.get().ArcType()
  * 
  *   cpdef bool error(self):             # <<<<<<<<<<<<<<
@@ -45908,7 +46863,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, 4506, __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, 4581, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -45925,7 +46880,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_10error(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4517
+/* "pywrapfst.pyx":4592
  *     return self._writer.get().Error()
  * 
  *   cpdef string far_type(self):             # <<<<<<<<<<<<<<
@@ -45952,7 +46907,7 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_far_type(struct __pyx_obj_9pywr
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_far_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4517, __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, 4592, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarWriter_13far_type)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -45968,10 +46923,10 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_far_type(struct __pyx_obj_9pywr
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4517, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4592, __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, 4517, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4592, __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;
@@ -45990,7 +46945,7 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_far_type(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":4523
+  /* "pywrapfst.pyx":4598
  *     Returns a string indicating the FAR type.
  *     """
  *     return fst.GetFarTypeString(self._writer.get().Type())             # <<<<<<<<<<<<<<
@@ -45999,12 +46954,12 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_far_type(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_writer");
-    __PYX_ERR(0, 4523, __pyx_L1_error)
+    __PYX_ERR(0, 4598, __pyx_L1_error)
   }
   __pyx_r = fst::GetFarTypeString(__pyx_v_self->_writer.get()->Type());
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4517
+  /* "pywrapfst.pyx":4592
  *     return self._writer.get().Error()
  * 
  *   cpdef string far_type(self):             # <<<<<<<<<<<<<<
@@ -46045,7 +47000,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_12far_type(struct __pyx_obj_9pyw
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("far_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarWriter_far_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4517, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarWriter_far_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4592, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -46062,7 +47017,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_12far_type(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4526
+/* "pywrapfst.pyx":4601
  * 
  *   # Dictionary-like assignment.
  *   def __setitem__(self, key, _Fst fst):             # <<<<<<<<<<<<<<
@@ -46076,7 +47031,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, 4526, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_fst), __pyx_ptype_9pywrapfst__Fst, 1, "fst", 0))) __PYX_ERR(0, 4601, __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 */
@@ -46093,20 +47048,20 @@ static int __pyx_pf_9pywrapfst_9FarWriter_14__setitem__(struct __pyx_obj_9pywrap
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__setitem__", 0);
 
-  /* "pywrapfst.pyx":4527
+  /* "pywrapfst.pyx":4602
  *   # Dictionary-like assignment.
  *   def __setitem__(self, key, _Fst fst):
  *     self.add(key, fst)             # <<<<<<<<<<<<<<
  * 
- * # Masks fst_error_fatal in-module.
+ * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "add");
-    __PYX_ERR(0, 4527, __pyx_L1_error)
+    __PYX_ERR(0, 4602, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_FarWriter *)__pyx_v_self->__pyx_vtab)->add(__pyx_v_self, __pyx_v_key, __pyx_v_fst, 0); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4527, __pyx_L1_error)
+  ((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, 4602, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4526
+  /* "pywrapfst.pyx":4601
  * 
  *   # Dictionary-like assignment.
  *   def __setitem__(self, key, _Fst fst):             # <<<<<<<<<<<<<<
@@ -46156,7 +47111,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_16__reduce_cython__(CYTHON_UNUSE
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._writer cannot be converted to a Python object for pickling")
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__58, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__56, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -46209,7 +47164,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_18__setstate_cython__(CYTHON_UNU
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._writer cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__59, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__57, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -46937,7 +47892,7 @@ static PyObject *__pyx_tp_new_9pywrapfst__EncodeMapperSymbolTable(PyTypeObject *
   if (unlikely(!o)) return 0;
   p = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *)o);
   p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_9pywrapfst__SymbolTable*)__pyx_vtabptr_9pywrapfst__EncodeMapperSymbolTable;
-  new((void*)&(p->_encoder)) std::shared_ptr<fst::script::EncodeMapperClass> ();
+  new((void*)&(p->_mapper)) std::shared_ptr<fst::script::EncodeMapperClass> ();
   return o;
 }
 
@@ -46948,7 +47903,7 @@ static void __pyx_tp_dealloc_9pywrapfst__EncodeMapperSymbolTable(PyObject *o) {
     if (PyObject_CallFinalizerFromDealloc(o)) return;
   }
   #endif
-  __Pyx_call_destructor(p->_encoder);
+  __Pyx_call_destructor(p->_mapper);
   __pyx_tp_dealloc_9pywrapfst__SymbolTable(o);
 }
 
@@ -47511,7 +48466,7 @@ static PyObject *__pyx_tp_new_9pywrapfst_EncodeMapper(PyTypeObject *t, CYTHON_UN
   if (unlikely(!o)) return 0;
   p = ((struct __pyx_obj_9pywrapfst_EncodeMapper *)o);
   p->__pyx_vtab = __pyx_vtabptr_9pywrapfst_EncodeMapper;
-  new((void*)&(p->_encoder)) std::shared_ptr<fst::script::EncodeMapperClass> ();
+  new((void*)&(p->_mapper)) std::shared_ptr<fst::script::EncodeMapperClass> ();
   return o;
 }
 
@@ -47522,21 +48477,24 @@ static void __pyx_tp_dealloc_9pywrapfst_EncodeMapper(PyObject *o) {
     if (PyObject_CallFinalizerFromDealloc(o)) return;
   }
   #endif
-  __Pyx_call_destructor(p->_encoder);
+  __Pyx_call_destructor(p->_mapper);
   (*Py_TYPE(o)->tp_free)(o);
 }
 
 static PyMethodDef __pyx_methods_9pywrapfst_EncodeMapper[] = {
-  {"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},
+  {"__reduce__", (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_7__reduce__, METH_NOARGS, 0},
+  {"arc_type", (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_9arc_type, METH_NOARGS, __pyx_doc_9pywrapfst_12EncodeMapper_8arc_type},
+  {"weight_type", (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_11weight_type, METH_NOARGS, __pyx_doc_9pywrapfst_12EncodeMapper_10weight_type},
+  {"flags", (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_13flags, METH_NOARGS, __pyx_doc_9pywrapfst_12EncodeMapper_12flags},
   {"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, __pyx_doc_9pywrapfst_12EncodeMapper_20weight_type},
-  {"__reduce_cython__", (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_23__reduce_cython__, METH_NOARGS, 0},
-  {"__setstate_cython__", (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_25__setstate_cython__, METH_O, 0},
+  {"read", (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_17read, METH_O, __pyx_doc_9pywrapfst_12EncodeMapper_16read},
+  {"read_from_string", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_12EncodeMapper_19read_from_string, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_12EncodeMapper_18read_from_string},
+  {"write", (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_21write, METH_O, __pyx_doc_9pywrapfst_12EncodeMapper_20write},
+  {"write_to_string", (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_23write_to_string, METH_NOARGS, __pyx_doc_9pywrapfst_12EncodeMapper_22write_to_string},
+  {"input_symbols", (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_25input_symbols, METH_NOARGS, __pyx_doc_9pywrapfst_12EncodeMapper_24input_symbols},
+  {"output_symbols", (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_27output_symbols, METH_NOARGS, __pyx_doc_9pywrapfst_12EncodeMapper_26output_symbols},
+  {"set_input_symbols", (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_29set_input_symbols, METH_O, __pyx_doc_9pywrapfst_12EncodeMapper_28set_input_symbols},
+  {"set_output_symbols", (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_31set_output_symbols, METH_O, __pyx_doc_9pywrapfst_12EncodeMapper_30set_output_symbols},
   {0, 0, 0, 0}
 };
 
@@ -47560,13 +48518,13 @@ static PyTypeObject __pyx_type_9pywrapfst_EncodeMapper = {
   0, /*tp_as_sequence*/
   0, /*tp_as_mapping*/
   0, /*tp_hash*/
-  __pyx_pw_9pywrapfst_12EncodeMapper_7__call__, /*tp_call*/
+  __pyx_pw_9pywrapfst_12EncodeMapper_5__call__, /*tp_call*/
   0, /*tp_str*/
   0, /*tp_getattro*/
   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  EncodeMapper(arc_type=\"standard\", encode_labels=False, encode_weights=False)\n\n  Arc encoder class, wrapping EncodeMapperClass.\n\n  This class provides an object which can be used to encode or decode FST arcs.\n  This is most useful to convert an FST to an unweighted acceptor, on which\n  some FST operations are more efficient, and then decoding the FST afterwards.\n\n  To use an instance of this class to encode or decode a mutable FST, pass it\n  as the first argument to the FST instance methods `encode` and `decode`.\n\n  For implementational reasons, it is not currently possible to use an encoder\n  on disk to construct this class.\n\n  Args:\n    arc_type: A string indicating the arc type.\n    encode_labels: Should labels be encoded?\n    encode_weights: Should weights be encoded?\n  ", /*tp_doc*/
+  "\n  EncodeMapper(arc_type=\"standard\", encode_labels=False, encode_weights=False)\n\n  Arc mapper class, wrapping EncodeMapperClass.\n\n  This class provides an object which can be used to encode or decode FST arcs.\n  This is most useful to convert an FST to an unweighted acceptor, on which\n  some FST operations are more efficient, and then decoding the FST afterwards.\n\n  To use an instance of this class to encode or decode a mutable FST, pass it\n  as the first argument to the FST instance methods `encode` and `decode`.\n\n  For implementational reasons, it is not currently possible to use an mapper\n  on disk to construct this class.\n\n  Args:\n    arc_type: A string indicating the arc type.\n    encode_labels: Should labels be encoded?\n    encode_weights: Should weights be encoded?\n  ", /*tp_doc*/
   0, /*tp_traverse*/
   0, /*tp_clear*/
   0, /*tp_richcompare*/
@@ -47769,7 +48727,7 @@ static PyMethodDef __pyx_methods_9pywrapfst__MutableFst[] = {
   {"set_properties", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_59set_properties, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_58set_properties},
   {"set_start", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_61set_start, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_60set_start},
   {"topsort", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_63topsort, METH_NOARGS, __pyx_doc_9pywrapfst_11_MutableFst_62topsort},
-  {"union", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_65union, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_64union},
+  {"union", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_65union, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_64union},
   {0, 0, 0, 0}
 };
 
@@ -48772,28 +49730,29 @@ static PyMethodDef __pyx_methods[] = {
   {"_read_SymbolTable_from_string", (PyCFunction)__pyx_pw_9pywrapfst_9_read_SymbolTable_from_string, METH_O, 0},
   {"compact_symbol_table", (PyCFunction)__pyx_pw_9pywrapfst_11compact_symbol_table, METH_O, __pyx_doc_9pywrapfst_10compact_symbol_table},
   {"merge_symbol_table", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_13merge_symbol_table, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_12merge_symbol_table},
-  {"_read", (PyCFunction)__pyx_pw_9pywrapfst_15_read, METH_O, 0},
-  {"_read_Fst_from_string", (PyCFunction)__pyx_pw_9pywrapfst_17_read_Fst_from_string, METH_O, 0},
-  {"arcmap", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_19arcmap, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_18arcmap},
-  {"compose", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_21compose, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_20compose},
-  {"convert", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_23convert, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_22convert},
-  {"determinize", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_25determinize, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_24determinize},
-  {"difference", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_27difference, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_26difference},
-  {"disambiguate", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_29disambiguate, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_28disambiguate},
-  {"epsnormalize", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_31epsnormalize, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_30epsnormalize},
-  {"equal", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_33equal, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_32equal},
-  {"equivalent", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_35equivalent, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_34equivalent},
-  {"intersect", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_37intersect, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_36intersect},
-  {"isomorphic", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_39isomorphic, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_38isomorphic},
-  {"prune", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_41prune, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_40prune},
-  {"push", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_43push, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_42push},
-  {"randequivalent", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_45randequivalent, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_44randequivalent},
-  {"randgen", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_47randgen, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_46randgen},
-  {"replace", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_49replace, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_48replace},
-  {"reverse", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_51reverse, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_50reverse},
-  {"shortestpath", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_55shortestpath, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_54shortestpath},
-  {"statemap", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_57statemap, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_56statemap},
-  {"synchronize", (PyCFunction)__pyx_pw_9pywrapfst_59synchronize, METH_O, __pyx_doc_9pywrapfst_58synchronize},
+  {"_read_EncodeMapper_from_string", (PyCFunction)__pyx_pw_9pywrapfst_15_read_EncodeMapper_from_string, METH_O, 0},
+  {"_read", (PyCFunction)__pyx_pw_9pywrapfst_17_read, METH_O, 0},
+  {"_read_Fst_from_string", (PyCFunction)__pyx_pw_9pywrapfst_19_read_Fst_from_string, METH_O, 0},
+  {"arcmap", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_21arcmap, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_20arcmap},
+  {"compose", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_23compose, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_22compose},
+  {"convert", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_25convert, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_24convert},
+  {"determinize", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_27determinize, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_26determinize},
+  {"difference", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_29difference, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_28difference},
+  {"disambiguate", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_31disambiguate, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_30disambiguate},
+  {"epsnormalize", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_33epsnormalize, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_32epsnormalize},
+  {"equal", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_35equal, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_34equal},
+  {"equivalent", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_37equivalent, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_36equivalent},
+  {"intersect", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_39intersect, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_38intersect},
+  {"isomorphic", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_41isomorphic, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_40isomorphic},
+  {"prune", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_43prune, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_42prune},
+  {"push", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_45push, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_44push},
+  {"randequivalent", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_47randequivalent, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_46randequivalent},
+  {"randgen", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_49randgen, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_48randgen},
+  {"replace", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_51replace, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_50replace},
+  {"reverse", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_53reverse, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_52reverse},
+  {"shortestpath", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_57shortestpath, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_56shortestpath},
+  {"statemap", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_59statemap, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_58statemap},
+  {"synchronize", (PyCFunction)__pyx_pw_9pywrapfst_61synchronize, METH_O, __pyx_doc_9pywrapfst_60synchronize},
   {0, 0, 0, 0}
 };
 
@@ -48996,7 +49955,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_kp_u_Write_failed_r, __pyx_k_Write_failed_r, sizeof(__pyx_k_Write_failed_r), 0, 1, 0, 0},
   {&__pyx_kp_u_Write_to_string_failed, __pyx_k_Write_to_string_failed, sizeof(__pyx_k_Write_to_string_failed), 0, 1, 0, 0},
   {&__pyx_n_s_Zero, __pyx_k_Zero, sizeof(__pyx_k_Zero), 0, 0, 1, 1},
-  {&__pyx_kp_b__10, __pyx_k__10, sizeof(__pyx_k__10), 0, 0, 0, 0},
+  {&__pyx_kp_b__8, __pyx_k__8, sizeof(__pyx_k__8), 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},
@@ -49044,7 +50003,6 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_epsilon_on_replace, __pyx_k_epsilon_on_replace, sizeof(__pyx_k_epsilon_on_replace), 0, 0, 1, 1},
   {&__pyx_n_s_error, __pyx_k_error, sizeof(__pyx_k_error), 0, 0, 1, 1},
   {&__pyx_n_s_far_type, __pyx_k_far_type, sizeof(__pyx_k_far_type), 0, 0, 1, 1},
-  {&__pyx_n_s_filename, __pyx_k_filename, sizeof(__pyx_k_filename), 0, 0, 1, 1},
   {&__pyx_n_s_final, __pyx_k_final, sizeof(__pyx_k_final), 0, 0, 1, 1},
   {&__pyx_n_s_find, __pyx_k_find, sizeof(__pyx_k_find), 0, 0, 1, 1},
   {&__pyx_n_s_flags, __pyx_k_flags, sizeof(__pyx_k_flags), 0, 0, 1, 1},
@@ -49138,6 +50096,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_queue_type, __pyx_k_queue_type, sizeof(__pyx_k_queue_type), 0, 0, 1, 1},
   {&__pyx_n_s_ranksep, __pyx_k_ranksep, sizeof(__pyx_k_ranksep), 0, 0, 1, 1},
   {&__pyx_n_s_read, __pyx_k_read, sizeof(__pyx_k_read), 0, 0, 1, 1},
+  {&__pyx_n_s_read_EncodeMapper_from_string, __pyx_k_read_EncodeMapper_from_string, sizeof(__pyx_k_read_EncodeMapper_from_string), 0, 0, 1, 1},
   {&__pyx_n_s_read_Fst_from_string, __pyx_k_read_Fst_from_string, sizeof(__pyx_k_read_Fst_from_string), 0, 0, 1, 1},
   {&__pyx_n_s_read_SymbolTable_from_string, __pyx_k_read_SymbolTable_from_string, sizeof(__pyx_k_read_SymbolTable_from_string), 0, 0, 1, 1},
   {&__pyx_n_s_read_from_string, __pyx_k_read_from_string, sizeof(__pyx_k_read_from_string), 0, 0, 1, 1},
@@ -49161,7 +50120,6 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_kp_s_self__aiter_self__fst_cannot_be, __pyx_k_self__aiter_self__fst_cannot_be, sizeof(__pyx_k_self__aiter_self__fst_cannot_be), 0, 0, 1, 0},
   {&__pyx_kp_s_self__aiter_self__mfst_cannot_be, __pyx_k_self__aiter_self__mfst_cannot_be, sizeof(__pyx_k_self__aiter_self__mfst_cannot_be), 0, 0, 1, 0},
   {&__pyx_kp_s_self__arc_cannot_be_converted_to, __pyx_k_self__arc_cannot_be_converted_to, sizeof(__pyx_k_self__arc_cannot_be_converted_to), 0, 0, 1, 0},
-  {&__pyx_kp_s_self__encoder_cannot_be_converte, __pyx_k_self__encoder_cannot_be_converte, sizeof(__pyx_k_self__encoder_cannot_be_converte), 0, 0, 1, 0},
   {&__pyx_kp_s_self__fst_self__siter_cannot_be, __pyx_k_self__fst_self__siter_cannot_be, sizeof(__pyx_k_self__fst_self__siter_cannot_be), 0, 0, 1, 0},
   {&__pyx_kp_s_self__reader_cannot_be_converted, __pyx_k_self__reader_cannot_be_converted, sizeof(__pyx_k_self__reader_cannot_be_converted), 0, 0, 1, 0},
   {&__pyx_kp_s_self__siter_self__table_cannot_b, __pyx_k_self__siter_self__table_cannot_b, sizeof(__pyx_k_self__siter_self__table_cannot_b), 0, 0, 1, 0},
@@ -49178,6 +50136,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_shortestdistance, __pyx_k_shortestdistance, sizeof(__pyx_k_shortestdistance), 0, 0, 1, 1},
   {&__pyx_n_s_show_weight_one, __pyx_k_show_weight_one, sizeof(__pyx_k_show_weight_one), 0, 0, 1, 1},
   {&__pyx_n_s_sort_type, __pyx_k_sort_type, sizeof(__pyx_k_sort_type), 0, 0, 1, 1},
+  {&__pyx_n_s_source, __pyx_k_source, sizeof(__pyx_k_source), 0, 0, 1, 1},
   {&__pyx_n_s_ssymbols, __pyx_k_ssymbols, sizeof(__pyx_k_ssymbols), 0, 0, 1, 1},
   {&__pyx_n_b_standard, __pyx_k_standard, sizeof(__pyx_k_standard), 0, 0, 0, 1},
   {&__pyx_n_s_start, __pyx_k_start, sizeof(__pyx_k_start), 0, 0, 1, 1},
@@ -49225,12 +50184,12 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) {
   __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) __PYX_ERR(0, 122, __pyx_L1_error)
   __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) __PYX_ERR(0, 127, __pyx_L1_error)
   __pyx_builtin_IOError = __Pyx_GetBuiltinName(__pyx_n_s_IOError); if (!__pyx_builtin_IOError) __PYX_ERR(0, 132, __pyx_L1_error)
-  __pyx_builtin_object = __Pyx_GetBuiltinName(__pyx_n_s_object); if (!__pyx_builtin_object) __PYX_ERR(0, 2778, __pyx_L1_error)
-  __pyx_builtin_staticmethod = __Pyx_GetBuiltinName(__pyx_n_s_staticmethod); if (!__pyx_builtin_staticmethod) __PYX_ERR(0, 2798, __pyx_L1_error)
+  __pyx_builtin_staticmethod = __Pyx_GetBuiltinName(__pyx_n_s_staticmethod); if (!__pyx_builtin_staticmethod) __PYX_ERR(0, 1344, __pyx_L1_error)
+  __pyx_builtin_object = __Pyx_GetBuiltinName(__pyx_n_s_object); if (!__pyx_builtin_object) __PYX_ERR(0, 2844, __pyx_L1_error)
   __pyx_builtin_id = __Pyx_GetBuiltinName(__pyx_n_s_id); if (!__pyx_builtin_id) __PYX_ERR(0, 356, __pyx_L1_error)
   __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) __PYX_ERR(1, 2, __pyx_L1_error)
-  __pyx_builtin_StopIteration = __Pyx_GetBuiltinName(__pyx_n_s_StopIteration); if (!__pyx_builtin_StopIteration) __PYX_ERR(0, 1170, __pyx_L1_error)
-  __pyx_builtin_KeyError = __Pyx_GetBuiltinName(__pyx_n_s_KeyError); if (!__pyx_builtin_KeyError) __PYX_ERR(0, 4407, __pyx_L1_error)
+  __pyx_builtin_StopIteration = __Pyx_GetBuiltinName(__pyx_n_s_StopIteration); if (!__pyx_builtin_StopIteration) __PYX_ERR(0, 1160, __pyx_L1_error)
+  __pyx_builtin_KeyError = __Pyx_GetBuiltinName(__pyx_n_s_KeyError); if (!__pyx_builtin_KeyError) __PYX_ERR(0, 4480, __pyx_L1_error)
   return 0;
   __pyx_L1_error:;
   return -1;
@@ -49278,38 +50237,19 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__5);
   __Pyx_GIVEREF(__pyx_tuple__5);
 
-  /* "(tree fragment)":2
- * def __reduce_cython__(self):
- *     raise TypeError("self._encoder cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
- * def __setstate_cython__(self, __pyx_state):
- *     raise TypeError("self._encoder cannot be converted to a Python object for pickling")
- */
-  __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_s_self__encoder_cannot_be_converte); if (unlikely(!__pyx_tuple__6)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__6);
-  __Pyx_GIVEREF(__pyx_tuple__6);
-
-  /* "(tree fragment)":4
- *     raise TypeError("self._encoder cannot be converted to a Python object for pickling")
- * def __setstate_cython__(self, __pyx_state):
- *     raise TypeError("self._encoder cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
- */
-  __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_s_self__encoder_cannot_be_converte); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__7);
-  __Pyx_GIVEREF(__pyx_tuple__7);
-
-  /* "pywrapfst.pyx":1402
+  /* "pywrapfst.pyx":1482
  *   @staticmethod
  *   cdef string _local_render_svg(const string &dot):
  *     proc = subprocess.Popen(("dot", "-Tsvg"),             # <<<<<<<<<<<<<<
  *                             stdin=subprocess.PIPE,
  *                             stdout=subprocess.PIPE)
  */
-  __pyx_tuple__8 = PyTuple_Pack(2, __pyx_n_u_dot, __pyx_kp_u_Tsvg); if (unlikely(!__pyx_tuple__8)) __PYX_ERR(0, 1402, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__8);
-  __Pyx_GIVEREF(__pyx_tuple__8);
-  __pyx_tuple__9 = PyTuple_Pack(1, __pyx_tuple__8); if (unlikely(!__pyx_tuple__9)) __PYX_ERR(0, 1402, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__9);
-  __Pyx_GIVEREF(__pyx_tuple__9);
+  __pyx_tuple__6 = PyTuple_Pack(2, __pyx_n_u_dot, __pyx_kp_u_Tsvg); if (unlikely(!__pyx_tuple__6)) __PYX_ERR(0, 1482, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__6);
+  __Pyx_GIVEREF(__pyx_tuple__6);
+  __pyx_tuple__7 = PyTuple_Pack(1, __pyx_tuple__6); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(0, 1482, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__7);
+  __Pyx_GIVEREF(__pyx_tuple__7);
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
@@ -49317,18 +50257,18 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._arc cannot be converted to a Python object for pickling")
  */
-  __pyx_tuple__23 = PyTuple_Pack(1, __pyx_kp_s_self__arc_cannot_be_converted_to); if (unlikely(!__pyx_tuple__23)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__23);
-  __Pyx_GIVEREF(__pyx_tuple__23);
+  __pyx_tuple__21 = PyTuple_Pack(1, __pyx_kp_s_self__arc_cannot_be_converted_to); if (unlikely(!__pyx_tuple__21)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__21);
+  __Pyx_GIVEREF(__pyx_tuple__21);
 
   /* "(tree fragment)":4
  *     raise TypeError("self._arc cannot be converted to a Python object for pickling")
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._arc cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_tuple__24 = PyTuple_Pack(1, __pyx_kp_s_self__arc_cannot_be_converted_to); if (unlikely(!__pyx_tuple__24)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__24);
-  __Pyx_GIVEREF(__pyx_tuple__24);
+  __pyx_tuple__22 = PyTuple_Pack(1, __pyx_kp_s_self__arc_cannot_be_converted_to); if (unlikely(!__pyx_tuple__22)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__22);
+  __Pyx_GIVEREF(__pyx_tuple__22);
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
@@ -49336,18 +50276,18 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._aiter,self._fst cannot be converted to a Python object for pickling")
  */
-  __pyx_tuple__25 = PyTuple_Pack(1, __pyx_kp_s_self__aiter_self__fst_cannot_be); if (unlikely(!__pyx_tuple__25)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__25);
-  __Pyx_GIVEREF(__pyx_tuple__25);
+  __pyx_tuple__23 = PyTuple_Pack(1, __pyx_kp_s_self__aiter_self__fst_cannot_be); if (unlikely(!__pyx_tuple__23)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__23);
+  __Pyx_GIVEREF(__pyx_tuple__23);
 
   /* "(tree fragment)":4
  *     raise TypeError("self._aiter,self._fst cannot be converted to a Python object for pickling")
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._aiter,self._fst cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_tuple__26 = PyTuple_Pack(1, __pyx_kp_s_self__aiter_self__fst_cannot_be); if (unlikely(!__pyx_tuple__26)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__26);
-  __Pyx_GIVEREF(__pyx_tuple__26);
+  __pyx_tuple__24 = PyTuple_Pack(1, __pyx_kp_s_self__aiter_self__fst_cannot_be); if (unlikely(!__pyx_tuple__24)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__24);
+  __Pyx_GIVEREF(__pyx_tuple__24);
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
@@ -49355,18 +50295,18 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._aiter,self._mfst cannot be converted to a Python object for pickling")
  */
-  __pyx_tuple__27 = PyTuple_Pack(1, __pyx_kp_s_self__aiter_self__mfst_cannot_be); if (unlikely(!__pyx_tuple__27)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__27);
-  __Pyx_GIVEREF(__pyx_tuple__27);
+  __pyx_tuple__25 = PyTuple_Pack(1, __pyx_kp_s_self__aiter_self__mfst_cannot_be); if (unlikely(!__pyx_tuple__25)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__25);
+  __Pyx_GIVEREF(__pyx_tuple__25);
 
   /* "(tree fragment)":4
  *     raise TypeError("self._aiter,self._mfst cannot be converted to a Python object for pickling")
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._aiter,self._mfst cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_tuple__28 = PyTuple_Pack(1, __pyx_kp_s_self__aiter_self__mfst_cannot_be); if (unlikely(!__pyx_tuple__28)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__28);
-  __Pyx_GIVEREF(__pyx_tuple__28);
+  __pyx_tuple__26 = PyTuple_Pack(1, __pyx_kp_s_self__aiter_self__mfst_cannot_be); if (unlikely(!__pyx_tuple__26)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__26);
+  __Pyx_GIVEREF(__pyx_tuple__26);
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
@@ -49374,18 +50314,18 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._fst,self._siter cannot be converted to a Python object for pickling")
  */
-  __pyx_tuple__29 = PyTuple_Pack(1, __pyx_kp_s_self__fst_self__siter_cannot_be); if (unlikely(!__pyx_tuple__29)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__29);
-  __Pyx_GIVEREF(__pyx_tuple__29);
+  __pyx_tuple__27 = PyTuple_Pack(1, __pyx_kp_s_self__fst_self__siter_cannot_be); if (unlikely(!__pyx_tuple__27)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__27);
+  __Pyx_GIVEREF(__pyx_tuple__27);
 
   /* "(tree fragment)":4
  *     raise TypeError("self._fst,self._siter cannot be converted to a Python object for pickling")
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._fst,self._siter cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_tuple__30 = PyTuple_Pack(1, __pyx_kp_s_self__fst_self__siter_cannot_be); if (unlikely(!__pyx_tuple__30)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__30);
-  __Pyx_GIVEREF(__pyx_tuple__30);
+  __pyx_tuple__28 = PyTuple_Pack(1, __pyx_kp_s_self__fst_self__siter_cannot_be); if (unlikely(!__pyx_tuple__28)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__28);
+  __Pyx_GIVEREF(__pyx_tuple__28);
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
@@ -49393,18 +50333,18 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")
  */
-  __pyx_tuple__54 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__54)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__54);
-  __Pyx_GIVEREF(__pyx_tuple__54);
+  __pyx_tuple__52 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__52)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__52);
+  __Pyx_GIVEREF(__pyx_tuple__52);
 
   /* "(tree fragment)":4
  *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")             # <<<<<<<<<<<<<<
  */
-  __pyx_tuple__55 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__55)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__55);
-  __Pyx_GIVEREF(__pyx_tuple__55);
+  __pyx_tuple__53 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__53)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__53);
+  __Pyx_GIVEREF(__pyx_tuple__53);
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
@@ -49412,18 +50352,18 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._reader cannot be converted to a Python object for pickling")
  */
-  __pyx_tuple__56 = PyTuple_Pack(1, __pyx_kp_s_self__reader_cannot_be_converted); if (unlikely(!__pyx_tuple__56)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__56);
-  __Pyx_GIVEREF(__pyx_tuple__56);
+  __pyx_tuple__54 = PyTuple_Pack(1, __pyx_kp_s_self__reader_cannot_be_converted); if (unlikely(!__pyx_tuple__54)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__54);
+  __Pyx_GIVEREF(__pyx_tuple__54);
 
   /* "(tree fragment)":4
  *     raise TypeError("self._reader cannot be converted to a Python object for pickling")
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._reader cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_tuple__57 = PyTuple_Pack(1, __pyx_kp_s_self__reader_cannot_be_converted); if (unlikely(!__pyx_tuple__57)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__57);
-  __Pyx_GIVEREF(__pyx_tuple__57);
+  __pyx_tuple__55 = PyTuple_Pack(1, __pyx_kp_s_self__reader_cannot_be_converted); if (unlikely(!__pyx_tuple__55)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__55);
+  __Pyx_GIVEREF(__pyx_tuple__55);
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
@@ -49431,18 +50371,18 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._writer cannot be converted to a Python object for pickling")
  */
-  __pyx_tuple__58 = PyTuple_Pack(1, __pyx_kp_s_self__writer_cannot_be_converted); if (unlikely(!__pyx_tuple__58)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__58);
-  __Pyx_GIVEREF(__pyx_tuple__58);
+  __pyx_tuple__56 = PyTuple_Pack(1, __pyx_kp_s_self__writer_cannot_be_converted); if (unlikely(!__pyx_tuple__56)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__56);
+  __Pyx_GIVEREF(__pyx_tuple__56);
 
   /* "(tree fragment)":4
  *     raise TypeError("self._writer cannot be converted to a Python object for pickling")
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._writer cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_tuple__59 = PyTuple_Pack(1, __pyx_kp_s_self__writer_cannot_be_converted); if (unlikely(!__pyx_tuple__59)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__59);
-  __Pyx_GIVEREF(__pyx_tuple__59);
+  __pyx_tuple__57 = PyTuple_Pack(1, __pyx_kp_s_self__writer_cannot_be_converted); if (unlikely(!__pyx_tuple__57)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__57);
+  __Pyx_GIVEREF(__pyx_tuple__57);
 
   /* "pywrapfst.pyx":445
  * 
@@ -49451,10 +50391,10 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  *   """
  *   plus(lhs, rhs)
  */
-  __pyx_tuple__60 = PyTuple_Pack(3, __pyx_n_s_lhs, __pyx_n_s_rhs, __pyx_n_s_result); if (unlikely(!__pyx_tuple__60)) __PYX_ERR(0, 445, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__60);
-  __Pyx_GIVEREF(__pyx_tuple__60);
-  __pyx_codeobj__61 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__60, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_plus, 445, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__61)) __PYX_ERR(0, 445, __pyx_L1_error)
+  __pyx_tuple__58 = PyTuple_Pack(3, __pyx_n_s_lhs, __pyx_n_s_rhs, __pyx_n_s_result); if (unlikely(!__pyx_tuple__58)) __PYX_ERR(0, 445, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__58);
+  __Pyx_GIVEREF(__pyx_tuple__58);
+  __pyx_codeobj__59 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__58, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_plus, 445, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__59)) __PYX_ERR(0, 445, __pyx_L1_error)
 
   /* "pywrapfst.pyx":477
  * 
@@ -49463,10 +50403,10 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  *   """
  *   times(lhs, rhs)
  */
-  __pyx_tuple__62 = PyTuple_Pack(3, __pyx_n_s_lhs, __pyx_n_s_rhs, __pyx_n_s_result); if (unlikely(!__pyx_tuple__62)) __PYX_ERR(0, 477, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__62);
-  __Pyx_GIVEREF(__pyx_tuple__62);
-  __pyx_codeobj__63 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__62, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_times, 477, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__63)) __PYX_ERR(0, 477, __pyx_L1_error)
+  __pyx_tuple__60 = PyTuple_Pack(3, __pyx_n_s_lhs, __pyx_n_s_rhs, __pyx_n_s_result); if (unlikely(!__pyx_tuple__60)) __PYX_ERR(0, 477, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__60);
+  __Pyx_GIVEREF(__pyx_tuple__60);
+  __pyx_codeobj__61 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__60, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_times, 477, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__61)) __PYX_ERR(0, 477, __pyx_L1_error)
 
   /* "pywrapfst.pyx":509
  * 
@@ -49475,10 +50415,10 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  *   """
  *   divide(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, 509, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__64);
-  __Pyx_GIVEREF(__pyx_tuple__64);
-  __pyx_codeobj__65 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__64, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_divide, 509, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__65)) __PYX_ERR(0, 509, __pyx_L1_error)
+  __pyx_tuple__62 = PyTuple_Pack(3, __pyx_n_s_lhs, __pyx_n_s_rhs, __pyx_n_s_result); if (unlikely(!__pyx_tuple__62)) __PYX_ERR(0, 509, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__62);
+  __Pyx_GIVEREF(__pyx_tuple__62);
+  __pyx_codeobj__63 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__62, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_divide, 509, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__63)) __PYX_ERR(0, 509, __pyx_L1_error)
 
   /* "pywrapfst.pyx":542
  * 
@@ -49487,72 +50427,84 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  *   """
  *   power(lhs, rhs)
  */
-  __pyx_tuple__66 = PyTuple_Pack(3, __pyx_n_s_w, __pyx_n_s_n, __pyx_n_s_result); if (unlikely(!__pyx_tuple__66)) __PYX_ERR(0, 542, __pyx_L1_error)
+  __pyx_tuple__64 = PyTuple_Pack(3, __pyx_n_s_w, __pyx_n_s_n, __pyx_n_s_result); if (unlikely(!__pyx_tuple__64)) __PYX_ERR(0, 542, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__64);
+  __Pyx_GIVEREF(__pyx_tuple__64);
+  __pyx_codeobj__65 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__64, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_power, 542, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__65)) __PYX_ERR(0, 542, __pyx_L1_error)
+
+  /* "pywrapfst.pyx":1345
+ * 
+ *   @staticmethod
+ *   def read_from_string(state):             # <<<<<<<<<<<<<<
+ *     """
+ *     read_from_string(state)
+ */
+  __pyx_tuple__66 = PyTuple_Pack(1, __pyx_n_s_state); if (unlikely(!__pyx_tuple__66)) __PYX_ERR(0, 1345, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__66);
   __Pyx_GIVEREF(__pyx_tuple__66);
-  __pyx_codeobj__67 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__66, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_power, 542, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__67)) __PYX_ERR(0, 542, __pyx_L1_error)
+  __pyx_codeobj__67 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__66, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_read_from_string, 1345, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__67)) __PYX_ERR(0, 1345, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2778
+  /* "pywrapfst.pyx":2844
  * 
  * 
  * class Fst(object):             # <<<<<<<<<<<<<<
  * 
  *    """
  */
-  __pyx_tuple__68 = PyTuple_Pack(1, __pyx_builtin_object); if (unlikely(!__pyx_tuple__68)) __PYX_ERR(0, 2778, __pyx_L1_error)
+  __pyx_tuple__68 = PyTuple_Pack(1, __pyx_builtin_object); if (unlikely(!__pyx_tuple__68)) __PYX_ERR(0, 2844, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__68);
   __Pyx_GIVEREF(__pyx_tuple__68);
 
-  /* "pywrapfst.pyx":2795
+  /* "pywrapfst.pyx":2861
  *    """
  * 
  *    def __new__(cls, arc_type=b"standard"):             # <<<<<<<<<<<<<<
  *     return _create_Fst(arc_type)
  * 
  */
-  __pyx_tuple__69 = PyTuple_Pack(2, __pyx_n_s_cls, __pyx_n_s_arc_type); if (unlikely(!__pyx_tuple__69)) __PYX_ERR(0, 2795, __pyx_L1_error)
+  __pyx_tuple__69 = PyTuple_Pack(2, __pyx_n_s_cls, __pyx_n_s_arc_type); if (unlikely(!__pyx_tuple__69)) __PYX_ERR(0, 2861, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__69);
   __Pyx_GIVEREF(__pyx_tuple__69);
-  __pyx_codeobj__70 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__69, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_new, 2795, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__70)) __PYX_ERR(0, 2795, __pyx_L1_error)
-  __pyx_tuple__71 = PyTuple_Pack(1, ((PyObject*)__pyx_n_b_standard)); if (unlikely(!__pyx_tuple__71)) __PYX_ERR(0, 2795, __pyx_L1_error)
+  __pyx_codeobj__70 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__69, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_new, 2861, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__70)) __PYX_ERR(0, 2861, __pyx_L1_error)
+  __pyx_tuple__71 = PyTuple_Pack(1, ((PyObject*)__pyx_n_b_standard)); if (unlikely(!__pyx_tuple__71)) __PYX_ERR(0, 2861, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__71);
   __Pyx_GIVEREF(__pyx_tuple__71);
 
-  /* "pywrapfst.pyx":2799
+  /* "pywrapfst.pyx":2865
  * 
  *    @staticmethod
- *    def read(filename):             # <<<<<<<<<<<<<<
+ *    def read(source):             # <<<<<<<<<<<<<<
  *      """
- *      read(filename):
+ *      read(source)
  */
-  __pyx_tuple__72 = PyTuple_Pack(1, __pyx_n_s_filename); if (unlikely(!__pyx_tuple__72)) __PYX_ERR(0, 2799, __pyx_L1_error)
+  __pyx_tuple__72 = PyTuple_Pack(1, __pyx_n_s_source); if (unlikely(!__pyx_tuple__72)) __PYX_ERR(0, 2865, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__72);
   __Pyx_GIVEREF(__pyx_tuple__72);
-  __pyx_codeobj__73 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__72, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_read, 2799, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__73)) __PYX_ERR(0, 2799, __pyx_L1_error)
+  __pyx_codeobj__73 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__72, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_read, 2865, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__73)) __PYX_ERR(0, 2865, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2817
+  /* "pywrapfst.pyx":2883
  * 
  *    @staticmethod
  *    def read_from_string(state):             # <<<<<<<<<<<<<<
  *      """
- *      read_from_string(string, fst_type=None)
+ *      read_from_string(state)
  */
-  __pyx_tuple__74 = PyTuple_Pack(1, __pyx_n_s_state); if (unlikely(!__pyx_tuple__74)) __PYX_ERR(0, 2817, __pyx_L1_error)
+  __pyx_tuple__74 = PyTuple_Pack(1, __pyx_n_s_state); if (unlikely(!__pyx_tuple__74)) __PYX_ERR(0, 2883, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__74);
   __Pyx_GIVEREF(__pyx_tuple__74);
-  __pyx_codeobj__75 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__74, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_read_from_string, 2817, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__75)) __PYX_ERR(0, 2817, __pyx_L1_error)
+  __pyx_codeobj__75 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__74, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_read_from_string, 2883, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__75)) __PYX_ERR(0, 2883, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3992
+  /* "pywrapfst.pyx":4056
  * 
  * 
  * def shortestdistance(_Fst ifst,             # <<<<<<<<<<<<<<
  *                      float delta=fst.kShortestDelta,
  *                      int64 nstate=fst.kNoStateId,
  */
-  __pyx_tuple__76 = PyTuple_Pack(8, __pyx_n_s_ifst, __pyx_n_s_delta, __pyx_n_s_nstate, __pyx_n_s_queue_type, __pyx_n_s_reverse, __pyx_n_s_distance, __pyx_n_s_weight_type, __pyx_n_s_weight); if (unlikely(!__pyx_tuple__76)) __PYX_ERR(0, 3992, __pyx_L1_error)
+  __pyx_tuple__76 = PyTuple_Pack(8, __pyx_n_s_ifst, __pyx_n_s_delta, __pyx_n_s_nstate, __pyx_n_s_queue_type, __pyx_n_s_reverse, __pyx_n_s_distance, __pyx_n_s_weight_type, __pyx_n_s_weight); if (unlikely(!__pyx_tuple__76)) __PYX_ERR(0, 4056, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__76);
   __Pyx_GIVEREF(__pyx_tuple__76);
-  __pyx_codeobj__77 = (PyObject*)__Pyx_PyCode_New(5, 0, 8, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__76, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_shortestdistance, 3992, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__77)) __PYX_ERR(0, 3992, __pyx_L1_error)
+  __pyx_codeobj__77 = (PyObject*)__Pyx_PyCode_New(5, 0, 8, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__76, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_shortestdistance, 4056, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__77)) __PYX_ERR(0, 4056, __pyx_L1_error)
   __Pyx_RefNannyFinishContext();
   return 0;
   __pyx_L1_error:;
@@ -49616,6 +50568,8 @@ static int __Pyx_modinit_function_export_code(void) {
   if (__Pyx_ExportFunction("_init_MutableFstSymbolTable", (void (*)(void))__pyx_f_9pywrapfst__init_MutableFstSymbolTable, "struct __pyx_obj_9pywrapfst__MutableFstSymbolTable *(fst::SymbolTable *, std::shared_ptr<fst::script::MutableFstClass> )") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("_init_SymbolTable", (void (*)(void))__pyx_f_9pywrapfst__init_SymbolTable, "struct __pyx_obj_9pywrapfst_SymbolTable *(fst::SymbolTable *)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("_read_SymbolTable_from_string", (void (*)(void))__pyx_f_9pywrapfst__read_SymbolTable_from_string, "struct __pyx_obj_9pywrapfst_SymbolTable *(PyObject *, int __pyx_skip_dispatch)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
+  if (__Pyx_ExportFunction("_init_EncodeMapper", (void (*)(void))__pyx_f_9pywrapfst__init_EncodeMapper, "struct __pyx_obj_9pywrapfst_EncodeMapper *(fst::script::EncodeMapperClass *)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
+  if (__Pyx_ExportFunction("_read_EncodeMapper_from_string", (void (*)(void))__pyx_f_9pywrapfst__read_EncodeMapper_from_string, "struct __pyx_obj_9pywrapfst_EncodeMapper *(PyObject *, int __pyx_skip_dispatch)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("_init_Fst", (void (*)(void))__pyx_f_9pywrapfst__init_Fst, "struct __pyx_obj_9pywrapfst__Fst *(__pyx_t_9pywrapfst_FstClass_ptr)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("_init_MutableFst", (void (*)(void))__pyx_f_9pywrapfst__init_MutableFst, "struct __pyx_obj_9pywrapfst__MutableFst *(__pyx_t_9pywrapfst_MutableFstClass_ptr)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("_init_XFst", (void (*)(void))__pyx_f_9pywrapfst__init_XFst, "struct __pyx_obj_9pywrapfst__Fst *(__pyx_t_9pywrapfst_FstClass_ptr)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
@@ -49698,28 +50652,28 @@ static int __Pyx_modinit_type_init_code(void) {
   __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, 852, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst__EncodeMapperSymbolTable) < 0) __PYX_ERR(0, 850, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst__EncodeMapperSymbolTable.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst__EncodeMapperSymbolTable.tp_dictoffset && __pyx_type_9pywrapfst__EncodeMapperSymbolTable.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst__EncodeMapperSymbolTable.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__EncodeMapperSymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst__EncodeMapperSymbolTable) < 0) __PYX_ERR(0, 852, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_EncodeMapperSymbolTable, (PyObject *)&__pyx_type_9pywrapfst__EncodeMapperSymbolTable) < 0) __PYX_ERR(0, 852, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__EncodeMapperSymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst__EncodeMapperSymbolTable) < 0) __PYX_ERR(0, 850, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_EncodeMapperSymbolTable, (PyObject *)&__pyx_type_9pywrapfst__EncodeMapperSymbolTable) < 0) __PYX_ERR(0, 850, __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, 872, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst__FstSymbolTable) < 0) __PYX_ERR(0, 870, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst__FstSymbolTable.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst__FstSymbolTable.tp_dictoffset && __pyx_type_9pywrapfst__FstSymbolTable.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst__FstSymbolTable.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__FstSymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst__FstSymbolTable) < 0) __PYX_ERR(0, 872, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_FstSymbolTable, (PyObject *)&__pyx_type_9pywrapfst__FstSymbolTable) < 0) __PYX_ERR(0, 872, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__FstSymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst__FstSymbolTable) < 0) __PYX_ERR(0, 870, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_FstSymbolTable, (PyObject *)&__pyx_type_9pywrapfst__FstSymbolTable) < 0) __PYX_ERR(0, 870, __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;
@@ -49727,41 +50681,41 @@ static int __Pyx_modinit_type_init_code(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, 891, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst__MutableSymbolTable) < 0) __PYX_ERR(0, 889, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst__MutableSymbolTable.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst__MutableSymbolTable.tp_dictoffset && __pyx_type_9pywrapfst__MutableSymbolTable.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst__MutableSymbolTable.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__MutableSymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst__MutableSymbolTable) < 0) __PYX_ERR(0, 891, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_MutableSymbolTable, (PyObject *)&__pyx_type_9pywrapfst__MutableSymbolTable) < 0) __PYX_ERR(0, 891, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__MutableSymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst__MutableSymbolTable) < 0) __PYX_ERR(0, 889, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_MutableSymbolTable, (PyObject *)&__pyx_type_9pywrapfst__MutableSymbolTable) < 0) __PYX_ERR(0, 889, __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, 943, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst__MutableFstSymbolTable) < 0) __PYX_ERR(0, 941, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst__MutableFstSymbolTable.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst__MutableFstSymbolTable.tp_dictoffset && __pyx_type_9pywrapfst__MutableFstSymbolTable.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst__MutableFstSymbolTable.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__MutableFstSymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst__MutableFstSymbolTable) < 0) __PYX_ERR(0, 943, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_MutableFstSymbolTable, (PyObject *)&__pyx_type_9pywrapfst__MutableFstSymbolTable) < 0) __PYX_ERR(0, 943, __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_SetAttr(__pyx_m, __pyx_n_s_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, 954, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_SymbolTable) < 0) __PYX_ERR(0, 952, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_SymbolTable.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_SymbolTable.tp_dictoffset && __pyx_type_9pywrapfst_SymbolTable.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_SymbolTable.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_SymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst_SymbolTable) < 0) __PYX_ERR(0, 954, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_SymbolTable_2, (PyObject *)&__pyx_type_9pywrapfst_SymbolTable) < 0) __PYX_ERR(0, 954, __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_SetAttr(__pyx_m, __pyx_n_s_SymbolTable_2, (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;
@@ -49769,27 +50723,29 @@ static int __Pyx_modinit_type_init_code(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, 1149, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_SymbolTableIterator) < 0) __PYX_ERR(0, 1139, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_SymbolTableIterator.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_SymbolTableIterator.tp_dictoffset && __pyx_type_9pywrapfst_SymbolTableIterator.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_SymbolTableIterator.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_SymbolTableIterator.tp_dict, __pyx_vtabptr_9pywrapfst_SymbolTableIterator) < 0) __PYX_ERR(0, 1149, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_SymbolTableIterator, (PyObject *)&__pyx_type_9pywrapfst_SymbolTableIterator) < 0) __PYX_ERR(0, 1149, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_SymbolTableIterator) < 0) __PYX_ERR(0, 1149, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_SymbolTableIterator.tp_dict, __pyx_vtabptr_9pywrapfst_SymbolTableIterator) < 0) __PYX_ERR(0, 1139, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_SymbolTableIterator, (PyObject *)&__pyx_type_9pywrapfst_SymbolTableIterator) < 0) __PYX_ERR(0, 1139, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_SymbolTableIterator) < 0) __PYX_ERR(0, 1139, __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;
-  __pyx_vtable_9pywrapfst_EncodeMapper.flags = (__pyx_t_10basictypes_uint32 (*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12EncodeMapper_flags;
+  __pyx_vtable_9pywrapfst_EncodeMapper.weight_type = (std::string (*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12EncodeMapper_weight_type;
+  __pyx_vtable_9pywrapfst_EncodeMapper.flags = (__pyx_t_10basictypes_uint8 (*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12EncodeMapper_flags;
+  __pyx_vtable_9pywrapfst_EncodeMapper.properties = (__pyx_t_10basictypes_uint64 (*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, __pyx_t_10basictypes_uint64, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12EncodeMapper_properties;
+  __pyx_vtable_9pywrapfst_EncodeMapper.write = (void (*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, PyObject *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12EncodeMapper_write;
+  __pyx_vtable_9pywrapfst_EncodeMapper.write_to_string = (PyObject *(*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12EncodeMapper_write_to_string;
   __pyx_vtable_9pywrapfst_EncodeMapper.input_symbols = (struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *(*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12EncodeMapper_input_symbols;
   __pyx_vtable_9pywrapfst_EncodeMapper.output_symbols = (struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *(*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12EncodeMapper_output_symbols;
-  __pyx_vtable_9pywrapfst_EncodeMapper.properties = (__pyx_t_10basictypes_uint64 (*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, __pyx_t_10basictypes_uint64, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12EncodeMapper_properties;
   __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, 1231, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_EncodeMapper) < 0) __PYX_ERR(0, 1221, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_EncodeMapper.tp_print = 0;
   #endif
@@ -49798,17 +50754,16 @@ static int __Pyx_modinit_type_init_code(void) {
   }
   #if CYTHON_COMPILING_IN_CPYTHON
   {
-    PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_9pywrapfst_EncodeMapper, "__call__"); if (unlikely(!wrapper)) __PYX_ERR(0, 1231, __pyx_L1_error)
+    PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_9pywrapfst_EncodeMapper, "__call__"); if (unlikely(!wrapper)) __PYX_ERR(0, 1221, __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__;
-      ((PyWrapperDescrObject *)wrapper)->d_base = &__pyx_wrapperbase_9pywrapfst_12EncodeMapper_6__call__;
+      __pyx_wrapperbase_9pywrapfst_12EncodeMapper_4__call__ = *((PyWrapperDescrObject *)wrapper)->d_base;
+      __pyx_wrapperbase_9pywrapfst_12EncodeMapper_4__call__.doc = __pyx_doc_9pywrapfst_12EncodeMapper_4__call__;
+      ((PyWrapperDescrObject *)wrapper)->d_base = &__pyx_wrapperbase_9pywrapfst_12EncodeMapper_4__call__;
     }
   }
   #endif
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_EncodeMapper.tp_dict, __pyx_vtabptr_9pywrapfst_EncodeMapper) < 0) __PYX_ERR(0, 1231, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_EncodeMapper, (PyObject *)&__pyx_type_9pywrapfst_EncodeMapper) < 0) __PYX_ERR(0, 1231, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_EncodeMapper) < 0) __PYX_ERR(0, 1231, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_EncodeMapper.tp_dict, __pyx_vtabptr_9pywrapfst_EncodeMapper) < 0) __PYX_ERR(0, 1221, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_EncodeMapper, (PyObject *)&__pyx_type_9pywrapfst_EncodeMapper) < 0) __PYX_ERR(0, 1221, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_EncodeMapper = &__pyx_type_9pywrapfst_EncodeMapper;
   __pyx_vtabptr_9pywrapfst__Fst = &__pyx_vtable_9pywrapfst__Fst;
   __pyx_vtable_9pywrapfst__Fst._local_render_svg = (std::string (*)(std::string const &))__pyx_f_9pywrapfst_4_Fst__local_render_svg;
@@ -49831,15 +50786,15 @@ static int __Pyx_modinit_type_init_code(void) {
   __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.write_to_string = (PyObject *(*)(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_4_Fst_write_to_string;
-  if (PyType_Ready(&__pyx_type_9pywrapfst__Fst) < 0) __PYX_ERR(0, 1387, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst__Fst) < 0) __PYX_ERR(0, 1467, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst__Fst.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst__Fst.tp_dictoffset && __pyx_type_9pywrapfst__Fst.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst__Fst.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__Fst.tp_dict, __pyx_vtabptr_9pywrapfst__Fst) < 0) __PYX_ERR(0, 1387, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Fst, (PyObject *)&__pyx_type_9pywrapfst__Fst) < 0) __PYX_ERR(0, 1387, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__Fst.tp_dict, __pyx_vtabptr_9pywrapfst__Fst) < 0) __PYX_ERR(0, 1467, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Fst, (PyObject *)&__pyx_type_9pywrapfst__Fst) < 0) __PYX_ERR(0, 1467, __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;
@@ -49874,101 +50829,100 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst__MutableFst._set_input_symbols = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_obj_9pywrapfst__SymbolTable *))__pyx_f_9pywrapfst_11_MutableFst__set_input_symbols;
   __pyx_vtable_9pywrapfst__MutableFst._set_output_symbols = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_obj_9pywrapfst__SymbolTable *))__pyx_f_9pywrapfst_11_MutableFst__set_output_symbols;
   __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, 1802, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst__MutableFst) < 0) __PYX_ERR(0, 1888, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst__MutableFst.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst__MutableFst.tp_dictoffset && __pyx_type_9pywrapfst__MutableFst.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst__MutableFst.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__MutableFst.tp_dict, __pyx_vtabptr_9pywrapfst__MutableFst) < 0) __PYX_ERR(0, 1802, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_MutableFst, (PyObject *)&__pyx_type_9pywrapfst__MutableFst) < 0) __PYX_ERR(0, 1802, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__MutableFst.tp_dict, __pyx_vtabptr_9pywrapfst__MutableFst) < 0) __PYX_ERR(0, 1888, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_MutableFst, (PyObject *)&__pyx_type_9pywrapfst__MutableFst) < 0) __PYX_ERR(0, 1888, __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, 2932, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_Arc) < 0) __PYX_ERR(0, 2995, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_Arc.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_Arc.tp_dictoffset && __pyx_type_9pywrapfst_Arc.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_Arc.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_Arc.tp_dict, __pyx_vtabptr_9pywrapfst_Arc) < 0) __PYX_ERR(0, 2932, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Arc, (PyObject *)&__pyx_type_9pywrapfst_Arc) < 0) __PYX_ERR(0, 2932, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_Arc) < 0) __PYX_ERR(0, 2932, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_Arc.tp_dict, __pyx_vtabptr_9pywrapfst_Arc) < 0) __PYX_ERR(0, 2995, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Arc, (PyObject *)&__pyx_type_9pywrapfst_Arc) < 0) __PYX_ERR(0, 2995, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_Arc) < 0) __PYX_ERR(0, 2995, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_Arc = &__pyx_type_9pywrapfst_Arc;
   __pyx_vtabptr_9pywrapfst_ArcIterator = &__pyx_vtable_9pywrapfst_ArcIterator;
   __pyx_vtable_9pywrapfst_ArcIterator.done = (bool (*)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11ArcIterator_done;
-  __pyx_vtable_9pywrapfst_ArcIterator.flags = (__pyx_t_10basictypes_uint32 (*)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11ArcIterator_flags;
+  __pyx_vtable_9pywrapfst_ArcIterator.flags = (__pyx_t_10basictypes_uint8 (*)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11ArcIterator_flags;
   __pyx_vtable_9pywrapfst_ArcIterator.next = (void (*)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11ArcIterator_next;
   __pyx_vtable_9pywrapfst_ArcIterator.position = (size_t (*)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11ArcIterator_position;
   __pyx_vtable_9pywrapfst_ArcIterator.reset = (void (*)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11ArcIterator_reset;
   __pyx_vtable_9pywrapfst_ArcIterator.seek = (void (*)(struct __pyx_obj_9pywrapfst_ArcIterator *, size_t, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11ArcIterator_seek;
-  __pyx_vtable_9pywrapfst_ArcIterator.set_flags = (void (*)(struct __pyx_obj_9pywrapfst_ArcIterator *, __pyx_t_10basictypes_uint32, __pyx_t_10basictypes_uint32, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11ArcIterator_set_flags;
+  __pyx_vtable_9pywrapfst_ArcIterator.set_flags = (void (*)(struct __pyx_obj_9pywrapfst_ArcIterator *, __pyx_t_10basictypes_uint8, __pyx_t_10basictypes_uint8, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11ArcIterator_set_flags;
   __pyx_vtable_9pywrapfst_ArcIterator.value = (PyObject *(*)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11ArcIterator_value;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 2999, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 3062, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_ArcIterator.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_ArcIterator.tp_dictoffset && __pyx_type_9pywrapfst_ArcIterator.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_ArcIterator.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_ArcIterator.tp_dict, __pyx_vtabptr_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 2999, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_ArcIterator, (PyObject *)&__pyx_type_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 2999, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 2999, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_ArcIterator.tp_dict, __pyx_vtabptr_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 3062, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_ArcIterator, (PyObject *)&__pyx_type_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 3062, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 3062, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_ArcIterator = &__pyx_type_9pywrapfst_ArcIterator;
   __pyx_vtabptr_9pywrapfst_MutableArcIterator = &__pyx_vtable_9pywrapfst_MutableArcIterator;
   __pyx_vtable_9pywrapfst_MutableArcIterator.done = (bool (*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_done;
-  __pyx_vtable_9pywrapfst_MutableArcIterator.flags = (__pyx_t_10basictypes_uint32 (*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_flags;
+  __pyx_vtable_9pywrapfst_MutableArcIterator.flags = (__pyx_t_10basictypes_uint8 (*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_flags;
   __pyx_vtable_9pywrapfst_MutableArcIterator.next = (void (*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_next;
   __pyx_vtable_9pywrapfst_MutableArcIterator.position = (size_t (*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_position;
   __pyx_vtable_9pywrapfst_MutableArcIterator.reset = (void (*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_reset;
   __pyx_vtable_9pywrapfst_MutableArcIterator.seek = (void (*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, size_t, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_seek;
-  __pyx_vtable_9pywrapfst_MutableArcIterator.set_flags = (void (*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, __pyx_t_10basictypes_uint32, __pyx_t_10basictypes_uint32, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_set_flags;
+  __pyx_vtable_9pywrapfst_MutableArcIterator.set_flags = (void (*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, __pyx_t_10basictypes_uint8, __pyx_t_10basictypes_uint8, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_set_flags;
   __pyx_vtable_9pywrapfst_MutableArcIterator.set_value = (void (*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, struct __pyx_obj_9pywrapfst_Arc *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_set_value;
   __pyx_vtable_9pywrapfst_MutableArcIterator.value = (PyObject *(*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_value;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3110, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3173, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_MutableArcIterator.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_MutableArcIterator.tp_dictoffset && __pyx_type_9pywrapfst_MutableArcIterator.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_MutableArcIterator.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_MutableArcIterator.tp_dict, __pyx_vtabptr_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3110, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_MutableArcIterator, (PyObject *)&__pyx_type_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3110, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3110, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_MutableArcIterator.tp_dict, __pyx_vtabptr_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3173, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_MutableArcIterator, (PyObject *)&__pyx_type_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3173, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3173, __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, 3230, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3293, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_StateIterator.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_StateIterator.tp_dictoffset && __pyx_type_9pywrapfst_StateIterator.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_StateIterator.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_StateIterator.tp_dict, __pyx_vtabptr_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3230, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_StateIterator, (PyObject *)&__pyx_type_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3230, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3230, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_StateIterator.tp_dict, __pyx_vtabptr_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3293, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_StateIterator, (PyObject *)&__pyx_type_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3293, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3293, __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, 4133, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4199, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_Compiler.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_Compiler.tp_dictoffset && __pyx_type_9pywrapfst_Compiler.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_Compiler.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_Compiler.tp_dict, __pyx_vtabptr_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4133, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Compiler, (PyObject *)&__pyx_type_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4133, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4133, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_Compiler.tp_dict, __pyx_vtabptr_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4199, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Compiler, (PyObject *)&__pyx_type_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4199, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4199, __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;
@@ -49980,16 +50934,16 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst_FarReader.get_key = (std::string (*)(struct __pyx_obj_9pywrapfst_FarReader *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_9FarReader_get_key;
   __pyx_vtable_9pywrapfst_FarReader.next = (void (*)(struct __pyx_obj_9pywrapfst_FarReader *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_9FarReader_next;
   __pyx_vtable_9pywrapfst_FarReader.reset = (void (*)(struct __pyx_obj_9pywrapfst_FarReader *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_9FarReader_reset;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4263, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4336, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_FarReader.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_FarReader.tp_dictoffset && __pyx_type_9pywrapfst_FarReader.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_FarReader.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_FarReader.tp_dict, __pyx_vtabptr_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4263, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_FarReader, (PyObject *)&__pyx_type_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4263, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4263, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_FarReader.tp_dict, __pyx_vtabptr_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4336, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_FarReader, (PyObject *)&__pyx_type_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4336, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4336, __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;
@@ -49997,18 +50951,18 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst_FarWriter.add = (void (*)(struct __pyx_obj_9pywrapfst_FarWriter *, PyObject *, struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_9FarWriter_add;
   __pyx_vtable_9pywrapfst_FarWriter.error = (bool (*)(struct __pyx_obj_9pywrapfst_FarWriter *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_9FarWriter_error;
   __pyx_vtable_9pywrapfst_FarWriter.far_type = (std::string (*)(struct __pyx_obj_9pywrapfst_FarWriter *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_9FarWriter_far_type;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4410, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4483, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_FarWriter.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_FarWriter.tp_dictoffset && __pyx_type_9pywrapfst_FarWriter.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_FarWriter.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_FarWriter.tp_dict, __pyx_vtabptr_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4410, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_FarWriter, (PyObject *)&__pyx_type_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4410, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4410, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_FarWriter.tp_dict, __pyx_vtabptr_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4483, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_FarWriter, (PyObject *)&__pyx_type_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4483, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4483, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_FarWriter = &__pyx_type_9pywrapfst_FarWriter;
-  if (PyType_Ready(&__pyx_type_9pywrapfst___pyx_scope_struct____iter__) < 0) __PYX_ERR(0, 3130, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst___pyx_scope_struct____iter__) < 0) __PYX_ERR(0, 3193, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst___pyx_scope_struct____iter__.tp_print = 0;
   #endif
@@ -50602,7 +51556,7 @@ if (!__Pyx_RefNanny) {
   if (PyDict_SetItem(__pyx_d, __pyx_n_s_power, __pyx_t_2) < 0) __PYX_ERR(0, 542, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":902
+  /* "pywrapfst.pyx":900
  *   """
  * 
  *   cpdef int64 add_symbol(self, symbol, int64 key=fst.kNoSymbol):             # <<<<<<<<<<<<<<
@@ -50612,1505 +51566,1558 @@ if (!__Pyx_RefNanny) {
   __pyx_k__3 = fst::kNoSymbol;
   __pyx_k__3 = fst::kNoSymbol;
 
-  /* "pywrapfst.pyx":979
+  /* "pywrapfst.pyx":977
  * 
  *   @classmethod
- *   def read(cls, filename):             # <<<<<<<<<<<<<<
+ *   def read(cls, source):             # <<<<<<<<<<<<<<
  *     """
- *     SymbolTable.read(filename)
+ *     SymbolTable.read(source)
  */
-  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_SymbolTable, __pyx_n_s_read); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 979, __pyx_L1_error)
+  __Pyx_GetNameInClass(__pyx_t_2, (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":978
+  /* "pywrapfst.pyx":976
  *     self._smart_table.reset(self._table)
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
- *   def read(cls, filename):
+ *   def read(cls, source):
  *     """
  */
-  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 978, __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, 979, __pyx_L1_error)
+  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":1002
+  /* "pywrapfst.pyx":998
  * 
  *   @classmethod
- *   def read_text(cls, filename, bool allow_negative_labels=False):             # <<<<<<<<<<<<<<
+ *   def read_text(cls, source, bool allow_negative_labels=False):             # <<<<<<<<<<<<<<
  *     """
- *     SymbolTable.read_text(filename)
+ *     SymbolTable.read_text(source)
  */
-  __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_9pywrapfst_SymbolTable, __pyx_n_s_read_text); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1002, __pyx_L1_error)
+  __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_9pywrapfst_SymbolTable, __pyx_n_s_read_text); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 998, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
 
-  /* "pywrapfst.pyx":1001
+  /* "pywrapfst.pyx":997
  *     return _init_SymbolTable(syms.release())
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
- *   def read_text(cls, filename, bool allow_negative_labels=False):
+ *   def read_text(cls, source, bool allow_negative_labels=False):
  *     """
  */
-  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1001, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 997, __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, 1002, __pyx_L1_error)
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_SymbolTable->tp_dict, __pyx_n_s_read_text, __pyx_t_2) < 0) __PYX_ERR(0, 998, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_SymbolTable);
 
-  /* "pywrapfst.pyx":1029
+  /* "pywrapfst.pyx":1023
  * 
  *   @classmethod
- *   def read_fst(cls, filename, bool input_table):             # <<<<<<<<<<<<<<
+ *   def read_fst(cls, source, bool input_table):             # <<<<<<<<<<<<<<
  *     """
- *     SymbolTable.read_fst(filename, input_table)
+ *     SymbolTable.read_fst(source, input_table)
  */
-  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_SymbolTable, __pyx_n_s_read_fst); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1029, __pyx_L1_error)
+  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_SymbolTable, __pyx_n_s_read_fst); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1023, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":1028
+  /* "pywrapfst.pyx":1022
  *     return _init_SymbolTable(syms.release())
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
- *   def read_fst(cls, filename, bool input_table):
+ *   def read_fst(cls, source, bool input_table):
  *     """
  */
-  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1028, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1022, __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, 1029, __pyx_L1_error)
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_SymbolTable->tp_dict, __pyx_n_s_read_fst, __pyx_t_1) < 0) __PYX_ERR(0, 1023, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_SymbolTable);
 
-  /* "pywrapfst.pyx":2102
+  /* "pywrapfst.pyx":1323
+ * 
+ *   @classmethod
+ *   def read(cls, source):             # <<<<<<<<<<<<<<
+ *     """
+ *     EncodeMapper.read(source)
+ */
+  __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_9pywrapfst_EncodeMapper, __pyx_n_s_read); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1323, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+
+  /* "pywrapfst.pyx":1322
+ *     return self._mapper.get().Properties(mask)
+ * 
+ *   @classmethod             # <<<<<<<<<<<<<<
+ *   def read(cls, source):
+ *     """
+ */
+  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1322, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_EncodeMapper->tp_dict, __pyx_n_s_read, __pyx_t_2) < 0) __PYX_ERR(0, 1323, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  PyType_Modified(__pyx_ptype_9pywrapfst_EncodeMapper);
+
+  /* "pywrapfst.pyx":1345
+ * 
+ *   @staticmethod
+ *   def read_from_string(state):             # <<<<<<<<<<<<<<
+ *     """
+ *     read_from_string(state)
+ */
+  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_12EncodeMapper_19read_from_string, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1345, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_EncodeMapper->tp_dict, __pyx_n_s_read_from_string, __pyx_t_2) < 0) __PYX_ERR(0, 1345, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  PyType_Modified(__pyx_ptype_9pywrapfst_EncodeMapper);
+
+  /* "pywrapfst.pyx":1344
+ *     return _init_EncodeMapper(mapper.release())
+ * 
+ *   @staticmethod             # <<<<<<<<<<<<<<
+ *   def read_from_string(state):
+ *     """
+ */
+  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_EncodeMapper, __pyx_n_s_read_from_string); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1345, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_staticmethod, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1344, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_EncodeMapper->tp_dict, __pyx_n_s_read_from_string, __pyx_t_1) < 0) __PYX_ERR(0, 1345, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  PyType_Modified(__pyx_ptype_9pywrapfst_EncodeMapper);
+
+  /* "pywrapfst.pyx":2176
  *     return self
  * 
  *   cdef void _minimize(self, float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
  *                       bool allow_nondet=False) except *:
  *     # This runs in-place when the second argument is null.
  */
-  __pyx_k__11 = fst::kShortestDelta;
+  __pyx_k__9 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":2108
+  /* "pywrapfst.pyx":2182
  *     self._check_mutating_imethod()
  * 
  *   def minimize(self, float delta=fst.kShortestDelta, bool allow_nondet=False):             # <<<<<<<<<<<<<<
  *     """
  *     minimize(self, delta=1e-6, allow_nondet=False)
  */
-  __pyx_k__12 = fst::kShortestDelta;
+  __pyx_k__10 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":2208
+  /* "pywrapfst.pyx":2278
  *     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__11 = fst::kDelta;
+  __pyx_k__12 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":2217
+  /* "pywrapfst.pyx":2287
  * 
  *   def prune(self,
  *             float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *             int64 nstate=fst.kNoStateId,
  *             weight=None):
  */
-  __pyx_k__15 = fst::kDelta;
+  __pyx_k__13 = fst::kDelta;
 
-  /* "pywrapfst.pyx":2218
+  /* "pywrapfst.pyx":2288
  *   def prune(self,
  *             float delta=fst.kDelta,
  *             int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *             weight=None):
  *     """
  */
-  __pyx_k__16 = fst::kNoStateId;
+  __pyx_k__14 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":2245
+  /* "pywrapfst.pyx":2313
  * 
  *   cdef void _push(self,
- *                   float delta=fst.kDelta,             # <<<<<<<<<<<<<<
+ *                   float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
  *                   bool remove_total_weight=False,
  *                   bool to_final=False) except *:
  */
-  __pyx_k__17 = fst::kDelta;
+  __pyx_k__15 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":2253
+  /* "pywrapfst.pyx":2321
  * 
  *   def push(self,
- *            float delta=fst.kDelta,             # <<<<<<<<<<<<<<
+ *            float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
  *            bool remove_total_weight=False,
  *            bool to_final=False):
  */
-  __pyx_k__18 = fst::kDelta;
+  __pyx_k__16 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":2490
+  /* "pywrapfst.pyx":2560
  *                        bool connect=True,
  *                        weight=None,
  *                        int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                        float delta=fst.kShortestDelta) except *:
  *     cdef fst.WeightClass wc = _get_WeightClass_or_Zero(self.weight_type(),
  */
-  __pyx_k__19 = fst::kNoStateId;
+  __pyx_k__17 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":2491
+  /* "pywrapfst.pyx":2561
  *                        weight=None,
  *                        int64 nstate=fst.kNoStateId,
  *                        float delta=fst.kShortestDelta) except *:             # <<<<<<<<<<<<<<
  *     cdef fst.WeightClass wc = _get_WeightClass_or_Zero(self.weight_type(),
  *                                                        weight)
  */
-  __pyx_k__20 = fst::kShortestDelta;
+  __pyx_k__18 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":2504
+  /* "pywrapfst.pyx":2577
  *                 bool connect=True,
  *                 weight=None,
  *                 int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                 float delta=fst.kShortestDelta):
  *     """
  */
-  __pyx_k__21 = fst::kNoStateId;
+  __pyx_k__19 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":2505
+  /* "pywrapfst.pyx":2578
  *                 weight=None,
  *                 int64 nstate=fst.kNoStateId,
  *                 float delta=fst.kShortestDelta):             # <<<<<<<<<<<<<<
  *     """
  *     rmepsilon(self, queue_type="auto", connect=True, weight=None,
  */
-  __pyx_k__22 = fst::kShortestDelta;
+  __pyx_k__20 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":2778
+  /* "pywrapfst.pyx":2844
  * 
  * 
  * class Fst(object):             # <<<<<<<<<<<<<<
  * 
  *    """
  */
-  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_tuple__68); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2778, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_tuple__68); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2844, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_tuple__68, __pyx_n_s_Fst_2, __pyx_n_s_Fst_2, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, __pyx_kp_s_Fst_arc_type_standard_Construct); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2778, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_tuple__68, __pyx_n_s_Fst_2, __pyx_n_s_Fst_2, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, __pyx_kp_s_Fst_arc_type_standard_Construct); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2844, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":2795
+  /* "pywrapfst.pyx":2861
  *    """
  * 
  *    def __new__(cls, arc_type=b"standard"):             # <<<<<<<<<<<<<<
  *     return _create_Fst(arc_type)
  * 
  */
-  __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_9pywrapfst_3Fst_1__new__, __Pyx_CYFUNCTION_STATICMETHOD, __pyx_n_s_Fst___new, NULL, __pyx_n_s_pywrapfst_2, __pyx_d, ((PyObject *)__pyx_codeobj__70)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2795, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_9pywrapfst_3Fst_1__new__, __Pyx_CYFUNCTION_STATICMETHOD, __pyx_n_s_Fst___new, NULL, __pyx_n_s_pywrapfst_2, __pyx_d, ((PyObject *)__pyx_codeobj__70)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2861, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_3, __pyx_tuple__71);
-  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_new, __pyx_t_3) < 0) __PYX_ERR(0, 2795, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_new, __pyx_t_3) < 0) __PYX_ERR(0, 2861, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-  /* "pywrapfst.pyx":2799
+  /* "pywrapfst.pyx":2865
  * 
  *    @staticmethod
- *    def read(filename):             # <<<<<<<<<<<<<<
+ *    def read(source):             # <<<<<<<<<<<<<<
  *      """
- *      read(filename):
+ *      read(source)
  */
-  __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_9pywrapfst_3Fst_3read, __Pyx_CYFUNCTION_STATICMETHOD, __pyx_n_s_Fst_read, NULL, __pyx_n_s_pywrapfst_2, __pyx_d, ((PyObject *)__pyx_codeobj__73)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2799, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_9pywrapfst_3Fst_3read, __Pyx_CYFUNCTION_STATICMETHOD, __pyx_n_s_Fst_read, NULL, __pyx_n_s_pywrapfst_2, __pyx_d, ((PyObject *)__pyx_codeobj__73)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2865, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
 
-  /* "pywrapfst.pyx":2798
+  /* "pywrapfst.pyx":2864
  *     return _create_Fst(arc_type)
  * 
  *    @staticmethod             # <<<<<<<<<<<<<<
- *    def read(filename):
+ *    def read(source):
  *      """
  */
-  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_staticmethod, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2798, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_staticmethod, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2864, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_read, __pyx_t_4) < 0) __PYX_ERR(0, 2799, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_read, __pyx_t_4) < 0) __PYX_ERR(0, 2865, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":2817
+  /* "pywrapfst.pyx":2883
  * 
  *    @staticmethod
  *    def read_from_string(state):             # <<<<<<<<<<<<<<
  *      """
- *      read_from_string(string, fst_type=None)
+ *      read_from_string(state)
  */
-  __pyx_t_4 = __Pyx_CyFunction_NewEx(&__pyx_mdef_9pywrapfst_3Fst_5read_from_string, __Pyx_CYFUNCTION_STATICMETHOD, __pyx_n_s_Fst_read_from_string, NULL, __pyx_n_s_pywrapfst_2, __pyx_d, ((PyObject *)__pyx_codeobj__75)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2817, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_CyFunction_NewEx(&__pyx_mdef_9pywrapfst_3Fst_5read_from_string, __Pyx_CYFUNCTION_STATICMETHOD, __pyx_n_s_Fst_read_from_string, NULL, __pyx_n_s_pywrapfst_2, __pyx_d, ((PyObject *)__pyx_codeobj__75)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2883, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
 
-  /* "pywrapfst.pyx":2816
- *      return _read(filename)
+  /* "pywrapfst.pyx":2882
+ *      return _read(source)
  * 
  *    @staticmethod             # <<<<<<<<<<<<<<
  *    def read_from_string(state):
  *      """
  */
-  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_staticmethod, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2816, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_staticmethod, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2882, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_read_from_string, __pyx_t_3) < 0) __PYX_ERR(0, 2817, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_read_from_string, __pyx_t_3) < 0) __PYX_ERR(0, 2883, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-  /* "pywrapfst.pyx":2778
+  /* "pywrapfst.pyx":2844
  * 
  * 
  * class Fst(object):             # <<<<<<<<<<<<<<
  * 
  *    """
  */
-  __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_Fst_2, __pyx_tuple__68, __pyx_t_2, NULL, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2778, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_Fst_2, __pyx_tuple__68, __pyx_t_2, NULL, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2844, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Fst_2, __pyx_t_3) < 0) __PYX_ERR(0, 2778, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Fst_2, __pyx_t_3) < 0) __PYX_ERR(0, 2844, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2841
+  /* "pywrapfst.pyx":2904
  * 
  * 
  * NO_LABEL = fst.kNoLabel             # <<<<<<<<<<<<<<
  * NO_STATE_ID = fst.kNoStateId
  * NO_SYMBOL = fst.kNoSymbol
  */
-  __pyx_t_1 = __Pyx_PyInt_From_int(fst::kNoLabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2841, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int(fst::kNoLabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2904, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_LABEL, __pyx_t_1) < 0) __PYX_ERR(0, 2841, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_LABEL, __pyx_t_1) < 0) __PYX_ERR(0, 2904, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2842
+  /* "pywrapfst.pyx":2905
  * 
  * NO_LABEL = fst.kNoLabel
  * NO_STATE_ID = fst.kNoStateId             # <<<<<<<<<<<<<<
  * NO_SYMBOL = fst.kNoSymbol
  * 
  */
-  __pyx_t_1 = __Pyx_PyInt_From_int(fst::kNoStateId); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2842, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int(fst::kNoStateId); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2905, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_STATE_ID, __pyx_t_1) < 0) __PYX_ERR(0, 2842, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_STATE_ID, __pyx_t_1) < 0) __PYX_ERR(0, 2905, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2843
+  /* "pywrapfst.pyx":2906
  * NO_LABEL = fst.kNoLabel
  * NO_STATE_ID = fst.kNoStateId
  * NO_SYMBOL = fst.kNoSymbol             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t(fst::kNoSymbol); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2843, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(fst::kNoSymbol); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2906, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_SYMBOL, __pyx_t_1) < 0) __PYX_ERR(0, 2843, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_SYMBOL, __pyx_t_1) < 0) __PYX_ERR(0, 2906, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2849
+  /* "pywrapfst.pyx":2912
  * 
  * 
  * EXPANDED = fst.kExpanded             # <<<<<<<<<<<<<<
  * MUTABLE = fst.kMutable
  * ERROR = fst.kError
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kExpanded); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2849, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kExpanded); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2912, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_EXPANDED, __pyx_t_1) < 0) __PYX_ERR(0, 2849, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_EXPANDED, __pyx_t_1) < 0) __PYX_ERR(0, 2912, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2850
+  /* "pywrapfst.pyx":2913
  * 
  * EXPANDED = fst.kExpanded
  * MUTABLE = fst.kMutable             # <<<<<<<<<<<<<<
  * ERROR = fst.kError
  * ACCEPTOR = fst.kAcceptor
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kMutable); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2850, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kMutable); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2913, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_MUTABLE, __pyx_t_1) < 0) __PYX_ERR(0, 2850, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_MUTABLE, __pyx_t_1) < 0) __PYX_ERR(0, 2913, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2851
+  /* "pywrapfst.pyx":2914
  * EXPANDED = fst.kExpanded
  * MUTABLE = fst.kMutable
  * ERROR = fst.kError             # <<<<<<<<<<<<<<
  * ACCEPTOR = fst.kAcceptor
  * NOT_ACCEPTOR = fst.kNotAcceptor
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2851, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2914, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ERROR, __pyx_t_1) < 0) __PYX_ERR(0, 2851, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ERROR, __pyx_t_1) < 0) __PYX_ERR(0, 2914, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2852
+  /* "pywrapfst.pyx":2915
  * MUTABLE = fst.kMutable
  * ERROR = fst.kError
  * ACCEPTOR = fst.kAcceptor             # <<<<<<<<<<<<<<
  * NOT_ACCEPTOR = fst.kNotAcceptor
  * I_DETERMINISTIC = fst.kIDeterministic
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAcceptor); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2852, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAcceptor); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2915, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ACCEPTOR, __pyx_t_1) < 0) __PYX_ERR(0, 2852, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ACCEPTOR, __pyx_t_1) < 0) __PYX_ERR(0, 2915, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2853
+  /* "pywrapfst.pyx":2916
  * ERROR = fst.kError
  * ACCEPTOR = fst.kAcceptor
  * NOT_ACCEPTOR = fst.kNotAcceptor             # <<<<<<<<<<<<<<
  * I_DETERMINISTIC = fst.kIDeterministic
  * NON_I_DETERMINISTIC = fst.kNonIDeterministic
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotAcceptor); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2853, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotAcceptor); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2916, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_ACCEPTOR, __pyx_t_1) < 0) __PYX_ERR(0, 2853, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_ACCEPTOR, __pyx_t_1) < 0) __PYX_ERR(0, 2916, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2854
+  /* "pywrapfst.pyx":2917
  * ACCEPTOR = fst.kAcceptor
  * NOT_ACCEPTOR = fst.kNotAcceptor
  * I_DETERMINISTIC = fst.kIDeterministic             # <<<<<<<<<<<<<<
  * NON_I_DETERMINISTIC = fst.kNonIDeterministic
  * O_DETERMINISTIC = fst.kODeterministic
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kIDeterministic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2854, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kIDeterministic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2917, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_I_DETERMINISTIC, __pyx_t_1) < 0) __PYX_ERR(0, 2854, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_I_DETERMINISTIC, __pyx_t_1) < 0) __PYX_ERR(0, 2917, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2855
+  /* "pywrapfst.pyx":2918
  * NOT_ACCEPTOR = fst.kNotAcceptor
  * I_DETERMINISTIC = fst.kIDeterministic
  * NON_I_DETERMINISTIC = fst.kNonIDeterministic             # <<<<<<<<<<<<<<
  * O_DETERMINISTIC = fst.kODeterministic
  * NON_O_DETERMINISTIC = fst.kNonODeterministic
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNonIDeterministic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2855, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNonIDeterministic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2918, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NON_I_DETERMINISTIC, __pyx_t_1) < 0) __PYX_ERR(0, 2855, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NON_I_DETERMINISTIC, __pyx_t_1) < 0) __PYX_ERR(0, 2918, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2856
+  /* "pywrapfst.pyx":2919
  * I_DETERMINISTIC = fst.kIDeterministic
  * NON_I_DETERMINISTIC = fst.kNonIDeterministic
  * O_DETERMINISTIC = fst.kODeterministic             # <<<<<<<<<<<<<<
  * NON_O_DETERMINISTIC = fst.kNonODeterministic
  * EPSILONS = fst.kEpsilons
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kODeterministic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2856, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kODeterministic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2919, __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, 2856, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_O_DETERMINISTIC, __pyx_t_1) < 0) __PYX_ERR(0, 2919, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2857
+  /* "pywrapfst.pyx":2920
  * NON_I_DETERMINISTIC = fst.kNonIDeterministic
  * O_DETERMINISTIC = fst.kODeterministic
  * NON_O_DETERMINISTIC = fst.kNonODeterministic             # <<<<<<<<<<<<<<
  * EPSILONS = fst.kEpsilons
  * NO_EPSILONS = fst.kNoEpsilons
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNonODeterministic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2857, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNonODeterministic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2920, __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, 2857, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NON_O_DETERMINISTIC, __pyx_t_1) < 0) __PYX_ERR(0, 2920, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2858
+  /* "pywrapfst.pyx":2921
  * O_DETERMINISTIC = fst.kODeterministic
  * NON_O_DETERMINISTIC = fst.kNonODeterministic
  * EPSILONS = fst.kEpsilons             # <<<<<<<<<<<<<<
  * NO_EPSILONS = fst.kNoEpsilons
  * I_EPSILONS = fst.kIEpsilons
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2858, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2921, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_EPSILONS, __pyx_t_1) < 0) __PYX_ERR(0, 2858, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_EPSILONS, __pyx_t_1) < 0) __PYX_ERR(0, 2921, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2859
+  /* "pywrapfst.pyx":2922
  * NON_O_DETERMINISTIC = fst.kNonODeterministic
  * EPSILONS = fst.kEpsilons
  * NO_EPSILONS = fst.kNoEpsilons             # <<<<<<<<<<<<<<
  * I_EPSILONS = fst.kIEpsilons
  * NO_I_EPSILONS = fst.kNoIEpsilons
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNoEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2859, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNoEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2922, __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, 2859, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_EPSILONS, __pyx_t_1) < 0) __PYX_ERR(0, 2922, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2860
+  /* "pywrapfst.pyx":2923
  * EPSILONS = fst.kEpsilons
  * NO_EPSILONS = fst.kNoEpsilons
  * I_EPSILONS = fst.kIEpsilons             # <<<<<<<<<<<<<<
  * NO_I_EPSILONS = fst.kNoIEpsilons
  * O_EPSILONS = fst.kOEpsilons
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kIEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2860, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kIEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2923, __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, 2860, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_I_EPSILONS, __pyx_t_1) < 0) __PYX_ERR(0, 2923, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2861
+  /* "pywrapfst.pyx":2924
  * NO_EPSILONS = fst.kNoEpsilons
  * I_EPSILONS = fst.kIEpsilons
  * NO_I_EPSILONS = fst.kNoIEpsilons             # <<<<<<<<<<<<<<
  * O_EPSILONS = fst.kOEpsilons
  * NO_O_EPSILONS = fst.kNoOEpsilons
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNoIEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2861, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNoIEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2924, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_I_EPSILONS, __pyx_t_1) < 0) __PYX_ERR(0, 2861, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_I_EPSILONS, __pyx_t_1) < 0) __PYX_ERR(0, 2924, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2862
+  /* "pywrapfst.pyx":2925
  * I_EPSILONS = fst.kIEpsilons
  * NO_I_EPSILONS = fst.kNoIEpsilons
  * O_EPSILONS = fst.kOEpsilons             # <<<<<<<<<<<<<<
  * NO_O_EPSILONS = fst.kNoOEpsilons
  * I_LABEL_SORTED = fst.kILabelSorted
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kOEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2862, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kOEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2925, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_O_EPSILONS, __pyx_t_1) < 0) __PYX_ERR(0, 2862, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_O_EPSILONS, __pyx_t_1) < 0) __PYX_ERR(0, 2925, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2863
+  /* "pywrapfst.pyx":2926
  * NO_I_EPSILONS = fst.kNoIEpsilons
  * O_EPSILONS = fst.kOEpsilons
  * NO_O_EPSILONS = fst.kNoOEpsilons             # <<<<<<<<<<<<<<
  * I_LABEL_SORTED = fst.kILabelSorted
  * NOT_I_LABEL_SORTED = fst.kNotILabelSorted
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNoOEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2863, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNoOEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2926, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_O_EPSILONS, __pyx_t_1) < 0) __PYX_ERR(0, 2863, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_O_EPSILONS, __pyx_t_1) < 0) __PYX_ERR(0, 2926, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2864
+  /* "pywrapfst.pyx":2927
  * O_EPSILONS = fst.kOEpsilons
  * NO_O_EPSILONS = fst.kNoOEpsilons
  * I_LABEL_SORTED = fst.kILabelSorted             # <<<<<<<<<<<<<<
  * NOT_I_LABEL_SORTED = fst.kNotILabelSorted
  * O_LABEL_SORTED = fst.kOLabelSorted
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kILabelSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2864, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kILabelSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2927, __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, 2864, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_I_LABEL_SORTED, __pyx_t_1) < 0) __PYX_ERR(0, 2927, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2865
+  /* "pywrapfst.pyx":2928
  * NO_O_EPSILONS = fst.kNoOEpsilons
  * I_LABEL_SORTED = fst.kILabelSorted
  * NOT_I_LABEL_SORTED = fst.kNotILabelSorted             # <<<<<<<<<<<<<<
  * O_LABEL_SORTED = fst.kOLabelSorted
  * NOT_O_LABEL_SORTED = fst.kNotOLabelSorted
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotILabelSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2865, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotILabelSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2928, __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, 2865, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_I_LABEL_SORTED, __pyx_t_1) < 0) __PYX_ERR(0, 2928, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2866
+  /* "pywrapfst.pyx":2929
  * I_LABEL_SORTED = fst.kILabelSorted
  * NOT_I_LABEL_SORTED = fst.kNotILabelSorted
  * O_LABEL_SORTED = fst.kOLabelSorted             # <<<<<<<<<<<<<<
  * NOT_O_LABEL_SORTED = fst.kNotOLabelSorted
  * WEIGHTED = fst.kWeighted
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kOLabelSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2866, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kOLabelSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2929, __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, 2866, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_O_LABEL_SORTED, __pyx_t_1) < 0) __PYX_ERR(0, 2929, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2867
+  /* "pywrapfst.pyx":2930
  * NOT_I_LABEL_SORTED = fst.kNotILabelSorted
  * O_LABEL_SORTED = fst.kOLabelSorted
  * NOT_O_LABEL_SORTED = fst.kNotOLabelSorted             # <<<<<<<<<<<<<<
  * WEIGHTED = fst.kWeighted
  * UNWEIGHTED = fst.kUnweighted
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotOLabelSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2867, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotOLabelSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2930, __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, 2867, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_O_LABEL_SORTED, __pyx_t_1) < 0) __PYX_ERR(0, 2930, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2868
+  /* "pywrapfst.pyx":2931
  * O_LABEL_SORTED = fst.kOLabelSorted
  * NOT_O_LABEL_SORTED = fst.kNotOLabelSorted
  * WEIGHTED = fst.kWeighted             # <<<<<<<<<<<<<<
  * UNWEIGHTED = fst.kUnweighted
  * CYCLIC = fst.kCyclic
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kWeighted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2868, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kWeighted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2931, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_WEIGHTED, __pyx_t_1) < 0) __PYX_ERR(0, 2868, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_WEIGHTED, __pyx_t_1) < 0) __PYX_ERR(0, 2931, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2869
+  /* "pywrapfst.pyx":2932
  * NOT_O_LABEL_SORTED = fst.kNotOLabelSorted
  * WEIGHTED = fst.kWeighted
  * UNWEIGHTED = fst.kUnweighted             # <<<<<<<<<<<<<<
  * CYCLIC = fst.kCyclic
  * ACYCLIC = fst.kAcyclic
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kUnweighted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2869, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kUnweighted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2932, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_UNWEIGHTED, __pyx_t_1) < 0) __PYX_ERR(0, 2869, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_UNWEIGHTED, __pyx_t_1) < 0) __PYX_ERR(0, 2932, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2870
+  /* "pywrapfst.pyx":2933
  * WEIGHTED = fst.kWeighted
  * UNWEIGHTED = fst.kUnweighted
  * CYCLIC = fst.kCyclic             # <<<<<<<<<<<<<<
  * ACYCLIC = fst.kAcyclic
  * INITIAL_CYCLIC = fst.kInitialCyclic
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kCyclic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2870, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kCyclic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2933, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_CYCLIC, __pyx_t_1) < 0) __PYX_ERR(0, 2870, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_CYCLIC, __pyx_t_1) < 0) __PYX_ERR(0, 2933, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2871
+  /* "pywrapfst.pyx":2934
  * UNWEIGHTED = fst.kUnweighted
  * CYCLIC = fst.kCyclic
  * ACYCLIC = fst.kAcyclic             # <<<<<<<<<<<<<<
  * INITIAL_CYCLIC = fst.kInitialCyclic
  * INITIAL_ACYCLIC = fst.kInitialAcyclic
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAcyclic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2871, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAcyclic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2934, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ACYCLIC, __pyx_t_1) < 0) __PYX_ERR(0, 2871, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ACYCLIC, __pyx_t_1) < 0) __PYX_ERR(0, 2934, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2872
+  /* "pywrapfst.pyx":2935
  * CYCLIC = fst.kCyclic
  * ACYCLIC = fst.kAcyclic
  * INITIAL_CYCLIC = fst.kInitialCyclic             # <<<<<<<<<<<<<<
  * INITIAL_ACYCLIC = fst.kInitialAcyclic
  * TOP_SORTED = fst.kTopSorted
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kInitialCyclic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2872, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kInitialCyclic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2935, __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, 2872, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_INITIAL_CYCLIC, __pyx_t_1) < 0) __PYX_ERR(0, 2935, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2873
+  /* "pywrapfst.pyx":2936
  * ACYCLIC = fst.kAcyclic
  * INITIAL_CYCLIC = fst.kInitialCyclic
  * INITIAL_ACYCLIC = fst.kInitialAcyclic             # <<<<<<<<<<<<<<
  * TOP_SORTED = fst.kTopSorted
  * NOT_TOP_SORTED = fst.kNotTopSorted
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kInitialAcyclic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2873, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kInitialAcyclic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2936, __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, 2873, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_INITIAL_ACYCLIC, __pyx_t_1) < 0) __PYX_ERR(0, 2936, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2874
+  /* "pywrapfst.pyx":2937
  * INITIAL_CYCLIC = fst.kInitialCyclic
  * INITIAL_ACYCLIC = fst.kInitialAcyclic
  * TOP_SORTED = fst.kTopSorted             # <<<<<<<<<<<<<<
  * NOT_TOP_SORTED = fst.kNotTopSorted
  * ACCESSIBLE = fst.kAccessible
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kTopSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2874, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kTopSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2937, __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, 2874, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_TOP_SORTED, __pyx_t_1) < 0) __PYX_ERR(0, 2937, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2875
+  /* "pywrapfst.pyx":2938
  * INITIAL_ACYCLIC = fst.kInitialAcyclic
  * TOP_SORTED = fst.kTopSorted
  * NOT_TOP_SORTED = fst.kNotTopSorted             # <<<<<<<<<<<<<<
  * ACCESSIBLE = fst.kAccessible
  * NOT_ACCESSIBLE = fst.kNotAccessible
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotTopSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2875, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotTopSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2938, __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, 2875, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_TOP_SORTED, __pyx_t_1) < 0) __PYX_ERR(0, 2938, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2876
+  /* "pywrapfst.pyx":2939
  * TOP_SORTED = fst.kTopSorted
  * NOT_TOP_SORTED = fst.kNotTopSorted
  * ACCESSIBLE = fst.kAccessible             # <<<<<<<<<<<<<<
  * NOT_ACCESSIBLE = fst.kNotAccessible
  * COACCESSIBLE = fst.kCoAccessible
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAccessible); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2876, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAccessible); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2939, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ACCESSIBLE, __pyx_t_1) < 0) __PYX_ERR(0, 2876, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ACCESSIBLE, __pyx_t_1) < 0) __PYX_ERR(0, 2939, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2877
+  /* "pywrapfst.pyx":2940
  * NOT_TOP_SORTED = fst.kNotTopSorted
  * ACCESSIBLE = fst.kAccessible
  * NOT_ACCESSIBLE = fst.kNotAccessible             # <<<<<<<<<<<<<<
  * COACCESSIBLE = fst.kCoAccessible
  * NOT_COACCESSIBLE = fst.kNotCoAccessible
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotAccessible); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2877, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotAccessible); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2940, __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, 2877, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_ACCESSIBLE, __pyx_t_1) < 0) __PYX_ERR(0, 2940, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2878
+  /* "pywrapfst.pyx":2941
  * ACCESSIBLE = fst.kAccessible
  * NOT_ACCESSIBLE = fst.kNotAccessible
  * COACCESSIBLE = fst.kCoAccessible             # <<<<<<<<<<<<<<
  * NOT_COACCESSIBLE = fst.kNotCoAccessible
  * STRING = fst.kString
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kCoAccessible); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2878, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kCoAccessible); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2941, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_COACCESSIBLE, __pyx_t_1) < 0) __PYX_ERR(0, 2878, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_COACCESSIBLE, __pyx_t_1) < 0) __PYX_ERR(0, 2941, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2879
+  /* "pywrapfst.pyx":2942
  * NOT_ACCESSIBLE = fst.kNotAccessible
  * COACCESSIBLE = fst.kCoAccessible
  * NOT_COACCESSIBLE = fst.kNotCoAccessible             # <<<<<<<<<<<<<<
  * STRING = fst.kString
  * NOT_STRING = fst.kNotString
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotCoAccessible); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2879, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotCoAccessible); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2942, __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, 2879, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_COACCESSIBLE, __pyx_t_1) < 0) __PYX_ERR(0, 2942, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2880
+  /* "pywrapfst.pyx":2943
  * COACCESSIBLE = fst.kCoAccessible
  * NOT_COACCESSIBLE = fst.kNotCoAccessible
  * STRING = fst.kString             # <<<<<<<<<<<<<<
  * NOT_STRING = fst.kNotString
  * WEIGHTED_CYCLES = fst.kWeightedCycles
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kString); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2880, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kString); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2943, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_STRING, __pyx_t_1) < 0) __PYX_ERR(0, 2880, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_STRING, __pyx_t_1) < 0) __PYX_ERR(0, 2943, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2881
+  /* "pywrapfst.pyx":2944
  * NOT_COACCESSIBLE = fst.kNotCoAccessible
  * STRING = fst.kString
  * NOT_STRING = fst.kNotString             # <<<<<<<<<<<<<<
  * WEIGHTED_CYCLES = fst.kWeightedCycles
  * UNWEIGHTED_CYCLES = fst.kUnweightedCycles
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotString); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2881, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotString); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2944, __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, 2881, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_STRING, __pyx_t_1) < 0) __PYX_ERR(0, 2944, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2882
+  /* "pywrapfst.pyx":2945
  * STRING = fst.kString
  * NOT_STRING = fst.kNotString
  * WEIGHTED_CYCLES = fst.kWeightedCycles             # <<<<<<<<<<<<<<
  * UNWEIGHTED_CYCLES = fst.kUnweightedCycles
  * NULL_PROPERTIES = fst.kNullProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kWeightedCycles); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2882, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kWeightedCycles); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2945, __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, 2882, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_WEIGHTED_CYCLES, __pyx_t_1) < 0) __PYX_ERR(0, 2945, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2883
+  /* "pywrapfst.pyx":2946
  * NOT_STRING = fst.kNotString
  * WEIGHTED_CYCLES = fst.kWeightedCycles
  * UNWEIGHTED_CYCLES = fst.kUnweightedCycles             # <<<<<<<<<<<<<<
  * NULL_PROPERTIES = fst.kNullProperties
  * COPY_PROPERTIES = fst.kCopyProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kUnweightedCycles); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2883, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kUnweightedCycles); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2946, __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, 2883, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_UNWEIGHTED_CYCLES, __pyx_t_1) < 0) __PYX_ERR(0, 2946, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2884
+  /* "pywrapfst.pyx":2947
  * WEIGHTED_CYCLES = fst.kWeightedCycles
  * UNWEIGHTED_CYCLES = fst.kUnweightedCycles
  * NULL_PROPERTIES = fst.kNullProperties             # <<<<<<<<<<<<<<
  * COPY_PROPERTIES = fst.kCopyProperties
  * INTRINSIC_PROPERTIES = fst.kIntrinsicProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNullProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2884, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNullProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2947, __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, 2884, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NULL_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2947, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2885
+  /* "pywrapfst.pyx":2948
  * UNWEIGHTED_CYCLES = fst.kUnweightedCycles
  * NULL_PROPERTIES = fst.kNullProperties
  * COPY_PROPERTIES = fst.kCopyProperties             # <<<<<<<<<<<<<<
  * INTRINSIC_PROPERTIES = fst.kIntrinsicProperties
  * EXTRINSIC_PROPERTIES = fst.kExtrinsicProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kCopyProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2885, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kCopyProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2948, __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, 2885, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_COPY_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2948, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2886
+  /* "pywrapfst.pyx":2949
  * NULL_PROPERTIES = fst.kNullProperties
  * COPY_PROPERTIES = fst.kCopyProperties
  * INTRINSIC_PROPERTIES = fst.kIntrinsicProperties             # <<<<<<<<<<<<<<
  * EXTRINSIC_PROPERTIES = fst.kExtrinsicProperties
  * SET_START_PROPERTIES = fst.kSetStartProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kIntrinsicProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2886, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kIntrinsicProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2949, __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, 2886, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_INTRINSIC_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2949, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2887
+  /* "pywrapfst.pyx":2950
  * COPY_PROPERTIES = fst.kCopyProperties
  * INTRINSIC_PROPERTIES = fst.kIntrinsicProperties
  * EXTRINSIC_PROPERTIES = fst.kExtrinsicProperties             # <<<<<<<<<<<<<<
  * SET_START_PROPERTIES = fst.kSetStartProperties
  * SET_FINAL_PROPERTIES = fst.kSetFinalProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kExtrinsicProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2887, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kExtrinsicProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2950, __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, 2887, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_EXTRINSIC_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2950, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2888
+  /* "pywrapfst.pyx":2951
  * INTRINSIC_PROPERTIES = fst.kIntrinsicProperties
  * EXTRINSIC_PROPERTIES = fst.kExtrinsicProperties
  * SET_START_PROPERTIES = fst.kSetStartProperties             # <<<<<<<<<<<<<<
  * SET_FINAL_PROPERTIES = fst.kSetFinalProperties
  * ADD_STATE_PROPERTIES = fst.kAddStateProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kSetStartProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2888, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kSetStartProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2951, __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, 2888, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_SET_START_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2951, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2889
+  /* "pywrapfst.pyx":2952
  * EXTRINSIC_PROPERTIES = fst.kExtrinsicProperties
  * SET_START_PROPERTIES = fst.kSetStartProperties
  * SET_FINAL_PROPERTIES = fst.kSetFinalProperties             # <<<<<<<<<<<<<<
  * ADD_STATE_PROPERTIES = fst.kAddStateProperties
  * ADD_ARC_PROPERTIES = fst.kAddArcProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kSetFinalProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2889, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kSetFinalProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2952, __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, 2889, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_SET_FINAL_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2952, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2890
+  /* "pywrapfst.pyx":2953
  * SET_START_PROPERTIES = fst.kSetStartProperties
  * SET_FINAL_PROPERTIES = fst.kSetFinalProperties
  * ADD_STATE_PROPERTIES = fst.kAddStateProperties             # <<<<<<<<<<<<<<
  * ADD_ARC_PROPERTIES = fst.kAddArcProperties
  * SET_ARC_PROPERTIES = fst.kSetArcProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAddStateProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2890, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAddStateProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2953, __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, 2890, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ADD_STATE_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2953, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2891
+  /* "pywrapfst.pyx":2954
  * SET_FINAL_PROPERTIES = fst.kSetFinalProperties
  * ADD_STATE_PROPERTIES = fst.kAddStateProperties
  * ADD_ARC_PROPERTIES = fst.kAddArcProperties             # <<<<<<<<<<<<<<
  * SET_ARC_PROPERTIES = fst.kSetArcProperties
  * DELETE_STATE_PROPERTIES = fst.kDeleteStatesProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAddArcProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2891, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAddArcProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2954, __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, 2891, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ADD_ARC_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2954, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2892
+  /* "pywrapfst.pyx":2955
  * ADD_STATE_PROPERTIES = fst.kAddStateProperties
  * ADD_ARC_PROPERTIES = fst.kAddArcProperties
  * SET_ARC_PROPERTIES = fst.kSetArcProperties             # <<<<<<<<<<<<<<
  * DELETE_STATE_PROPERTIES = fst.kDeleteStatesProperties
  * DELETE_ARC_PROPERTIES = fst.kDeleteArcsProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kSetArcProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2892, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kSetArcProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2955, __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, 2892, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_SET_ARC_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2955, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2893
+  /* "pywrapfst.pyx":2956
  * ADD_ARC_PROPERTIES = fst.kAddArcProperties
  * SET_ARC_PROPERTIES = fst.kSetArcProperties
  * DELETE_STATE_PROPERTIES = fst.kDeleteStatesProperties             # <<<<<<<<<<<<<<
  * DELETE_ARC_PROPERTIES = fst.kDeleteArcsProperties
  * STATE_SORT_PROPERTIES = fst.kStateSortProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kDeleteStatesProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2893, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kDeleteStatesProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2956, __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, 2893, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_DELETE_STATE_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2956, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2894
+  /* "pywrapfst.pyx":2957
  * SET_ARC_PROPERTIES = fst.kSetArcProperties
  * DELETE_STATE_PROPERTIES = fst.kDeleteStatesProperties
  * DELETE_ARC_PROPERTIES = fst.kDeleteArcsProperties             # <<<<<<<<<<<<<<
  * STATE_SORT_PROPERTIES = fst.kStateSortProperties
  * ARC_SORT_PROPERTIES = fst.kArcSortProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kDeleteArcsProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2894, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kDeleteArcsProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2957, __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, 2894, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_DELETE_ARC_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2957, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2895
+  /* "pywrapfst.pyx":2958
  * DELETE_STATE_PROPERTIES = fst.kDeleteStatesProperties
  * DELETE_ARC_PROPERTIES = fst.kDeleteArcsProperties
  * STATE_SORT_PROPERTIES = fst.kStateSortProperties             # <<<<<<<<<<<<<<
  * ARC_SORT_PROPERTIES = fst.kArcSortProperties
  * I_LABEL_INVARIANT_PROPERTIES = fst.kILabelInvariantProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kStateSortProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2895, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kStateSortProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2958, __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, 2895, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_STATE_SORT_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2958, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2896
+  /* "pywrapfst.pyx":2959
  * DELETE_ARC_PROPERTIES = fst.kDeleteArcsProperties
  * STATE_SORT_PROPERTIES = fst.kStateSortProperties
  * ARC_SORT_PROPERTIES = fst.kArcSortProperties             # <<<<<<<<<<<<<<
  * I_LABEL_INVARIANT_PROPERTIES = fst.kILabelInvariantProperties
  * O_LABEL_INVARIANT_PROPERTIES = fst.kOLabelInvariantProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kArcSortProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2896, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kArcSortProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2959, __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, 2896, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_SORT_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2959, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2897
+  /* "pywrapfst.pyx":2960
  * STATE_SORT_PROPERTIES = fst.kStateSortProperties
  * ARC_SORT_PROPERTIES = fst.kArcSortProperties
  * I_LABEL_INVARIANT_PROPERTIES = fst.kILabelInvariantProperties             # <<<<<<<<<<<<<<
  * O_LABEL_INVARIANT_PROPERTIES = fst.kOLabelInvariantProperties
  * WEIGHT_INVARIANT_PROPERTIES = fst.kWeightInvariantProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kILabelInvariantProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2897, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kILabelInvariantProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2960, __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, 2897, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_I_LABEL_INVARIANT_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2960, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2898
+  /* "pywrapfst.pyx":2961
  * ARC_SORT_PROPERTIES = fst.kArcSortProperties
  * I_LABEL_INVARIANT_PROPERTIES = fst.kILabelInvariantProperties
  * O_LABEL_INVARIANT_PROPERTIES = fst.kOLabelInvariantProperties             # <<<<<<<<<<<<<<
  * WEIGHT_INVARIANT_PROPERTIES = fst.kWeightInvariantProperties
  * ADD_SUPERFINAL_PROPERTIES = fst.kAddSuperFinalProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kOLabelInvariantProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2898, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kOLabelInvariantProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2961, __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, 2898, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_O_LABEL_INVARIANT_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2961, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2899
+  /* "pywrapfst.pyx":2962
  * I_LABEL_INVARIANT_PROPERTIES = fst.kILabelInvariantProperties
  * O_LABEL_INVARIANT_PROPERTIES = fst.kOLabelInvariantProperties
  * WEIGHT_INVARIANT_PROPERTIES = fst.kWeightInvariantProperties             # <<<<<<<<<<<<<<
  * ADD_SUPERFINAL_PROPERTIES = fst.kAddSuperFinalProperties
  * RM_SUPERFINAL_PROPERTIES = fst.kRmSuperFinalProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kWeightInvariantProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2899, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kWeightInvariantProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2962, __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, 2899, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_WEIGHT_INVARIANT_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2962, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2900
+  /* "pywrapfst.pyx":2963
  * O_LABEL_INVARIANT_PROPERTIES = fst.kOLabelInvariantProperties
  * WEIGHT_INVARIANT_PROPERTIES = fst.kWeightInvariantProperties
  * ADD_SUPERFINAL_PROPERTIES = fst.kAddSuperFinalProperties             # <<<<<<<<<<<<<<
  * RM_SUPERFINAL_PROPERTIES = fst.kRmSuperFinalProperties
  * BINARY_PROPERTIES = fst.kBinaryProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAddSuperFinalProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2900, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAddSuperFinalProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2963, __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, 2900, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ADD_SUPERFINAL_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2963, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2901
+  /* "pywrapfst.pyx":2964
  * WEIGHT_INVARIANT_PROPERTIES = fst.kWeightInvariantProperties
  * ADD_SUPERFINAL_PROPERTIES = fst.kAddSuperFinalProperties
  * RM_SUPERFINAL_PROPERTIES = fst.kRmSuperFinalProperties             # <<<<<<<<<<<<<<
  * BINARY_PROPERTIES = fst.kBinaryProperties
  * TRINARY_PROPERTIES = fst.kTrinaryProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kRmSuperFinalProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2901, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kRmSuperFinalProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2964, __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, 2901, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_RM_SUPERFINAL_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2964, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2902
+  /* "pywrapfst.pyx":2965
  * ADD_SUPERFINAL_PROPERTIES = fst.kAddSuperFinalProperties
  * RM_SUPERFINAL_PROPERTIES = fst.kRmSuperFinalProperties
  * BINARY_PROPERTIES = fst.kBinaryProperties             # <<<<<<<<<<<<<<
  * TRINARY_PROPERTIES = fst.kTrinaryProperties
  * POS_TRINARY_PROPERTIES = fst.kPosTrinaryProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kBinaryProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2902, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kBinaryProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2965, __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, 2902, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_BINARY_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2965, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2903
+  /* "pywrapfst.pyx":2966
  * RM_SUPERFINAL_PROPERTIES = fst.kRmSuperFinalProperties
  * BINARY_PROPERTIES = fst.kBinaryProperties
  * TRINARY_PROPERTIES = fst.kTrinaryProperties             # <<<<<<<<<<<<<<
  * POS_TRINARY_PROPERTIES = fst.kPosTrinaryProperties
  * NEG_TRINARY_PROPERTIES = fst.kNegTrinaryProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kTrinaryProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2903, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kTrinaryProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2966, __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, 2903, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_TRINARY_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2966, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2904
+  /* "pywrapfst.pyx":2967
  * BINARY_PROPERTIES = fst.kBinaryProperties
  * TRINARY_PROPERTIES = fst.kTrinaryProperties
  * POS_TRINARY_PROPERTIES = fst.kPosTrinaryProperties             # <<<<<<<<<<<<<<
  * NEG_TRINARY_PROPERTIES = fst.kNegTrinaryProperties
  * FST_PROPERTIES = fst.kFstProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kPosTrinaryProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2904, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kPosTrinaryProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2967, __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, 2904, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_POS_TRINARY_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2967, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2905
+  /* "pywrapfst.pyx":2968
  * TRINARY_PROPERTIES = fst.kTrinaryProperties
  * POS_TRINARY_PROPERTIES = fst.kPosTrinaryProperties
  * NEG_TRINARY_PROPERTIES = fst.kNegTrinaryProperties             # <<<<<<<<<<<<<<
  * FST_PROPERTIES = fst.kFstProperties
  * 
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNegTrinaryProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2905, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNegTrinaryProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2968, __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, 2905, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NEG_TRINARY_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2968, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2906
+  /* "pywrapfst.pyx":2969
  * POS_TRINARY_PROPERTIES = fst.kPosTrinaryProperties
  * NEG_TRINARY_PROPERTIES = fst.kNegTrinaryProperties
  * FST_PROPERTIES = fst.kFstProperties             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kFstProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2906, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kFstProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2969, __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, 2906, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FST_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2969, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2912
+  /* "pywrapfst.pyx":2975
  * 
  * 
  * 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, 2912, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(fst::kArcILabelValue); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2975, __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, 2912, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_I_LABEL_VALUE, __pyx_t_1) < 0) __PYX_ERR(0, 2975, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2913
+  /* "pywrapfst.pyx":2976
  * 
  * 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, 2913, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(fst::kArcOLabelValue); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2976, __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, 2913, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_O_LABEL_VALUE, __pyx_t_1) < 0) __PYX_ERR(0, 2976, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2914
+  /* "pywrapfst.pyx":2977
  * 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, 2914, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(fst::kArcWeightValue); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2977, __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, 2914, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_WEIGHT_VALUE, __pyx_t_1) < 0) __PYX_ERR(0, 2977, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2915
+  /* "pywrapfst.pyx":2978
  * 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, 2915, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(fst::kArcNextStateValue); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2978, __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, 2915, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_NEXT_STATE_VALUE, __pyx_t_1) < 0) __PYX_ERR(0, 2978, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2916
+  /* "pywrapfst.pyx":2979
  * 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, 2916, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(fst::kArcNoCache); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2979, __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, 2916, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_NO_CACHE, __pyx_t_1) < 0) __PYX_ERR(0, 2979, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2917
+  /* "pywrapfst.pyx":2980
  * 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, 2917, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(fst::kArcValueFlags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2980, __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, 2917, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_VALUE_FLAGS, __pyx_t_1) < 0) __PYX_ERR(0, 2980, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2918
+  /* "pywrapfst.pyx":2981
  * 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, 2918, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(fst::kArcFlags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2981, __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, 2918, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_FLAGS, __pyx_t_1) < 0) __PYX_ERR(0, 2981, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2924
+  /* "pywrapfst.pyx":2987
  * 
  * 
  * 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, 2924, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(fst::kEncodeLabels); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2987, __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, 2924, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ENCODE_LABELS, __pyx_t_1) < 0) __PYX_ERR(0, 2987, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2925
+  /* "pywrapfst.pyx":2988
  * 
  * 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, 2925, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(fst::kEncodeWeights); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2988, __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, 2925, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ENCODE_WEIGHTS, __pyx_t_1) < 0) __PYX_ERR(0, 2988, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2926
+  /* "pywrapfst.pyx":2989
  * 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, 2926, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(fst::kEncodeFlags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2989, __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, 2926, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ENCODE_FLAGS, __pyx_t_1) < 0) __PYX_ERR(0, 2989, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":3298
+  /* "pywrapfst.pyx":3361
  * 
  * cdef _Fst _map(_Fst ifst,
  *                float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                map_type=b"identity",
  *                double power=1.,
  */
-  __pyx_k__31 = fst::kDelta;
+  __pyx_k__29 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3312
+  /* "pywrapfst.pyx":3377
  * 
  * cpdef _Fst arcmap(_Fst ifst,
  *                   float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                   map_type=b"identity",
  *                   double power=1.,
  */
-  __pyx_k__32 = fst::kDelta;
+  __pyx_k__30 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3311
+  /* "pywrapfst.pyx":3376
  * 
  * 
  * cpdef _Fst arcmap(_Fst ifst,             # <<<<<<<<<<<<<<
  *                   float delta=fst.kDelta,
  *                   map_type=b"identity",
  */
-  __pyx_k__32 = fst::kDelta;
+  __pyx_k__30 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3425
+  /* "pywrapfst.pyx":3487
  * 
  * cpdef _MutableFst determinize(_Fst ifst,
  *                               float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
  *                               det_type=b"functional",
  *                               int64 nstate=fst.kNoStateId,
  */
-  __pyx_k__33 = fst::kShortestDelta;
+  __pyx_k__31 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":3427
+  /* "pywrapfst.pyx":3489
  *                               float delta=fst.kShortestDelta,
  *                               det_type=b"functional",
  *                               int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                               int64 subsequential_label=0,
  *                               weight=None,
  */
-  __pyx_k__34 = fst::kNoStateId;
+  __pyx_k__32 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3425
+  /* "pywrapfst.pyx":3487
  * 
  * cpdef _MutableFst determinize(_Fst ifst,
  *                               float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
  *                               det_type=b"functional",
  *                               int64 nstate=fst.kNoStateId,
  */
-  __pyx_k__33 = fst::kShortestDelta;
+  __pyx_k__31 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":3427
+  /* "pywrapfst.pyx":3489
  *                               float delta=fst.kShortestDelta,
  *                               det_type=b"functional",
  *                               int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                               int64 subsequential_label=0,
  *                               weight=None,
  */
-  __pyx_k__34 = fst::kNoStateId;
+  __pyx_k__32 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3519
+  /* "pywrapfst.pyx":3583
  * 
  * cpdef _MutableFst disambiguate(_Fst ifst,
  *                                float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                                int64 nstate=fst.kNoStateId,
  *                                int64 subsequential_label=0,
  */
-  __pyx_k__35 = fst::kDelta;
+  __pyx_k__33 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3520
+  /* "pywrapfst.pyx":3584
  * cpdef _MutableFst disambiguate(_Fst ifst,
  *                                float delta=fst.kDelta,
  *                                int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                                int64 subsequential_label=0,
  *                                weight=None):
  */
-  __pyx_k__36 = fst::kNoStateId;
+  __pyx_k__34 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3519
+  /* "pywrapfst.pyx":3583
  * 
  * cpdef _MutableFst disambiguate(_Fst ifst,
  *                                float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                                int64 nstate=fst.kNoStateId,
  *                                int64 subsequential_label=0,
  */
-  __pyx_k__35 = fst::kDelta;
+  __pyx_k__33 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3520
+  /* "pywrapfst.pyx":3584
  * cpdef _MutableFst disambiguate(_Fst ifst,
  *                                float delta=fst.kDelta,
  *                                int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                                int64 subsequential_label=0,
  *                                weight=None):
  */
-  __pyx_k__36 = fst::kNoStateId;
+  __pyx_k__34 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3590
+  /* "pywrapfst.pyx":3653
  * 
  * 
  * cpdef bool equal(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
  *   """
  *   equal(ifst1, ifst2, delta=0.0009765625)
  */
-  __pyx_k__37 = fst::kDelta;
-  __pyx_k__37 = fst::kDelta;
+  __pyx_k__35 = fst::kDelta;
+  __pyx_k__35 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3613
+  /* "pywrapfst.pyx":3674
  * 
  * 
  * cpdef bool equivalent(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta) except *:             # <<<<<<<<<<<<<<
  *   """
  *   equivalent(ifst1, ifst2, delta=0.0009765625)
  */
-  __pyx_k__38 = fst::kDelta;
-  __pyx_k__38 = fst::kDelta;
+  __pyx_k__36 = fst::kDelta;
+  __pyx_k__36 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3670
+  /* "pywrapfst.pyx":3730
  * 
  * 
  * cpdef bool isomorphic(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
  *   """
  *   isomorphic(ifst1, ifst2, delta=0.0009765625)
  */
-  __pyx_k__39 = fst::kDelta;
-  __pyx_k__39 = fst::kDelta;
+  __pyx_k__37 = fst::kDelta;
+  __pyx_k__37 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3697
+  /* "pywrapfst.pyx":3755
  * 
  * cpdef _MutableFst prune(_Fst ifst,
  *                         float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                         int64 nstate=fst.kNoStateId,
  *                         weight=None):
  */
-  __pyx_k__40 = fst::kDelta;
+  __pyx_k__38 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3698
+  /* "pywrapfst.pyx":3756
  * cpdef _MutableFst prune(_Fst ifst,
  *                         float delta=fst.kDelta,
  *                         int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                         weight=None):
  *   """
  */
-  __pyx_k__41 = fst::kNoStateId;
+  __pyx_k__39 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3697
+  /* "pywrapfst.pyx":3755
  * 
  * cpdef _MutableFst prune(_Fst ifst,
  *                         float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                         int64 nstate=fst.kNoStateId,
  *                         weight=None):
  */
-  __pyx_k__40 = fst::kDelta;
+  __pyx_k__38 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3698
+  /* "pywrapfst.pyx":3756
  * cpdef _MutableFst prune(_Fst ifst,
  *                         float delta=fst.kDelta,
  *                         int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                         weight=None):
  *   """
  */
-  __pyx_k__41 = fst::kNoStateId;
+  __pyx_k__39 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3730
+  /* "pywrapfst.pyx":3786
  * 
  * cpdef _MutableFst push(_Fst ifst,
  *                        float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                        bool push_weights=False,
  *                        bool push_labels=False,
  */
-  __pyx_k__42 = fst::kDelta;
+  __pyx_k__40 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3729
+  /* "pywrapfst.pyx":3785
  * 
  * 
  * cpdef _MutableFst push(_Fst ifst,             # <<<<<<<<<<<<<<
  *                        float delta=fst.kDelta,
  *                        bool push_weights=False,
  */
-  __pyx_k__42 = fst::kDelta;
+  __pyx_k__40 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3786
+  /* "pywrapfst.pyx":3845
  *                           _Fst ifst2,
  *                           int32 npath=1,
  *                           float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                           time_t seed=0,
  *                           select=b"uniform",
  */
-  __pyx_k__43 = fst::kDelta;
+  __pyx_k__41 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3789
+  /* "pywrapfst.pyx":3848
  *                           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__44 = INT32_MAX;
+  __pyx_k__42 = INT32_MAX;
 
-  /* "pywrapfst.pyx":3786
+  /* "pywrapfst.pyx":3845
  *                           _Fst ifst2,
  *                           int32 npath=1,
  *                           float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                           time_t seed=0,
  *                           select=b"uniform",
  */
-  __pyx_k__43 = fst::kDelta;
+  __pyx_k__41 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3789
+  /* "pywrapfst.pyx":3848
  *                           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__44 = INT32_MAX;
+  __pyx_k__42 = INT32_MAX;
 
-  /* "pywrapfst.pyx":3833
+  /* "pywrapfst.pyx":3897
  *                           time_t seed=0,
  *                           select=b"uniform",
  *                           int32 max_length=INT32_MAX,             # <<<<<<<<<<<<<<
  *                           bool weighted=False,
  *                           bool remove_total_weight=False):
  */
-  __pyx_k__45 = INT32_MAX;
+  __pyx_k__43 = INT32_MAX;
 
-  /* "pywrapfst.pyx":3829
+  /* "pywrapfst.pyx":3893
  * 
  * 
  * cpdef _MutableFst randgen(_Fst ifst,             # <<<<<<<<<<<<<<
  *                           int32 npath=1,
  *                           time_t seed=0,
  */
-  __pyx_k__45 = INT32_MAX;
+  __pyx_k__43 = INT32_MAX;
 
-  /* "pywrapfst.pyx":3971
+  /* "pywrapfst.pyx":4033
  * 
  * cdef vector[fst.WeightClass] *_shortestdistance(_Fst ifst,
  *                                                 float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
  *                                                 int64 nstate=fst.kNoStateId,
  *                                                 queue_type=b"auto",
  */
-  __pyx_k__46 = fst::kShortestDelta;
+  __pyx_k__44 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":3972
+  /* "pywrapfst.pyx":4034
  * cdef vector[fst.WeightClass] *_shortestdistance(_Fst ifst,
  *                                                 float delta=fst.kShortestDelta,
  *                                                 int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                                                 queue_type=b"auto",
  *                                                 bool reverse=False) except *:
  */
-  __pyx_k__47 = fst::kNoStateId;
+  __pyx_k__45 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3993
+  /* "pywrapfst.pyx":4057
  * 
  * def shortestdistance(_Fst ifst,
  *                      float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
  *                      int64 nstate=fst.kNoStateId,
  *                      queue_type=b"auto",
  */
-  __pyx_k__48 = fst::kShortestDelta;
+  __pyx_k__46 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":3994
+  /* "pywrapfst.pyx":4058
  * def shortestdistance(_Fst ifst,
  *                      float delta=fst.kShortestDelta,
  *                      int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                      queue_type=b"auto",
  *                      bool reverse=False):
  */
-  __pyx_k__49 = fst::kNoStateId;
+  __pyx_k__47 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3992
+  /* "pywrapfst.pyx":4056
  * 
  * 
  * def shortestdistance(_Fst ifst,             # <<<<<<<<<<<<<<
  *                      float delta=fst.kShortestDelta,
  *                      int64 nstate=fst.kNoStateId,
  */
-  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_53shortestdistance, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3992, __pyx_L1_error)
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_55shortestdistance, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4056, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_shortestdistance, __pyx_t_1) < 0) __PYX_ERR(0, 3992, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_shortestdistance, __pyx_t_1) < 0) __PYX_ERR(0, 4056, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":4030
+  /* "pywrapfst.pyx":4094
  * 
  * cpdef _MutableFst shortestpath(_Fst ifst,
  *                                float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
  *                                int32 nshortest=1,
  *                                int64 nstate=fst.kNoStateId,
  */
-  __pyx_k__50 = fst::kShortestDelta;
+  __pyx_k__48 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":4032
+  /* "pywrapfst.pyx":4096
  *                                float delta=fst.kShortestDelta,
  *                                int32 nshortest=1,
  *                                int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                                queue_type=b"auto",
  *                                bool unique=False,
  */
-  __pyx_k__51 = fst::kNoStateId;
+  __pyx_k__49 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":4030
+  /* "pywrapfst.pyx":4094
  * 
  * cpdef _MutableFst shortestpath(_Fst ifst,
  *                                float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
  *                                int32 nshortest=1,
  *                                int64 nstate=fst.kNoStateId,
  */
-  __pyx_k__50 = fst::kShortestDelta;
+  __pyx_k__48 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":4032
+  /* "pywrapfst.pyx":4096
  *                                float delta=fst.kShortestDelta,
  *                                int32 nshortest=1,
  *                                int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                                queue_type=b"auto",
  *                                bool unique=False,
  */
-  __pyx_k__51 = fst::kNoStateId;
+  __pyx_k__49 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":4185
+  /* "pywrapfst.pyx":4251
  * 
  *   def __cinit__(self,
  *                 string fst_type=b"vector",             # <<<<<<<<<<<<<<
  *                 string arc_type=b"standard",
  *                 SymbolTable isymbols=None,
  */
-  __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_n_b_vector); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4185, __pyx_L1_error)
-  __pyx_k__52 = __pyx_t_5;
+  __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_n_b_vector); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4251, __pyx_L1_error)
+  __pyx_k__50 = __pyx_t_5;
 
-  /* "pywrapfst.pyx":4186
+  /* "pywrapfst.pyx":4252
  *   def __cinit__(self,
  *                 string fst_type=b"vector",
  *                 string arc_type=b"standard",             # <<<<<<<<<<<<<<
  *                 SymbolTable isymbols=None,
  *                 SymbolTable osymbols=None,
  */
-  __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_n_b_standard); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4186, __pyx_L1_error)
-  __pyx_k__53 = __pyx_t_5;
+  __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_n_b_standard); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4252, __pyx_L1_error)
+  __pyx_k__51 = __pyx_t_5;
 
-  /* "pywrapfst.pyx":4287
+  /* "pywrapfst.pyx":4360
  * 
  *   @classmethod
- *   def open(cls, *filenames):             # <<<<<<<<<<<<<<
+ *   def open(cls, *sources):             # <<<<<<<<<<<<<<
  *     """
- *     FarReader.open(*filenames)
+ *     FarReader.open(*sources)
  */
-  __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_9pywrapfst_FarReader, __pyx_n_s_open); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4287, __pyx_L1_error)
+  __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_9pywrapfst_FarReader, __pyx_n_s_open); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4360, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
 
-  /* "pywrapfst.pyx":4286
+  /* "pywrapfst.pyx":4359
  *     return "<{} FarReader at 0x{:x}>".format(self.far_type(), id(self))
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
- *   def open(cls, *filenames):
+ *   def open(cls, *sources):
  *     """
  */
-  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4286, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4359, __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, 4287, __pyx_L1_error)
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_FarReader->tp_dict, __pyx_n_s_open, __pyx_t_2) < 0) __PYX_ERR(0, 4360, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_FarReader);
 
-  /* "pywrapfst.pyx":4438
+  /* "pywrapfst.pyx":4511
  * 
  *   @classmethod
- *   def create(cls, filename, arc_type=b"standard", far_type=b"default"):             # <<<<<<<<<<<<<<
+ *   def create(cls, source, arc_type=b"standard", far_type=b"default"):             # <<<<<<<<<<<<<<
  *     """
  *     FarWriter.
  */
-  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_FarWriter, __pyx_n_s_create); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4438, __pyx_L1_error)
+  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_FarWriter, __pyx_n_s_create); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4511, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":4437
+  /* "pywrapfst.pyx":4510
  *     return "<{} FarWriter at 0x{:x}>".format(self.far_type(), id(self))
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
- *   def create(cls, filename, arc_type=b"standard", far_type=b"default"):
+ *   def create(cls, source, arc_type=b"standard", far_type=b"default"):
  *     """
  */
-  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4437, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4510, __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, 4438, __pyx_L1_error)
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_FarWriter->tp_dict, __pyx_n_s_create, __pyx_t_1) < 0) __PYX_ERR(0, 4511, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_FarWriter);
 
-  /* "pywrapfst.pyx":4530
+  /* "pywrapfst.pyx":4606
  * 
  * # Masks fst_error_fatal in-module.
  * fst.FLAGS_fst_error_fatal = False             # <<<<<<<<<<<<<<
@@ -52119,7 +53126,7 @@ if (!__Pyx_RefNanny) {
   FLAGS_fst_error_fatal = 0;
 
   /* "pywrapfst.pyx":1
- * #cython: nonecheck=True, c_string_type=unicode, c_string_encoding=utf8             # <<<<<<<<<<<<<<
+ * #cython: c_string_encoding=utf8, c_string_type=unicode, language_level=3, nonecheck=True             # <<<<<<<<<<<<<<
  * # Licensed under the Apache License, Version 2.0 (the "License");
  * # you may not use this file except in compliance with the License.
  */
@@ -53421,61 +54428,6 @@ static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) {
     return 0;
 }
 
-/* IterNext */
-static PyObject *__Pyx_PyIter_Next2Default(PyObject* defval) {
-    PyObject* exc_type;
-    __Pyx_PyThreadState_declare
-    __Pyx_PyThreadState_assign
-    exc_type = __Pyx_PyErr_Occurred();
-    if (unlikely(exc_type)) {
-        if (!defval || unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration)))
-            return NULL;
-        __Pyx_PyErr_Clear();
-        Py_INCREF(defval);
-        return defval;
-    }
-    if (defval) {
-        Py_INCREF(defval);
-        return defval;
-    }
-    __Pyx_PyErr_SetNone(PyExc_StopIteration);
-    return NULL;
-}
-static void __Pyx_PyIter_Next_ErrorNoIterator(PyObject *iterator) {
-    PyErr_Format(PyExc_TypeError,
-        "%.200s object is not an iterator", Py_TYPE(iterator)->tp_name);
-}
-static CYTHON_INLINE PyObject *__Pyx_PyIter_Next2(PyObject* iterator, PyObject* defval) {
-    PyObject* next;
-    iternextfunc iternext = Py_TYPE(iterator)->tp_iternext;
-    if (likely(iternext)) {
-#if CYTHON_USE_TYPE_SLOTS
-        next = iternext(iterator);
-        if (likely(next))
-            return next;
-        #if PY_VERSION_HEX >= 0x02070000
-        if (unlikely(iternext == &_PyObject_NextNotImplemented))
-            return NULL;
-        #endif
-#else
-        next = PyIter_Next(iterator);
-        if (likely(next))
-            return next;
-#endif
-    } else if (CYTHON_USE_TYPE_SLOTS || unlikely(!PyIter_Check(iterator))) {
-        __Pyx_PyIter_Next_ErrorNoIterator(iterator);
-        return NULL;
-    }
-#if !CYTHON_USE_TYPE_SLOTS
-    else {
-        next = PyIter_Next(iterator);
-        if (likely(next))
-            return next;
-    }
-#endif
-    return __Pyx_PyIter_Next2Default(defval);
-}
-
 /* PyObject_GenericGetAttrNoDict */
 #if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000
 static PyObject *__Pyx_RaiseGenericGetAttributeError(PyTypeObject *tp, PyObject *attr_name) {
@@ -54818,24 +55770,24 @@ static CYTHON_INLINE PyObject* __Pyx_PyInt_From_uint64_t(uint64_t value) {
 }
 
 /* CIntToPy */
-static CYTHON_INLINE PyObject* __Pyx_PyInt_From_uint32_t(uint32_t value) {
-    const uint32_t neg_one = (uint32_t) ((uint32_t) 0 - (uint32_t) 1), const_zero = (uint32_t) 0;
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_uint8_t(uint8_t value) {
+    const uint8_t neg_one = (uint8_t) ((uint8_t) 0 - (uint8_t) 1), const_zero = (uint8_t) 0;
     const int is_unsigned = neg_one > const_zero;
     if (is_unsigned) {
-        if (sizeof(uint32_t) < sizeof(long)) {
+        if (sizeof(uint8_t) < sizeof(long)) {
             return PyInt_FromLong((long) value);
-        } else if (sizeof(uint32_t) <= sizeof(unsigned long)) {
+        } else if (sizeof(uint8_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(uint8_t) <= sizeof(unsigned PY_LONG_LONG)) {
             return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value);
 #endif
         }
     } else {
-        if (sizeof(uint32_t) <= sizeof(long)) {
+        if (sizeof(uint8_t) <= sizeof(long)) {
             return PyInt_FromLong((long) value);
 #ifdef HAVE_LONG_LONG
-        } else if (sizeof(uint32_t) <= sizeof(PY_LONG_LONG)) {
+        } else if (sizeof(uint8_t) <= sizeof(PY_LONG_LONG)) {
             return PyLong_FromLongLong((PY_LONG_LONG) value);
 #endif
         }
@@ -54843,7 +55795,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyInt_From_uint32_t(uint32_t value) {
     {
         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(uint8_t),
                                      little, !is_unsigned);
     }
 }
@@ -55667,19 +56619,19 @@ raise_neg_overflow:
 }
 
 /* CIntFromPy */
-static CYTHON_INLINE uint32_t __Pyx_PyInt_As_uint32_t(PyObject *x) {
-    const uint32_t neg_one = (uint32_t) ((uint32_t) 0 - (uint32_t) 1), const_zero = (uint32_t) 0;
+static CYTHON_INLINE uint8_t __Pyx_PyInt_As_uint8_t(PyObject *x) {
+    const uint8_t neg_one = (uint8_t) ((uint8_t) 0 - (uint8_t) 1), const_zero = (uint8_t) 0;
     const int is_unsigned = neg_one > const_zero;
 #if PY_MAJOR_VERSION < 3
     if (likely(PyInt_Check(x))) {
-        if (sizeof(uint32_t) < sizeof(long)) {
-            __PYX_VERIFY_RETURN_INT(uint32_t, long, PyInt_AS_LONG(x))
+        if (sizeof(uint8_t) < sizeof(long)) {
+            __PYX_VERIFY_RETURN_INT(uint8_t, long, PyInt_AS_LONG(x))
         } else {
             long val = PyInt_AS_LONG(x);
             if (is_unsigned && unlikely(val < 0)) {
                 goto raise_neg_overflow;
             }
-            return (uint32_t) val;
+            return (uint8_t) val;
         }
     } else
 #endif
@@ -55688,32 +56640,32 @@ static CYTHON_INLINE uint32_t __Pyx_PyInt_As_uint32_t(PyObject *x) {
 #if CYTHON_USE_PYLONG_INTERNALS
             const digit* digits = ((PyLongObject*)x)->ob_digit;
             switch (Py_SIZE(x)) {
-                case  0: return (uint32_t) 0;
-                case  1: __PYX_VERIFY_RETURN_INT(uint32_t, digit, digits[0])
+                case  0: return (uint8_t) 0;
+                case  1: __PYX_VERIFY_RETURN_INT(uint8_t, digit, digits[0])
                 case 2:
-                    if (8 * sizeof(uint32_t) > 1 * PyLong_SHIFT) {
+                    if (8 * sizeof(uint8_t) > 1 * PyLong_SHIFT) {
                         if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) {
-                            __PYX_VERIFY_RETURN_INT(uint32_t, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
-                        } else if (8 * sizeof(uint32_t) >= 2 * PyLong_SHIFT) {
-                            return (uint32_t) (((((uint32_t)digits[1]) << PyLong_SHIFT) | (uint32_t)digits[0]));
+                            __PYX_VERIFY_RETURN_INT(uint8_t, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(uint8_t) >= 2 * PyLong_SHIFT) {
+                            return (uint8_t) (((((uint8_t)digits[1]) << PyLong_SHIFT) | (uint8_t)digits[0]));
                         }
                     }
                     break;
                 case 3:
-                    if (8 * sizeof(uint32_t) > 2 * PyLong_SHIFT) {
+                    if (8 * sizeof(uint8_t) > 2 * PyLong_SHIFT) {
                         if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) {
-                            __PYX_VERIFY_RETURN_INT(uint32_t, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
-                        } else if (8 * sizeof(uint32_t) >= 3 * PyLong_SHIFT) {
-                            return (uint32_t) (((((((uint32_t)digits[2]) << PyLong_SHIFT) | (uint32_t)digits[1]) << PyLong_SHIFT) | (uint32_t)digits[0]));
+                            __PYX_VERIFY_RETURN_INT(uint8_t, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(uint8_t) >= 3 * PyLong_SHIFT) {
+                            return (uint8_t) (((((((uint8_t)digits[2]) << PyLong_SHIFT) | (uint8_t)digits[1]) << PyLong_SHIFT) | (uint8_t)digits[0]));
                         }
                     }
                     break;
                 case 4:
-                    if (8 * sizeof(uint32_t) > 3 * PyLong_SHIFT) {
+                    if (8 * sizeof(uint8_t) > 3 * PyLong_SHIFT) {
                         if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) {
-                            __PYX_VERIFY_RETURN_INT(uint32_t, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
-                        } else if (8 * sizeof(uint32_t) >= 4 * PyLong_SHIFT) {
-                            return (uint32_t) (((((((((uint32_t)digits[3]) << PyLong_SHIFT) | (uint32_t)digits[2]) << PyLong_SHIFT) | (uint32_t)digits[1]) << PyLong_SHIFT) | (uint32_t)digits[0]));
+                            __PYX_VERIFY_RETURN_INT(uint8_t, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(uint8_t) >= 4 * PyLong_SHIFT) {
+                            return (uint8_t) (((((((((uint8_t)digits[3]) << PyLong_SHIFT) | (uint8_t)digits[2]) << PyLong_SHIFT) | (uint8_t)digits[1]) << PyLong_SHIFT) | (uint8_t)digits[0]));
                         }
                     }
                     break;
@@ -55727,86 +56679,86 @@ static CYTHON_INLINE uint32_t __Pyx_PyInt_As_uint32_t(PyObject *x) {
             {
                 int result = PyObject_RichCompareBool(x, Py_False, Py_LT);
                 if (unlikely(result < 0))
-                    return (uint32_t) -1;
+                    return (uint8_t) -1;
                 if (unlikely(result == 1))
                     goto raise_neg_overflow;
             }
 #endif
-            if (sizeof(uint32_t) <= sizeof(unsigned long)) {
-                __PYX_VERIFY_RETURN_INT_EXC(uint32_t, unsigned long, PyLong_AsUnsignedLong(x))
+            if (sizeof(uint8_t) <= sizeof(unsigned long)) {
+                __PYX_VERIFY_RETURN_INT_EXC(uint8_t, unsigned long, PyLong_AsUnsignedLong(x))
 #ifdef HAVE_LONG_LONG
-            } else if (sizeof(uint32_t) <= sizeof(unsigned PY_LONG_LONG)) {
-                __PYX_VERIFY_RETURN_INT_EXC(uint32_t, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x))
+            } else if (sizeof(uint8_t) <= sizeof(unsigned PY_LONG_LONG)) {
+                __PYX_VERIFY_RETURN_INT_EXC(uint8_t, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x))
 #endif
             }
         } else {
 #if CYTHON_USE_PYLONG_INTERNALS
             const digit* digits = ((PyLongObject*)x)->ob_digit;
             switch (Py_SIZE(x)) {
-                case  0: return (uint32_t) 0;
-                case -1: __PYX_VERIFY_RETURN_INT(uint32_t, sdigit, (sdigit) (-(sdigit)digits[0]))
-                case  1: __PYX_VERIFY_RETURN_INT(uint32_t,  digit, +digits[0])
+                case  0: return (uint8_t) 0;
+                case -1: __PYX_VERIFY_RETURN_INT(uint8_t, sdigit, (sdigit) (-(sdigit)digits[0]))
+                case  1: __PYX_VERIFY_RETURN_INT(uint8_t,  digit, +digits[0])
                 case -2:
-                    if (8 * sizeof(uint32_t) - 1 > 1 * PyLong_SHIFT) {
+                    if (8 * sizeof(uint8_t) - 1 > 1 * PyLong_SHIFT) {
                         if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) {
-                            __PYX_VERIFY_RETURN_INT(uint32_t, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
-                        } else if (8 * sizeof(uint32_t) - 1 > 2 * PyLong_SHIFT) {
-                            return (uint32_t) (((uint32_t)-1)*(((((uint32_t)digits[1]) << PyLong_SHIFT) | (uint32_t)digits[0])));
+                            __PYX_VERIFY_RETURN_INT(uint8_t, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(uint8_t) - 1 > 2 * PyLong_SHIFT) {
+                            return (uint8_t) (((uint8_t)-1)*(((((uint8_t)digits[1]) << PyLong_SHIFT) | (uint8_t)digits[0])));
                         }
                     }
                     break;
                 case 2:
-                    if (8 * sizeof(uint32_t) > 1 * PyLong_SHIFT) {
+                    if (8 * sizeof(uint8_t) > 1 * PyLong_SHIFT) {
                         if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) {
-                            __PYX_VERIFY_RETURN_INT(uint32_t, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
-                        } else if (8 * sizeof(uint32_t) - 1 > 2 * PyLong_SHIFT) {
-                            return (uint32_t) ((((((uint32_t)digits[1]) << PyLong_SHIFT) | (uint32_t)digits[0])));
+                            __PYX_VERIFY_RETURN_INT(uint8_t, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(uint8_t) - 1 > 2 * PyLong_SHIFT) {
+                            return (uint8_t) ((((((uint8_t)digits[1]) << PyLong_SHIFT) | (uint8_t)digits[0])));
                         }
                     }
                     break;
                 case -3:
-                    if (8 * sizeof(uint32_t) - 1 > 2 * PyLong_SHIFT) {
+                    if (8 * sizeof(uint8_t) - 1 > 2 * PyLong_SHIFT) {
                         if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) {
-                            __PYX_VERIFY_RETURN_INT(uint32_t, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
-                        } else if (8 * sizeof(uint32_t) - 1 > 3 * PyLong_SHIFT) {
-                            return (uint32_t) (((uint32_t)-1)*(((((((uint32_t)digits[2]) << PyLong_SHIFT) | (uint32_t)digits[1]) << PyLong_SHIFT) | (uint32_t)digits[0])));
+                            __PYX_VERIFY_RETURN_INT(uint8_t, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(uint8_t) - 1 > 3 * PyLong_SHIFT) {
+                            return (uint8_t) (((uint8_t)-1)*(((((((uint8_t)digits[2]) << PyLong_SHIFT) | (uint8_t)digits[1]) << PyLong_SHIFT) | (uint8_t)digits[0])));
                         }
                     }
                     break;
                 case 3:
-                    if (8 * sizeof(uint32_t) > 2 * PyLong_SHIFT) {
+                    if (8 * sizeof(uint8_t) > 2 * PyLong_SHIFT) {
                         if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) {
-                            __PYX_VERIFY_RETURN_INT(uint32_t, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
-                        } else if (8 * sizeof(uint32_t) - 1 > 3 * PyLong_SHIFT) {
-                            return (uint32_t) ((((((((uint32_t)digits[2]) << PyLong_SHIFT) | (uint32_t)digits[1]) << PyLong_SHIFT) | (uint32_t)digits[0])));
+                            __PYX_VERIFY_RETURN_INT(uint8_t, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(uint8_t) - 1 > 3 * PyLong_SHIFT) {
+                            return (uint8_t) ((((((((uint8_t)digits[2]) << PyLong_SHIFT) | (uint8_t)digits[1]) << PyLong_SHIFT) | (uint8_t)digits[0])));
                         }
                     }
                     break;
                 case -4:
-                    if (8 * sizeof(uint32_t) - 1 > 3 * PyLong_SHIFT) {
+                    if (8 * sizeof(uint8_t) - 1 > 3 * PyLong_SHIFT) {
                         if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) {
-                            __PYX_VERIFY_RETURN_INT(uint32_t, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
-                        } else if (8 * sizeof(uint32_t) - 1 > 4 * PyLong_SHIFT) {
-                            return (uint32_t) (((uint32_t)-1)*(((((((((uint32_t)digits[3]) << PyLong_SHIFT) | (uint32_t)digits[2]) << PyLong_SHIFT) | (uint32_t)digits[1]) << PyLong_SHIFT) | (uint32_t)digits[0])));
+                            __PYX_VERIFY_RETURN_INT(uint8_t, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(uint8_t) - 1 > 4 * PyLong_SHIFT) {
+                            return (uint8_t) (((uint8_t)-1)*(((((((((uint8_t)digits[3]) << PyLong_SHIFT) | (uint8_t)digits[2]) << PyLong_SHIFT) | (uint8_t)digits[1]) << PyLong_SHIFT) | (uint8_t)digits[0])));
                         }
                     }
                     break;
                 case 4:
-                    if (8 * sizeof(uint32_t) > 3 * PyLong_SHIFT) {
+                    if (8 * sizeof(uint8_t) > 3 * PyLong_SHIFT) {
                         if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) {
-                            __PYX_VERIFY_RETURN_INT(uint32_t, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
-                        } else if (8 * sizeof(uint32_t) - 1 > 4 * PyLong_SHIFT) {
-                            return (uint32_t) ((((((((((uint32_t)digits[3]) << PyLong_SHIFT) | (uint32_t)digits[2]) << PyLong_SHIFT) | (uint32_t)digits[1]) << PyLong_SHIFT) | (uint32_t)digits[0])));
+                            __PYX_VERIFY_RETURN_INT(uint8_t, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(uint8_t) - 1 > 4 * PyLong_SHIFT) {
+                            return (uint8_t) ((((((((((uint8_t)digits[3]) << PyLong_SHIFT) | (uint8_t)digits[2]) << PyLong_SHIFT) | (uint8_t)digits[1]) << PyLong_SHIFT) | (uint8_t)digits[0])));
                         }
                     }
                     break;
             }
 #endif
-            if (sizeof(uint32_t) <= sizeof(long)) {
-                __PYX_VERIFY_RETURN_INT_EXC(uint32_t, long, PyLong_AsLong(x))
+            if (sizeof(uint8_t) <= sizeof(long)) {
+                __PYX_VERIFY_RETURN_INT_EXC(uint8_t, long, PyLong_AsLong(x))
 #ifdef HAVE_LONG_LONG
-            } else if (sizeof(uint32_t) <= sizeof(PY_LONG_LONG)) {
-                __PYX_VERIFY_RETURN_INT_EXC(uint32_t, PY_LONG_LONG, PyLong_AsLongLong(x))
+            } else if (sizeof(uint8_t) <= sizeof(PY_LONG_LONG)) {
+                __PYX_VERIFY_RETURN_INT_EXC(uint8_t, PY_LONG_LONG, PyLong_AsLongLong(x))
 #endif
             }
         }
@@ -55815,7 +56767,7 @@ static CYTHON_INLINE uint32_t __Pyx_PyInt_As_uint32_t(PyObject *x) {
             PyErr_SetString(PyExc_RuntimeError,
                             "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
 #else
-            uint32_t val;
+            uint8_t val;
             PyObject *v = __Pyx_PyNumber_IntOrLong(x);
  #if PY_MAJOR_VERSION < 3
             if (likely(v) && !PyLong_Check(v)) {
@@ -55835,24 +56787,24 @@ static CYTHON_INLINE uint32_t __Pyx_PyInt_As_uint32_t(PyObject *x) {
                     return val;
             }
 #endif
-            return (uint32_t) -1;
+            return (uint8_t) -1;
         }
     } else {
-        uint32_t val;
+        uint8_t val;
         PyObject *tmp = __Pyx_PyNumber_IntOrLong(x);
-        if (!tmp) return (uint32_t) -1;
-        val = __Pyx_PyInt_As_uint32_t(tmp);
+        if (!tmp) return (uint8_t) -1;
+        val = __Pyx_PyInt_As_uint8_t(tmp);
         Py_DECREF(tmp);
         return val;
     }
 raise_overflow:
     PyErr_SetString(PyExc_OverflowError,
-        "value too large to convert to uint32_t");
-    return (uint32_t) -1;
+        "value too large to convert to uint8_t");
+    return (uint8_t) -1;
 raise_neg_overflow:
     PyErr_SetString(PyExc_OverflowError,
-        "can't convert negative value to uint32_t");
-    return (uint32_t) -1;
+        "can't convert negative value to uint8_t");
+    return (uint8_t) -1;
 }
 
 /* CIntFromPy */
index 8dc646e..80903ca 100644 (file)
@@ -1,3 +1,4 @@
+#cython: language_level=3
 # See www.openfst.org for extensive documentation on this weighted
 # finite-state transducer library.
 
@@ -12,11 +13,12 @@ from libcpp.string cimport string
 from libcpp.utility cimport pair
 from libcpp.vector cimport vector
 
-from basictypes cimport int32
-from basictypes cimport int64
-from basictypes cimport uint32
-from basictypes cimport uint64
+from basictypes cimport *
+
 cimport fst as fst
+
+from ios cimport ostream
+from ios cimport ofstream
 from ios cimport stringstream
 
 
@@ -38,7 +40,8 @@ cdef fst.RandArcSelection _get_rand_arc_selection(
     const string &replace_label_type) except *
 
 cdef fst.ReplaceLabelType _get_replace_label_type(
-    const string &replace_label_type, bool epsilon_on_replace) except *
+    const string &replace_label_type,
+    bool epsilon_on_replace) except *
 
 
 # Weight.
@@ -106,16 +109,16 @@ cdef class _SymbolTable(object):
 
   cpdef size_t num_symbols(self)
 
-  cpdef void write(self, filename) except *
+  cpdef void write(self, source) except *
 
-  cpdef void write_text(self, filename) except *
+  cpdef void write_text(self, source) except *
 
   cpdef bytes write_to_string(self)
 
 
 cdef class _EncodeMapperSymbolTable(_SymbolTable):
 
-  cdef shared_ptr[fst.EncodeMapperClass] _encoder
+  cdef shared_ptr[fst.EncodeMapperClass] _mapper
 
 
 cdef class _FstSymbolTable(_SymbolTable):
@@ -143,14 +146,16 @@ cdef class SymbolTable(_MutableSymbolTable):
 
 
 cdef _EncodeMapperSymbolTable _init_EncodeMapperSymbolTable(
-    fst.SymbolTable *table, shared_ptr[fst.EncodeMapperClass] encoder)
+    fst.SymbolTable *table,
+    shared_ptr[fst.EncodeMapperClass] encoder)
 
 
 cdef _FstSymbolTable _init_FstSymbolTable(fst.SymbolTable *table,
                                           shared_ptr[fst.FstClass] ifst)
 
 
-cdef _MutableFstSymbolTable _init_MutableFstSymbolTable(fst.SymbolTable *table,
+cdef _MutableFstSymbolTable _init_MutableFstSymbolTable(
+    fst.SymbolTable *table,
     shared_ptr[fst.MutableFstClass] ifst)
 
 
@@ -181,29 +186,38 @@ cdef class SymbolTableIterator(object):
 
 cdef class EncodeMapper(object):
 
-  cdef shared_ptr[fst.EncodeMapperClass] _encoder
+  cdef shared_ptr[fst.EncodeMapperClass] _mapper
 
   cpdef string arc_type(self)
 
-  cpdef uint32 flags(self)
+  cpdef string weight_type(self)
+
+  cpdef uint8 flags(self)
+
+  cpdef uint64 properties(self, uint64 mask)
+
+  cpdef void write(self, source) except *
+
+  cpdef bytes write_to_string(self)
 
   cpdef _EncodeMapperSymbolTable input_symbols(self)
 
   cpdef _EncodeMapperSymbolTable output_symbols(self)
 
-  cpdef uint64 properties(self, uint64 mask)
-
   cpdef void set_input_symbols(self, _SymbolTable syms) except *
 
   cpdef void set_output_symbols(self, _SymbolTable syms) except *
 
-  cpdef string weight_type(self)
 
+cdef EncodeMapper _init_EncodeMapper(fst.EncodeMapperClass *mapper)
+
+cpdef EncodeMapper _read_EncodeMapper_from_string(state)
 
 # Fst.
 
 
 ctypedef fst.FstClass * FstClass_ptr
+ctypedef const fst.FstClass * const_FstClass_ptr
 ctypedef fst.MutableFstClass * MutableFstClass_ptr
 ctypedef fst.VectorFstClass * VectorFstClass_ptr
 
@@ -226,12 +240,22 @@ cdef class _Fst(object):
 
   cpdef _Fst copy(self)
 
-  cpdef void draw(self, filename, _SymbolTable isymbols=?,
-                  _SymbolTable osymbols=?, SymbolTable ssymbols=?,
-                  bool acceptor=?, title=?, double width=?,
-                  double height=?, bool portrait=?, bool vertical=?,
-                  double ranksep=?, double nodesep=?, int32 fontsize=?,
-                  int32 precision=?, float_format=?,
+  cpdef void draw(self,
+                  source,
+                  _SymbolTable isymbols=?,
+                  _SymbolTable osymbols=?,
+                  _SymbolTable ssymbols=?,
+                  bool acceptor=?,
+                  title=?,
+                  double width=?,
+                  double height=?,
+                  bool portrait=?,
+                  bool vertical=?,
+                  double ranksep=?,
+                  double nodesep=?,
+                  int32 fontsize=?,
+                  int32 precision=?,
+                  float_format=?,
                   bool show_weight_one=?)
 
   cpdef Weight final(self, int64 state)
@@ -254,15 +278,19 @@ cdef class _Fst(object):
 
   cpdef StateIterator states(self)
 
-  cpdef string text(self, _SymbolTable isymbols=?, _SymbolTable osymbols=?,
-                    _SymbolTable ssymbols=?, bool acceptor=?,
-                    bool show_weight_one=?, missing_sym=?)
+  cpdef string text(self,
+                    _SymbolTable isymbols=?,
+                    _SymbolTable osymbols=?,
+                    _SymbolTable ssymbols=?,
+                    bool acceptor=?,
+                    bool show_weight_one=?,
+                    missing_sym=?)
 
   cpdef bool verify(self)
 
   cpdef string weight_type(self)
 
-  cpdef void write(self, filename) except *
+  cpdef void write(self, source) except *
 
   cpdef bytes write_to_string(self)
 
@@ -283,7 +311,7 @@ cdef class _MutableFst(_Fst):
 
   cdef void _closure(self, bool closure_plus=?) except *
 
-  cdef void _concat(self, _Fst ifst) except *
+  cdef void _concat(self, _Fst fst2) except *
 
   cdef void _connect(self) except *
 
@@ -307,16 +335,22 @@ cdef class _MutableFst(_Fst):
 
   cdef void _prune(self, float delta=?, int64 nstate=?, weight=?) except *
 
-  cdef void _push(self, float delta=?, bool remove_total_weight=?,
+  cdef void _push(self,
+                  float delta=?,
+                  bool remove_total_weight=?,
                   bool to_final=?) except *
 
   cdef void _relabel_pairs(self, ipairs=?, opairs=?) except *
 
-  cdef void _relabel_tables(self, _SymbolTable old_isymbols=?,
-      _SymbolTable new_isymbols=?, unknown_isymbol=?,
-      bool attach_new_isymbols=?,
-      _SymbolTable old_osymbols=?, _SymbolTable new_osymbols=?,
-      unknown_osymbol=?, bool attach_new_osymbols=?) except *
+  cdef void _relabel_tables(self,
+                            _SymbolTable old_isymbols=?,
+                            _SymbolTable new_isymbols=?,
+                            unknown_isymbol=?,
+                            bool attach_new_isymbols=?,
+                            _SymbolTable old_osymbols=?,
+                            _SymbolTable new_osymbols=?,
+                            unknown_osymbol=?,
+                            bool attach_new_osymbols=?) except *
 
   cdef void _reserve_arcs(self, int64 state, size_t n) except *
 
@@ -324,8 +358,12 @@ cdef class _MutableFst(_Fst):
 
   cdef void _reweight(self, potentials, bool to_final=?) except *
 
-  cdef void _rmepsilon(self, queue_type=?, bool connect=?, weight=?,
-                       int64 nstate=?, float delta=?) except *
+  cdef void _rmepsilon(self,
+                       queue_type=?,
+                       bool connect=?,
+                       weight=?,
+                       int64 nstate=?,
+                       float delta=?) except *
 
   cdef void _set_final(self, int64 state, weight=?) except *
 
@@ -339,8 +377,6 @@ cdef class _MutableFst(_Fst):
 
   cdef void _topsort(self) except *
 
-  cdef void _union(self, _Fst ifst) except *
-
 
 # Construction helpers.
 
@@ -353,7 +389,7 @@ cdef _Fst _init_XFst(FstClass_ptr tfst)
 
 cdef _MutableFst _create_Fst(arc_type=?)
 
-cpdef _Fst _read(filename)
+cpdef _Fst _read(source)
 
 cpdef _Fst _read_Fst_from_string(state)
 
@@ -378,7 +414,7 @@ cdef class ArcIterator(object):
 
   cpdef bool done(self)
 
-  cpdef uint32 flags(self)
+  cpdef uint8 flags(self)
 
   cpdef void next(self)
 
@@ -388,7 +424,7 @@ cdef class ArcIterator(object):
 
   cpdef void seek(self, size_t a)
 
-  cpdef void set_flags(self, uint32 flags, uint32 mask)
+  cpdef void set_flags(self, uint8 flags, uint8 mask)
 
   cpdef object value(self)
 
@@ -400,7 +436,7 @@ cdef class MutableArcIterator(object):
 
   cpdef bool done(self)
 
-  cpdef uint32 flags(self)
+  cpdef uint8 flags(self)
 
   cpdef void next(self)
 
@@ -410,7 +446,7 @@ cdef class MutableArcIterator(object):
 
   cpdef void seek(self, size_t a)
 
-  cpdef void set_flags(self, uint32 flags, uint32 mask)
+  cpdef void set_flags(self, uint8 flags, uint8 mask)
 
   cpdef void set_value(self, Arc arc)
 
@@ -436,23 +472,37 @@ cdef class StateIterator(object):
 
 cdef _Fst _map(_Fst ifst, float delta=?, map_type=?, double power=?, weight=?)
 
-cpdef _Fst arcmap(_Fst ifst, float delta=?, map_type=?, double power=?,
+cpdef _Fst arcmap(_Fst ifst,
+                  float delta=?,
+                  map_type=?,
+                  double power=?,
                   weight=?)
 
-cpdef _MutableFst compose(_Fst ifst1, _Fst ifst2, compose_filter=?,
+cpdef _MutableFst compose(_Fst ifst1,
+                          _Fst ifst2,
+                          compose_filter=?,
                           bool connect=?)
 
 cpdef _Fst convert(_Fst ifst, fst_type=?)
 
-cpdef _MutableFst determinize(_Fst ifst, float delta=?, det_type=?,
-                              int64 nstate=?, int64 subsequential_label=?,
-                              weight=?, bool increment_subsequential_label=?)
-
-cpdef _MutableFst difference(_Fst ifst1, _Fst ifst2, compose_filter=?,
+cpdef _MutableFst determinize(_Fst ifst,
+                              float delta=?,
+                              det_type=?,
+                              int64 nstate=?,
+                              int64 subsequential_label=?,
+                              weight=?,
+                              bool increment_subsequential_label=?)
+
+cpdef _MutableFst difference(_Fst ifst1,
+                             _Fst ifst2,
+                             compose_filter=?,
                              bool connect=?)
 
-cpdef _MutableFst disambiguate(_Fst ifst, float delta=?, int64 nstate=?,
-                               int64 subsequential_label=?, weight=?)
+cpdef _MutableFst disambiguate(_Fst ifst,
+                               float delta=?,
+                               int64 nstate=?,
+                               int64 subsequential_label=?,
+                               weight=?)
 
 cpdef _MutableFst epsnormalize(_Fst ifst, bool eps_norm_output=?)
 
@@ -460,40 +510,66 @@ cpdef bool equal(_Fst ifst1, _Fst ifst2, float delta=?)
 
 cpdef bool equivalent(_Fst ifst1, _Fst ifst2, float delta=?) except *
 
-cpdef _MutableFst intersect(_Fst ifst1, _Fst ifst2, compose_filter=?,
+cpdef _MutableFst intersect(_Fst ifst1,
+                            _Fst ifst2,
+                            compose_filter=?,
                             bool connect=?)
 
 cpdef bool isomorphic(_Fst ifst1, _Fst ifst2, float delta=?)
 
-cpdef _MutableFst prune(_Fst ifst, float delta=?, int64 nstate=?,
+cpdef _MutableFst prune(_Fst ifst,
+                        float delta=?,
+                        int64 nstate=?,
                         weight=?)
 
-cpdef _MutableFst push(_Fst ifst, float delta=?, bool push_weights=?,
-                       bool push_labels=?, bool remove_common_affix=?,
-                       bool remove_total_weight=?, bool to_final=?)
-
-cpdef bool randequivalent(_Fst ifst1, _Fst ifst2, int32 npath=?,
-                          float delta=?, time_t seed=?, select=?,
+cpdef _MutableFst push(_Fst ifst,
+                       float delta=?,
+                       bool push_weights=?,
+                       bool push_labels=?,
+                       bool remove_common_affix=?,
+                       bool remove_total_weight=?,
+                       bool to_final=?)
+
+cpdef bool randequivalent(_Fst ifst1,
+                          _Fst ifst2,
+                          int32 npath=?,
+                          float delta=?,
+                          time_t seed=?,
+                          select=?,
                           int32 max_length=?) except *
 
-cpdef _MutableFst randgen(_Fst ifst, int32 npath=?, time_t seed=?,
-                          select=?, int32 max_length=?,
-                          bool remove_total_weight=?, bool weighted=?)
+cpdef _MutableFst randgen(_Fst ifst,
+                          int32 npath=?,
+                          time_t seed=?,
+                          select=?,
+                          int32 max_length=?,
+                          bool remove_total_weight=?,
+                          bool weighted=?)
 
-cdef fst.ReplaceLabelType _get_replace_label_type(string rlt,
+cdef fst.ReplaceLabelType _get_replace_label_type(
+    string rlt,
     bool epsilon_on_replace) except *
 
-cpdef _MutableFst replace(pairs, call_arc_labeling=?, return_arc_labeling=?,
-                          bool epsilon_on_replace=?, int64 return_label=?)
+cpdef _MutableFst replace(pairs,
+                          call_arc_labeling=?,
+                          return_arc_labeling=?,
+                          bool epsilon_on_replace=?,
+                          int64 return_label=?)
 
 cpdef _MutableFst reverse(_Fst ifst, bool require_superinitial=?)
 
-cdef vector[fst.WeightClass] *_shortestdistance(_Fst ifst, float delta=?,
-                                                int64 nstate=?, queue_type=?,
+cdef vector[fst.WeightClass] *_shortestdistance(_Fst ifst,
+                                                float delta=?,
+                                                int64 nstate=?,
+                                                queue_type=?,
                                                 bool reverse=?) except *
 
-cpdef _MutableFst shortestpath(_Fst ifst, float delta=?, int32 nshortest=?,
-                               int64 nstate=?, queue_type=?, bool unique=?,
+cpdef _MutableFst shortestpath(_Fst ifst,
+                               float delta=?,
+                               int32 nshortest=?,
+                               int64 nstate=?,
+                               queue_type=?,
+                               bool unique=?,
                                weight=?)
 
 cpdef _Fst statemap(_Fst ifst, map_type)
index 7dd7492..814f35d 100644 (file)
@@ -1,4 +1,4 @@
-#cython: nonecheck=True, c_string_type=unicode, c_string_encoding=utf8
+#cython: c_string_encoding=utf8, c_string_type=unicode, language_level=3, nonecheck=True
 # See www.openfst.org for extensive documentation on this weighted
 # finite-state transducer library.
 
@@ -70,10 +70,10 @@ from posix.unistd cimport getpid
 from libcpp cimport bool
 from libcpp.cast cimport const_cast
 from libcpp.cast cimport static_cast
+from libcpp.memory cimport static_pointer_cast
 
-# Our C++ imports.
+# Missing C++ imports.
 from ios cimport ofstream
-from memory cimport static_pointer_cast
 
 # Cython operator workarounds.
 from cython.operator cimport address as addr       # &foo
@@ -791,39 +791,39 @@ cdef class _SymbolTable(object):
     """
     return self._table.NumSymbols()
 
-  cpdef void write(self, filename) except *:
+  cpdef void write(self, source) except *:
     """
-    write(self, filename)
+    write(self, source)
 
     Serializes symbol table to a file.
 
     This methods writes the SymbolTable to a file in binary format.
 
     Args:
-      filename: The string location of the output file.
+      source: The string location of the output file.
 
     Raises:
       FstIOError: Write failed.
     """
-    if not self._table.Write(tostring(filename)):
-      raise FstIOError("Write failed: {!r}".format(filename))
+    if not self._table.Write(tostring(source)):
+      raise FstIOError("Write failed: {!r}".format(source))
 
-  cpdef void write_text(self, filename) except *:
+  cpdef void write_text(self, source) except *:
     """
-    write_text(self, filename)
+    write_text(self, source)
 
     Writes symbol table to text file.
 
     This method writes the SymbolTable to a file in human-readable format.
 
     Args:
-      filename: The string location of the output file.
+      source: The string location of the output file.
 
     Raises:
       FstIOError: Write failed.
     """
-    if not self._table.WriteText(tostring(filename)):
-      raise FstIOError("Write failed: {!r}".format(filename))
+    if not self._table.WriteText(tostring(source)):
+      raise FstIOError("Write failed: {!r}".format(source))
 
   cpdef bytes write_to_string(self):
     """
@@ -836,8 +836,6 @@ cdef class _SymbolTable(object):
 
     Raises:
       FstIOError: Write to string failed.
-
-    See also: `read_from_string`.
     """
     cdef stringstream sstrm
     if not self._table.Write(sstrm):
@@ -972,59 +970,55 @@ cdef class SymbolTable(_MutableSymbolTable):
     self._smart_table.reset(self._table)
 
   @classmethod
-  def read(cls, filename):
+  def read(cls, source):
     """
-    SymbolTable.read(filename)
+    SymbolTable.read(source)
 
     Reads symbol table from binary file.
 
     This class method creates a new SymbolTable from a symbol table binary file.
 
     Args:
-      filename: The string location of the input binary file.
+      source: The string location of the input binary file.
 
     Returns:
       A new SymbolTable instance.
-
-    See also: `SymbolTable.read_fst`, `SymbolTable.read_text`.
     """
     cdef unique_ptr[fst.SymbolTable] syms
-    syms.reset(fst.SymbolTable.Read(tostring(filename)))
+    syms.reset(fst.SymbolTable.Read(tostring(source)))
     if syms.get() == NULL:
-      raise FstIOError("Read failed: {!r}".format(filename))
+      raise FstIOError("Read failed: {!r}".format(source))
     return _init_SymbolTable(syms.release())
 
   @classmethod
-  def read_text(cls, filename, bool allow_negative_labels=False):
+  def read_text(cls, source, bool allow_negative_labels=False):
     """
-    SymbolTable.read_text(filename)
+    SymbolTable.read_text(source)
 
     Reads symbol table from text file.
 
     This class method creates a new SymbolTable from a symbol table text file.
 
     Args:
-      filename: The string location of the input text file.
+      source: The string location of the input text file.
       allow_negative_labels: Should negative labels be allowed? (Not
           recommended; may cause conflicts).
 
     Returns:
       A new SymbolTable instance.
-
-    See also: `SymbolTable.read`, `SymbolTable.read_fst`.
     """
     cdef unique_ptr[fst.SymbolTableTextOptions] opts
     opts.reset(new fst.SymbolTableTextOptions(allow_negative_labels))
     cdef unique_ptr[fst.SymbolTable] syms
-    syms.reset(fst.SymbolTable.ReadText(tostring(filename), deref(opts)))
+    syms.reset(fst.SymbolTable.ReadText(tostring(source), deref(opts)))
     if syms.get() == NULL:
-      raise FstIOError("Read failed: {!r}".format(filename))
+      raise FstIOError("Read failed: {!r}".format(source))
     return _init_SymbolTable(syms.release())
 
   @classmethod
-  def read_fst(cls, filename, bool input_table):
+  def read_fst(cls, source, bool input_table):
     """
-    SymbolTable.read_fst(filename, input_table)
+    SymbolTable.read_fst(source, input_table)
 
     Reads symbol table from an FST file without loading the corresponding FST.
 
@@ -1032,7 +1026,7 @@ cdef class SymbolTable(_MutableSymbolTable):
     output symbol table from an FST file, without loading the corresponding FST.
 
     Args:
-      filename: The string location of the input FST file.
+      source: The string location of the input FST file.
       input_table: Should the input table be read (True) or the output table
           (False)?
 
@@ -1041,22 +1035,20 @@ cdef class SymbolTable(_MutableSymbolTable):
 
     Raises:
       FstIOError: Read failed.
-
-    See also: `SymbolTable.read`, `SymbolTable.read_text`.
     """
     cdef unique_ptr[fst.SymbolTable] syms
-    syms.reset(fst.FstReadSymbols(tostring(filename), input_table))
+    syms.reset(fst.FstReadSymbols(tostring(source), input_table))
     if syms.get() == NULL:
-      raise FstIOError("Read failed: {!r}".format(filename))
+      raise FstIOError("Read failed: {!r}".format(source))
     return _init_SymbolTable(syms.release())
 
 
 cdef _EncodeMapperSymbolTable _init_EncodeMapperSymbolTable(
-    fst.SymbolTable *table, shared_ptr[fst.EncodeMapperClass] encoder):
+    fst.SymbolTable *table, shared_ptr[fst.EncodeMapperClass] mapper):
   cdef _EncodeMapperSymbolTable result = (
       _EncodeMapperSymbolTable.__new__(_EncodeMapperSymbolTable))
   result._table = table
-  result._encoder = encoder
+  result._mapper = mapper
   return result
 
 
@@ -1132,8 +1124,6 @@ cpdef SymbolTable merge_symbol_table(_SymbolTable lhs, _SymbolTable rhs):
 
   Returns:
     A new merged SymbolTable.
-
-  See also: `relabel_symbols`.
   """
   return _init_SymbolTable(fst.MergeSymbolTable(deref(lhs._table),
                                                 deref(rhs._table), NULL))
@@ -1229,7 +1219,7 @@ cdef class EncodeMapper(object):
   """
   EncodeMapper(arc_type="standard", encode_labels=False, encode_weights=False)
 
-  Arc encoder class, wrapping EncodeMapperClass.
+  Arc mapper class, wrapping EncodeMapperClass.
 
   This class provides an object which can be used to encode or decode FST arcs.
   This is most useful to convert an FST to an unweighted acceptor, on which
@@ -1238,7 +1228,7 @@ cdef class EncodeMapper(object):
   To use an instance of this class to encode or decode a mutable FST, pass it
   as the first argument to the FST instance methods `encode` and `decode`.
 
-  For implementational reasons, it is not currently possible to use an encoder
+  For implementational reasons, it is not currently possible to use an mapper
   on disk to construct this class.
 
   Args:
@@ -1254,27 +1244,19 @@ cdef class EncodeMapper(object):
                arc_type=b"standard",
                bool encode_labels=False,
                bool encode_weights=False):
-    cdef uint32 flags = fst.GetEncodeFlags(encode_labels, encode_weights)
-    self._encoder.reset(new fst.EncodeMapperClass(tostring(arc_type), flags,
+    cdef uint8 flags = fst.GetEncodeFlags(encode_labels, encode_weights)
+    self._mapper.reset(new fst.EncodeMapperClass(tostring(arc_type), flags,
                                                   fst.ENCODE))
-    if not self._encoder:
+    if not self._mapper:
       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().
 
   def __call__(self, Arc arc):
     """
     self(state, ilabel, olabel, weight, nextstate)
 
-    Uses the encoder to encode an arc.
+    Uses the mapper to encode an arc.
 
     Args:
       ilabel: The integer index of the input label.
@@ -1286,39 +1268,36 @@ cdef class EncodeMapper(object):
     Raises:
       FstOpError: Incompatible or invalid weight.
     """
-    return _init_Arc(self._encoder.get().__call__(deref(arc._arc)))
+    return _init_Arc(self._mapper.get().__call__(deref(arc._arc)))
 
-  cpdef uint32 flags(self):
+  # Registers the class for pickling.
+
+  def __reduce__(self):
+      return (_read_EncodeMapper_from_string, (self.write_to_string(),))
+
+  cpdef string arc_type(self):
     """
-    flags(self)
+    arc_type(self)
 
-    Returns the encoder's flags.
+    Returns a string indicating the arc type.
     """
-    return self._encoder.get().Flags()
+    return self._mapper.get().ArcType()
 
-  cpdef _EncodeMapperSymbolTable input_symbols(self):
+  cpdef string weight_type(self):
     """
-    input_symbols(self)
+    weight_type(self)
 
-    Returns the encoder's input symbol table, or None if none is present.
+    Returns a string indicating the weight type.
     """
-    cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
-        self._encoder.get().InputSymbols())
-    if syms == NULL:
-      return
-    return _init_EncodeMapperSymbolTable(syms, self._encoder)
+    return self._mapper.get().WeightType()
 
-  cpdef _EncodeMapperSymbolTable output_symbols(self):
+  cpdef uint8 flags(self):
     """
-    output_symbols(self)
+    flags(self)
 
-    Returns the encoder's output symbol table, or None if none is present.
+    Returns the mapper's flags.
     """
-    cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
-        self._encoder.get().OutputSymbols())
-    if syms == NULL:
-      return
-    return _init_EncodeMapperSymbolTable(syms, self._encoder)
+    return self._mapper.get().Flags()
 
   cpdef uint64 properties(self, uint64 mask):
     """
@@ -1326,49 +1305,150 @@ cdef class EncodeMapper(object):
 
     Provides property bits.
 
-    This method provides user access to the properties of the encoder.
+    This method provides user access to the properties of the mapper.
 
     Args:
-      mask: The property mask to be compared to the encoder's properties.
+      mask: The property mask to be compared to the mapper's properties.
 
     Returns:
       A 64-bit bitmask representing the requested properties.
     """
-    return self._encoder.get().Properties(mask)
+    return self._mapper.get().Properties(mask)
+
+  @classmethod
+  def read(cls, source):
+    """
+    EncodeMapper.read(source)
+
+    Reads encode mapper from binary file.
+
+    This class method creates a new EncodeMapper from an encode mapper binary
+    file.
+
+    Args:
+      source: The string location of the input binary file.
+
+    Returns:
+      A new EncodeMapper instance.
+    """
+    cdef unique_ptr[fst.EncodeMapperClass] mapper
+    mapper.reset(fst.EncodeMapperClass.Read(tostring(source)))
+    if mapper.get() == NULL:
+      raise FstIOError("Read failed: {!r}".format(source))
+    return _init_EncodeMapper(mapper.release())
+
+  @staticmethod
+  def read_from_string(state):
+    """
+    read_from_string(state)
+
+    Reads an EncodeMapper from a serialized string.
+
+    Args:
+      state: A string containing the serialized EncodeMapper.
+
+    Returns:
+      An EncodeMapper object.
+
+    Raises:
+      FstIOError: Read failed.
+    """
+    return _read_EncodeMapper_from_string(state)
+
+  cpdef void write(self, source) except *:
+      """
+      write(self, source)
+
+      Serializes mapper to a file.
+
+      This method writes the mapper to a file in a binary format.
+
+      Args:
+        source: The string location of the output file.
+      Raises:
+        FstIOError: Write failed.
+      """
+      if not self._mapper.get().Write(tostring(source)):
+        raise FstIOError("Write failed: {!r}".format(source))
+
+  cpdef bytes write_to_string(self):
+      """
+      write_to_string(self)
+
+      Serializes mapper to a string.
+
+      Returns:
+        A bytestring.
+
+      Raises:
+        FstIOError: Write to string failed.
+      """
+      cdef stringstream sstrm
+      if not self._mapper.get().WriteStream(sstrm, b"<pywrapfst>"):
+        raise FstIOError("Write to string failed")
+      return sstrm.str()
+
+  cpdef _EncodeMapperSymbolTable input_symbols(self):
+    """
+    input_symbols(self)
+
+    Returns the mapper's input symbol table, or None if none is present.
+    """
+    cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
+        self._mapper.get().InputSymbols())
+    if syms == NULL:
+      return
+    return _init_EncodeMapperSymbolTable(syms, self._mapper)
+
+  cpdef _EncodeMapperSymbolTable output_symbols(self):
+    """
+    output_symbols(self)
+
+    Returns the mapper's output symbol table, or None if none is present.
+    """
+    cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
+        self._mapper.get().OutputSymbols())
+    if syms == NULL:
+      return
+    return _init_EncodeMapperSymbolTable(syms, self._mapper)
 
   cpdef void set_input_symbols(self, _SymbolTable syms) except *:
     """
     set_input_symbols(self, syms)
 
-    Sets the encoder's input symbol table.
+    Sets the mapper's input symbol table.
 
     Args:
       syms: A SymbolTable.
-
-    See also: `set_output_symbols`.
     """
-    self._encoder.get().SetInputSymbols(syms._table)
+    self._mapper.get().SetInputSymbols(syms._table)
 
   cpdef void set_output_symbols(self, _SymbolTable syms) except *:
     """
     set_output_symbols(self, syms)
 
-    Sets the encoder's output symbol table.
+    Sets the mapper's output symbol table.
 
     Args:
       syms: A SymbolTable.
-
-    See also: `set_input_symbols`.
     """
-    self._encoder.get().SetOutputSymbols(syms._table)
+    self._mapper.get().SetOutputSymbols(syms._table)
 
-  cpdef string weight_type(self):
-    """
-    weight_type(self)
 
-    Returns a string indicating the weight type.
-    """
-    return self._encoder.get().WeightType()
+cdef EncodeMapper _init_EncodeMapper(fst.EncodeMapperClass *mapper):
+  cdef EncodeMapper result = EncodeMapper.__new__(EncodeMapper)
+  result._mapper.reset(mapper)
+  return result
+
+
+cpdef EncodeMapper _read_EncodeMapper_from_string(state):
+  cdef stringstream sstrm
+  sstrm << tostring(state)
+  cdef unique_ptr[fst.EncodeMapperClass] mapper
+  mapper.reset(fst.EncodeMapperClass.ReadStream(sstrm, b"<pywrapfst>"))
+  if mapper.get() == NULL:
+    raise FstIOError("Read failed")
+  return _init_EncodeMapper(mapper.release())
 
 
 ## _Fst, _MutableFst, Fst, and helpers.
@@ -1377,7 +1457,7 @@ cdef class EncodeMapper(object):
 #
 # _Fst: base class; has-a FstClass*.
 # _MutableFst(_Fst): adds mutable methods.
-# Fst(filename): pseudo-constructor.
+# Fst(source): pseudo-constructor.
 
 
 cdef class _Fst(object):
@@ -1420,16 +1500,14 @@ cdef class _Fst(object):
     This method produces an SVG of the internal graph. Users wishing to create
     publication-quality graphs should instead use the method `draw`, which
     exposes additional parameters.
-
-    See also: `draw`, `text`.
     """
     cdef stringstream sstrm
     cdef bool acceptor = (self._fst.get().Properties(fst.kAcceptor, True) ==
                           fst.kAcceptor)
-    fst.DrawFst(deref(self._fst), self._fst.get().InputSymbols(),
-                self._fst.get().OutputSymbols(), NULL, acceptor,
-                b"", 8.5, 11, True, False, 0.4, 0.25, 14, 5, b"g", False,
-                addr(sstrm), b"<pywrapfst>")
+    fst.Draw(deref(self._fst), self._fst.get().InputSymbols(),
+             self._fst.get().OutputSymbols(), NULL, acceptor, b"", 8.5, 11,
+             True, False, 0.4, 0.25, 14, 5, b"g", False, sstrm,
+             b"<pywrapfst>")
     # Google-only...
     try:
       return _Fst._server_render_svg(sstrm.str())
@@ -1477,8 +1555,6 @@ cdef class _Fst(object):
 
     Returns:
       An ArcIterator.
-
-    See also: `mutable_arcs`, `states`.
     """
     return ArcIterator(self, state)
 
@@ -1491,10 +1567,10 @@ cdef class _Fst(object):
     return _init_XFst(new fst.FstClass(deref(self._fst)))
 
   cpdef void draw(self,
-                  filename,
+                  source,
                   _SymbolTable isymbols=None,
                   _SymbolTable osymbols=None,
-                  SymbolTable ssymbols=None,
+                  _SymbolTable ssymbols=None,
                   bool acceptor=False,
                   title=b"",
                   double width=8.5,
@@ -1508,7 +1584,7 @@ cdef class _Fst(object):
                   float_format=b"g",
                   bool show_weight_one=False):
     """
-    draw(self, filename, isymbols=None, osymbols=None, ssymbols=None,
+    draw(self, source, isymbols=None, osymbols=None, ssymbols=None,
          acceptor=False, title="", width=8.5, height=11, portrait=False,
          vertical=False, ranksep=0.4, nodesep=0.25, fontsize=14,
          precision=5, float_format="g", show_weight_one=False):
@@ -1519,7 +1595,7 @@ cdef class _Fst(object):
     graph can be rendered using the `dot` executable provided by Graphviz.
 
     Args:
-      filename: The string location of the output dot/Graphviz file.
+      source: The string location of the output dot/Graphviz file.
       isymbols: An optional symbol table used to label input symbols.
       osymbols: An optional symbol table used to label output symbols.
       ssymbols: An optional symbol table used to label states.
@@ -1537,24 +1613,37 @@ cdef class _Fst(object):
       precision: Numeric precision for floats, in number of chars.
       float_format: One of: 'e', 'f' or 'g'.
       show_weight_one: Should weights equivalent to semiring One be printed?
-
-    See also: `text`.
     """
-    cdef string filename_string = tostring(filename)
-    cdef unique_ptr[ofstream] ostrm
-    ostrm.reset(new ofstream(filename_string))
-    cdef fst.SymbolTable *ssymbols_ptr = NULL
+    cdef string source_string = tostring(source)
+    cdef unique_ptr[ostream] fstrm
+    fstrm.reset(new ofstream(source_string))
+    cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
+    if isymbols is not None:
+       _isymbols = isymbols._table
+    cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
+    if osymbols is not None:
+       _osymbols = osymbols._table
+    cdef fst.SymbolTable *_ssymbols = NULL
     if ssymbols is not None:
-      ssymbols_ptr = ssymbols._table
-    fst.DrawFst(deref(self._fst),
-        self._fst.get().InputSymbols() if isymbols is None
-        else isymbols._table,
-        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(),
-        filename_string)
+      _ssymbols = ssymbols._table
+    fst.Draw(deref(self._fst),
+        _isymbols,
+        _osymbols,
+        _ssymbols,
+        acceptor,
+        tostring(title),
+        width,
+        height,
+        portrait,
+        vertical,
+        ranksep,
+        nodesep,
+        fontsize,
+        precision,
+        tostring(float_format),
+        show_weight_one,
+        deref(fstrm),
+        source_string)
 
   cpdef Weight final(self, int64 state):
     """
@@ -1590,8 +1679,6 @@ cdef class _Fst(object):
     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())
@@ -1613,8 +1700,6 @@ cdef class _Fst(object):
 
     Raises:
       FstIndexError: State index out of range.
-
-    See also: `num_states`.
     """
     cdef size_t result = self._fst.get().NumArcs(state)
     if result == SIZE_MAX:
@@ -1635,8 +1720,6 @@ cdef class _Fst(object):
 
     Raises:
       FstIndexError: State index out of range.
-
-    See also: `num_output_epsilons`.
     """
     cdef size_t result = self._fst.get().NumInputEpsilons(state)
     if result == SIZE_MAX:
@@ -1657,8 +1740,6 @@ cdef class _Fst(object):
 
     Raises:
       FstIndexError: State index out of range.
-
-    See also: `num_input_epsilons`.
     """
     cdef size_t result = self._fst.get().NumOutputEpsilons(state)
     if result == SIZE_MAX:
@@ -1670,8 +1751,6 @@ cdef class _Fst(object):
     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())
@@ -1715,8 +1794,6 @@ cdef class _Fst(object):
 
     Returns:
       A StateIterator object for the FST.
-
-    See also: `arcs`, `mutable_arcs`.
     """
     return StateIterator(self)
 
@@ -1745,16 +1822,27 @@ cdef class _Fst(object):
       A formatted string representing the machine.
     """
     # Prints FST to stringstream, then returns resulting string.
-    cdef fst.SymbolTable *ssymbols_ptr = NULL
+    cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
+    if isymbols is not None:
+       _isymbols = isymbols._table
+    cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
+    if osymbols is not None:
+       _osymbols = osymbols._table
+    cdef fst.SymbolTable *_ssymbols = NULL
+    if ssymbols is not None:
+      _ssymbols = ssymbols._table
     if ssymbols is not None:
-      ssymbols_ptr = ssymbols._table
+      _ssymbols = ssymbols._table
     cdef stringstream sstrm
-    fst.PrintFst(deref(self._fst), sstrm, b"<pywrapfst>",
-        self._fst.get().InputSymbols() if isymbols is None
-        else isymbols._table,
-        self._fst.get().OutputSymbols() if osymbols is None
-        else osymbols._table,
-        ssymbols_ptr, acceptor, show_weight_one, tostring(missing_sym))
+    fst.Print(deref(self._fst),
+              sstrm,
+              b"<pywrapfst>",
+              _isymbols,
+              _osymbols,
+              _ssymbols,
+              acceptor,
+              show_weight_one,
+              tostring(missing_sym))
     return sstrm.str()
 
   cpdef bool verify(self):
@@ -1779,22 +1867,22 @@ cdef class _Fst(object):
     """
     return self._fst.get().WeightType()
 
-  cpdef void write(self, filename) except *:
+  cpdef void write(self, source) except *:
     """
-    write(self, filename)
+    write(self, source)
 
     Serializes FST to a file.
 
     This method writes the FST to a file in a binary format.
 
     Args:
-      filename: The string location of the output file.
+      source: The string location of the output file.
 
     Raises:
       FstIOError: Write failed.
     """
-    if not self._fst.get().Write(tostring(filename)):
-      raise FstIOError("Write failed: {!r}".format(filename))
+    if not self._fst.get().Write(tostring(source)):
+      raise FstIOError("Write failed: {!r}".format(source))
 
   cpdef bytes write_to_string(self):
     """
@@ -1807,8 +1895,6 @@ cdef class _Fst(object):
 
     Raises:
       FstIOError: Write to string failed.
-
-    See also: `read_from_string`.
     """
     cdef stringstream sstrm
     if not self._fst.get().Write(sstrm, b"<pywrapfst>"):
@@ -1857,8 +1943,6 @@ cdef class _MutableFst(_Fst):
     Raises:
       FstIndexError: State index out of range.
       FstOpdexError: Incompatible or invalid weight type.
-
-    See also: `add_state`.
     """
     self._add_arc(state, arc)
     return self
@@ -1871,8 +1955,6 @@ cdef class _MutableFst(_Fst):
 
     Returns:
       The integer index of the new state.
-
-    See also: `add_arc`, `set_start`, `set_final`.
     """
     cdef int64 result = self._mfst.get().AddState()
     self._check_mutating_imethod()
@@ -1944,13 +2026,13 @@ cdef class _MutableFst(_Fst):
     self._closure(closure_plus)
     return self
 
-  cdef void _concat(self, _Fst ifst) except *:
-    fst.Concat(self._mfst.get(), deref(ifst._fst))
+  cdef void _concat(self, _Fst fst2) except *:
+    fst.Concat(self._mfst.get(), deref(fst2._fst))
     self._check_mutating_imethod()
 
-  def concat(self, _Fst ifst):
+  def concat(self, _Fst fst2):
     """
-    concat(self, ifst)
+    concat(self, fst2)
 
     Computes the concatenation (product) of two FSTs.
 
@@ -1960,12 +2042,12 @@ cdef class _MutableFst(_Fst):
     \otimes b.
 
     Args:
-      ifst: The second input FST.
+      fst2: The second input FST.
 
     Returns:
       self.
     """
-    self._concat(ifst)
+    self._concat(fst2)
     return self
 
   cdef void _connect(self) except *:
@@ -1987,27 +2069,25 @@ cdef class _MutableFst(_Fst):
     self._connect()
     return self
 
-  cdef void _decode(self, EncodeMapper encoder) except *:
-    fst.Decode(self._mfst.get(), deref(encoder._encoder))
+  cdef void _decode(self, EncodeMapper mapper) except *:
+    fst.Decode(self._mfst.get(), deref(mapper._mapper))
     self._check_mutating_imethod()
 
-  def decode(self, EncodeMapper encoder):
+  def decode(self, EncodeMapper mapper):
     """
-    decode(self, encoder)
+    decode(self, mapper)
 
     Decodes encoded labels and/or weights.
 
     This operation reverses the encoding performed by `encode`.
 
     Args:
-      encoder: An EncodeMapper object used to encode the FST.
+      mapper: An EncodeMapper object used to encode the FST.
 
     Returns:
       self.
-
-    See also: `encode`.
     """
-    self._decode(encoder)
+    self._decode(mapper)
     return self
 
   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:
@@ -2033,8 +2113,6 @@ cdef class _MutableFst(_Fst):
 
     Raises:
       FstIndexError: State index out of range.
-
-    See also: `delete_states`.
     """
     self._delete_arcs(state, n)
     return self
@@ -2063,19 +2141,17 @@ cdef class _MutableFst(_Fst):
 
     Raises:
       FstIndexError: State index out of range.
-
-    See also: `delete_arcs`.
     """
     self._delete_states(states)
     return self
 
-  cdef void _encode(self, EncodeMapper encoder) except *:
-    fst.Encode(self._mfst.get(), encoder._encoder.get())
+  cdef void _encode(self, EncodeMapper mapper) except *:
+    fst.Encode(self._mfst.get(), mapper._mapper.get())
     self._check_mutating_imethod()
 
-  def encode(self, EncodeMapper encoder):
+  def encode(self, EncodeMapper mapper):
     """
-    encode(self, encoder)
+    encode(self, mapper)
 
     Encodes labels and/or weights.
 
@@ -2087,14 +2163,12 @@ cdef class _MutableFst(_Fst):
     can then be used to decode.
 
     Args:
-      encoder: An EncodeMapper object to be used as the encoder.
+      mapper: An EncodeMapper object to be used as the mapper.
 
     Returns:
       self.
-
-    See also: `decode`.
     """
-    self._encode(encoder)
+    self._encode(mapper)
     return self
 
   cdef void _invert(self) except *:
@@ -2162,8 +2236,6 @@ cdef class _MutableFst(_Fst):
 
     Returns:
       A MutableArcIterator.
-
-    See also: `arcs`, `states`.
     """
     return MutableArcIterator(self, state)
 
@@ -2216,8 +2288,6 @@ cdef class _MutableFst(_Fst):
 
     Returns:
       self.
-
-    See also: `decode`, `encode`, `relabel_pairs`, `relabel_symbols`.
     """
     self._project(project_output)
     return self
@@ -2252,14 +2322,12 @@ cdef class _MutableFst(_Fst):
 
     Returns:
       self.
-
-    See also: The constructive variant.
     """
     self._prune(delta, nstate, weight)
     return self
 
   cdef void _push(self,
-                  float delta=fst.kDelta,
+                  float delta=fst.kShortestDelta,
                   bool remove_total_weight=False,
                   bool to_final=False) except *:
     fst.Push(self._mfst.get(), fst.GetReweightType(to_final), delta,
@@ -2267,11 +2335,11 @@ cdef class _MutableFst(_Fst):
     self._check_mutating_imethod()
 
   def push(self,
-           float delta=fst.kDelta,
+           float delta=fst.kShortestDelta,
            bool remove_total_weight=False,
            bool to_final=False):
     """
-    push(self, delta=0.0009765625, remove_total_weight=False, to_final=False)
+    push(self, delta=1-e6, remove_total_weight=False, to_final=False)
 
     Pushes weights towards the initial or final states.
 
@@ -2292,8 +2360,6 @@ cdef class _MutableFst(_Fst):
 
     Returns:
       self.
-
-    See also: The constructive variant, which also supports label pushing.
     """
     self._push(delta, remove_total_weight, to_final)
     return self
@@ -2312,7 +2378,7 @@ cdef class _MutableFst(_Fst):
       for (before, after) in opairs:
         _opairs.get().push_back(fst.LabelPair(before, after))
     if _ipairs.get().empty() and _opairs.get().empty():
-      raise FstArgError("No relabeling pairs specified.")
+      raise FstArgError("No relabeling pairs specified")
     fst.Relabel(self._mfst.get(), deref(_ipairs), deref(_opairs))
     self._check_mutating_imethod()
 
@@ -2335,8 +2401,6 @@ cdef class _MutableFst(_Fst):
 
     Raises:
       FstArgError: No relabeling pairs specified.
-
-    See also: `decode`, `encode`, `project`, `relabel_tables`.
     """
     self._relabel_pairs(ipairs, opairs)
     return self
@@ -2352,18 +2416,26 @@ cdef class _MutableFst(_Fst):
                             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
+    cdef const fst.SymbolTable *_old_isymbols = self._fst.get().InputSymbols()
+    if old_isymbols is not None:
+      _old_isymbols = old_isymbols._table
+    cdef const fst.SymbolTable *_old_osymbols = self._fst.get().OutputSymbols()
+    if old_osymbols is not None:
+       _old_osymbols = old_osymbols._table
+    cdef const fst.SymbolTable *_new_isymbols = NULL
     if new_isymbols is not None:
-      new_isymbols_ptr = new_isymbols._table
-    cdef fst.SymbolTable *new_osymbols_ptr = NULL
+      _new_isymbols = new_isymbols._table
+    cdef const fst.SymbolTable *_new_osymbols = NULL
     if new_osymbols is not None:
-      new_osymbols_ptr = new_osymbols._table
+      _new_osymbols = new_osymbols._table
     fst.Relabel(self._mfst.get(),
-        self._fst.get().InputSymbols() if old_isymbols is None else
-        old_isymbols._table, new_isymbols_ptr, tostring(unknown_isymbol),
+        _old_isymbols,
+        _new_isymbols,
+        tostring(unknown_isymbol),
         attach_new_isymbols,
-        self._fst.get().OutputSymbols() if old_osymbols is None else
-        old_osymbols._table, new_osymbols_ptr, tostring(unknown_osymbol),
+        _old_osymbols,
+        _new_osymbols,
+        tostring(unknown_osymbol),
         attach_new_osymbols)
     self._check_mutating_imethod()
 
@@ -2408,13 +2480,15 @@ cdef class _MutableFst(_Fst):
 
     Raises:
       FstArgError: No SymbolTable specified.
-
-    See also: `decode`, `encode`, `project`, `relabel_pairs`.
     """
-    self._relabel_tables(old_isymbols, new_isymbols,
-                         unknown_isymbol, attach_new_isymbols,
-                         old_osymbols, new_osymbols,
-                         unknown_osymbol, attach_new_osymbols)
+    self._relabel_tables(old_isymbols,
+                         new_isymbols,
+                         unknown_isymbol,
+                         attach_new_isymbols,
+                         old_osymbols,
+                         new_osymbols,
+                         unknown_osymbol,
+                         attach_new_osymbols)
     return self
 
   cdef void _reserve_arcs(self, int64 state, size_t n) except *:
@@ -2437,8 +2511,6 @@ cdef class _MutableFst(_Fst):
 
     Raises:
       FstIndexError: State index out of range.
-
-    See also: `reserve_states`.
     """
     self._reserve_arcs(state, n)
     return self
@@ -2458,8 +2530,6 @@ cdef class _MutableFst(_Fst):
 
     Returns:
       self.
-
-    See also: `reserve_arcs`.
     """
     self._reserve_states(n)
     return self
@@ -2510,7 +2580,10 @@ cdef class _MutableFst(_Fst):
                                                        weight)
     cdef unique_ptr[fst.RmEpsilonOptions] opts
     opts.reset(new fst.RmEpsilonOptions(_get_queue_type(tostring(queue_type)),
-                                        connect, wc, nstate, delta))
+                                        connect,
+                                        wc,
+                                        nstate,
+                                        delta))
     fst.RmEpsilon(self._mfst.get(), deref(opts))
     self._check_mutating_imethod()
 
@@ -2570,8 +2643,6 @@ cdef class _MutableFst(_Fst):
     Raises:
       FstIndexError: State index out of range.
       FstOpError: Incompatible or invalid weight.
-
-    See also: `set_start`.
     """
     self._set_final(state, weight)
     return self
@@ -2596,8 +2667,6 @@ cdef class _MutableFst(_Fst):
 
     Returns:
       self.
-
-    See also: `set_output_symbols`.
     """
     self._set_input_symbols(syms)
     return self
@@ -2622,8 +2691,6 @@ cdef class _MutableFst(_Fst):
 
     Returns:
       self.
-
-    See also: `set_input_symbols`.
     """
     self._set_output_symbols(syms)
     return self
@@ -2667,8 +2734,6 @@ cdef class _MutableFst(_Fst):
 
     Raises:
       FstIndexError: State index out of range.
-
-    See also: `set_final`.
     """
     self._set_start(state)
     return self
@@ -2695,27 +2760,28 @@ cdef class _MutableFst(_Fst):
     self._topsort()
     return self
 
-  cdef void _union(self, _Fst ifst) except *:
-    fst.Union(self._mfst.get(), deref(ifst._fst))
-    self._check_mutating_imethod()
-
-  def union(self, _Fst ifst):
+  def union(self, *fsts2):
     """
-    union(self, ifst)
+    union(self, *fsts2)
 
-    Computes the union (sum) of two FSTs.
+    Computes the union (sum) of two or more FSTs.
 
-    This operation computes the union (sum) of two FSTs. If A transduces string
-    x to y with weight a and B transduces string w to v with weight b, then
-    their union transduces x to y with weight a and w to v with weight b.
+    This operation computes the union of two or more FSTs. If A transduces
+    string x to y with weight a and B transduces string w to v with weight b,
+    then their union transduces x to y with weight a and w to v with weight b.
 
     Args:
-      ifst: The second input FST.
+      *fsts2: One or more input FSTs.
 
     Returns:
       self.
     """
-    self._union(ifst)
+    cdef vector[const_FstClass_ptr] _fsts2
+    cdef _Fst fst2
+    for fst2 in fsts2:
+      _fsts2.push_back(fst2._fst.get())
+    fst.Union(self._mfst.get(), _fsts2)
+    self._check_mutating_imethod()
     return self
 
 
@@ -2774,11 +2840,11 @@ cdef _MutableFst _create_Fst(arc_type=b"standard"):
   return _init_MutableFst(tfst.release())
 
 
-cpdef _Fst _read(filename):
+cpdef _Fst _read(source):
   cdef unique_ptr[fst.FstClass] tfst
-  tfst.reset(fst.FstClass.Read(tostring(filename)))
+  tfst.reset(fst.FstClass.Read(tostring(source)))
   if tfst.get() == NULL:
-    raise FstIOError("Read failed: {!r}".format(filename))
+    raise FstIOError("Read failed: {!r}".format(source))
   return _init_XFst(tfst.release())
 
 
@@ -2813,14 +2879,14 @@ class Fst(object):
     return _create_Fst(arc_type)
 
    @staticmethod
-   def read(filename):
+   def read(source):
      """
-     read(filename):
+     read(source)
 
      Reads an FST from a file.
 
      Args:
-       filename: The string location of the input file.
+       source: The string location of the input file.
 
      Returns:
        An FST object.
@@ -2828,12 +2894,12 @@ class Fst(object):
      Raises:
        FstIOError: Read failed.
      """
-     return _read(filename)
+     return _read(source)
 
    @staticmethod
    def read_from_string(state):
      """
-     read_from_string(string, fst_type=None)
+     read_from_string(state)
 
      Reads an FST from a serialized string.
 
@@ -2845,9 +2911,6 @@ class Fst(object):
 
      Raises:
        FstIOError: Read failed.
-       FstOpError: Read-time conversion failed.
-
-     See also: `write_to_string`.
      """
      return _read_Fst_from_string(state)
 
@@ -3054,7 +3117,7 @@ cdef class ArcIterator(object):
     """
     return self._aiter.get().Done()
 
-  cpdef uint32 flags(self):
+  cpdef uint8 flags(self):
     """
     flags(self)
 
@@ -3103,7 +3166,7 @@ cdef class ArcIterator(object):
     """
     self._aiter.get().Seek(a)
 
-  cpdef void set_flags(self, uint32 flags, uint32 mask):
+  cpdef void set_flags(self, uint8 flags, uint8 mask):
     """
     set_flags(self, flags, mask)
 
@@ -3160,7 +3223,7 @@ cdef class MutableArcIterator(object):
     """
     return self._aiter.get().Done()
 
-  cpdef uint32 flags(self):
+  cpdef uint8 flags(self):
     """
     flags(self)
 
@@ -3209,7 +3272,7 @@ cdef class MutableArcIterator(object):
     """
     self._aiter.get().Seek(a)
 
-  cpdef void set_flags(self, uint32 flags, uint32 mask):
+  cpdef void set_flags(self, uint8 flags, uint8 mask):
     """
     set_flags(self, flags, mask)
 
@@ -3319,9 +3382,11 @@ cdef _Fst _map(_Fst ifst,
   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
-      _get_WeightClass_or_Zero(ifst.weight_type(), weight))
+  cdef fst.WeightClass wc
+  if map_type_enum == fst.TIMES_MAPPER:
+      wc = _get_WeightClass_or_One(ifst.weight_type(), weight)
+  else:
+      wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)
   return _init_XFst(fst.Map(deref(ifst._fst), map_type_enum, delta, power, wc))
 
 
@@ -3369,8 +3434,6 @@ cpdef _Fst arcmap(_Fst ifst,
 
   Raises:
     FstArgError: Unknown map type.
-
-  See also: `statemap`.
   """
   return _map(ifst, delta, map_type, power, weight)
 
@@ -3400,13 +3463,12 @@ cpdef _MutableFst compose(_Fst ifst1,
 
   Returns:
     An FST.
-
-  See also: `arcsort`.
   """
   cdef unique_ptr[fst.VectorFstClass] tfst
   tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))
   cdef unique_ptr[fst.ComposeOptions] opts
-  opts.reset(new fst.ComposeOptions(connect,
+  opts.reset(new fst.ComposeOptions(
+      connect,
       _get_compose_filter(tostring(compose_filter))))
   fst.Compose(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))
   return _init_MutableFst(tfst.release())
@@ -3476,8 +3538,6 @@ cpdef _MutableFst determinize(_Fst ifst,
 
   Raises:
     FstArgError: Unknown determinization type.
-
-  See also: `disambiguate`, `rmepsilon`.
   """
   cdef unique_ptr[fst.VectorFstClass] tfst
   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
@@ -3489,7 +3549,10 @@ cpdef _MutableFst determinize(_Fst ifst,
                                 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,
+  opts.reset(new fst.DeterminizeOptions(delta,
+                                        wc,
+                                        nstate,
+                                        subsequential_label,
                                         determinize_type_enum,
                                         increment_subsequential_label))
   fst.Determinize(deref(ifst._fst), tfst.get(), deref(opts))
@@ -3526,8 +3589,9 @@ cpdef _MutableFst difference(_Fst ifst1,
   cdef unique_ptr[fst.VectorFstClass] tfst
   tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))
   cdef unique_ptr[fst.ComposeOptions] opts
-  opts.reset(new fst.ComposeOptions(connect, _get_compose_filter(
-      tostring(compose_filter))))
+  opts.reset(new fst.ComposeOptions(
+      connect,
+      _get_compose_filter(tostring(compose_filter))))
   fst.Difference(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))
   return _init_MutableFst(tfst.release())
 
@@ -3559,8 +3623,6 @@ cpdef _MutableFst disambiguate(_Fst ifst,
 
   Returns:
     An equivalent disambiguated FST.
-
-  See also: `determinize`, `rmepsilon`.
   """
   cdef unique_ptr[fst.VectorFstClass] tfst
   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
@@ -3568,7 +3630,9 @@ cpdef _MutableFst disambiguate(_Fst ifst,
   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,
+  opts.reset(new fst.DisambiguateOptions(delta,
+                                         wc,
+                                         nstate,
                                          subsequential_label))
   fst.Disambiguate(deref(ifst._fst), tfst.get(), deref(opts))
   return _init_MutableFst(tfst.release())
@@ -3593,14 +3657,13 @@ cpdef _MutableFst epsnormalize(_Fst ifst, bool eps_norm_output=False):
 
   Returns:
     An equivalent epsilon-normalized FST.
-
-  See also: `rmepsilon`.
   """
   cdef unique_ptr[fst.VectorFstClass] tfst
   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
-  fst.EpsNormalize(deref(ifst._fst), tfst.get(), fst.EPS_NORM_OUTPUT if
-                                                 eps_norm_output else
-                                                 fst.EPS_NORM_INPUT)
+  fst.EpsNormalize(
+      deref(ifst._fst),
+      tfst.get(),
+      fst.EPS_NORM_OUTPUT if eps_norm_output else fst.EPS_NORM_INPUT)
   return _init_MutableFst(tfst.release())
 
 
@@ -3621,8 +3684,6 @@ cpdef bool equal(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):
 
   Returns:
     True if the FSTs satisfy the above condition, else False.
-
-  See also: `equivalent`, `isomorphic`, `randequivalent`.
   """
   return fst.Equal(deref(ifst1._fst), deref(ifst2._fst), delta)
 
@@ -3644,8 +3705,6 @@ cpdef bool equivalent(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta) except *:
 
   Returns:
     True if the FSTs satisfy the above condition, else False.
-
-  See also: `equal`, `isomorphic`, `randequivalent`.
   """
   return fst.Equivalent(deref(ifst1._fst), deref(ifst2._fst), delta)
 
@@ -3678,8 +3737,9 @@ cpdef _MutableFst intersect(_Fst ifst1,
   cdef unique_ptr[fst.VectorFstClass] tfst
   tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))
   cdef unique_ptr[fst.ComposeOptions] opts
-  opts.reset(new fst.ComposeOptions(connect,
-        _get_compose_filter(tostring(compose_filter))))
+  opts.reset(new fst.ComposeOptions(
+      connect,
+      _get_compose_filter(tostring(compose_filter))))
   fst.Intersect(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))
   return _init_MutableFst(tfst.release())
 
@@ -3704,8 +3764,6 @@ cpdef bool isomorphic(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):
 
   Returns:
     True if the two transducers satisfy the above condition, else False.
-
-  See also: `equal`, `equivalent`, `randequivalent`.
   """
   return fst.Isomorphic(deref(ifst1._fst), deref(ifst2._fst), delta)
 
@@ -3733,8 +3791,6 @@ cpdef _MutableFst prune(_Fst ifst,
 
   Returns:
     A pruned FST.
-
-  See also: The destructive variant.
   """
   cdef unique_ptr[fst.VectorFstClass] tfst
   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
@@ -3784,15 +3840,18 @@ cpdef _MutableFst push(_Fst ifst,
 
   Returns:
     An equivalent pushed FST.
-
-  See also: The destructive variant.
   """
   # This is copied, almost verbatim, from ./fstpush.cc.
   cdef unique_ptr[fst.VectorFstClass] tfst
   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
-  cdef uint32 flags = fst.GetPushFlags(push_weights, push_labels,
-                                       remove_common_affix, remove_total_weight)
-  fst.Push(deref(ifst._fst), tfst.get(), flags, fst.GetReweightType(to_final),
+  cdef uint8 flags = fst.GetPushFlags(push_weights,
+                                      push_labels,
+                                      remove_common_affix,
+                                      remove_total_weight)
+  fst.Push(deref(ifst._fst),
+           tfst.get(),
+           flags,
+           fst.GetReweightType(to_final),
            delta)
   return _init_MutableFst(tfst.release())
 
@@ -3829,18 +3888,23 @@ cpdef bool randequivalent(_Fst ifst1,
 
   Returns:
     True if the two transducers satisfy the above condition, else False.
-
-  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.
-  opts.reset(new fst.RandGenOptions[fst.RandArcSelection](ras, max_length,
-                                                          1, False, False))
+  opts.reset(new fst.RandGenOptions[fst.RandArcSelection](ras,
+                                                          max_length,
+                                                          1,
+                                                          False,
+                                                          False))
   if seed == 0:
     seed = time(NULL) + getpid()
-  return fst.RandEquivalent(deref(ifst1._fst), deref(ifst2._fst), npath, delta,
-                           seed, deref(opts))
+  return fst.RandEquivalent(deref(ifst1._fst),
+                            deref(ifst2._fst),
+                            npath,
+                            delta,
+                            seed,
+                            deref(opts))
 
 
 cpdef _MutableFst randgen(_Fst ifst,
@@ -3878,13 +3942,13 @@ cpdef _MutableFst randgen(_Fst ifst,
 
   Returns:
     An FST containing one or more random paths.
-
-  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,
-                                                          npath, weighted,
+  opts.reset(new fst.RandGenOptions[fst.RandArcSelection](ras,
+                                                          max_length,
+                                                          npath,
+                                                          weighted,
                                                           remove_total_weight))
   cdef unique_ptr[fst.VectorFstClass] tfst
   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
@@ -3936,22 +4000,20 @@ cpdef _MutableFst replace(pairs,
     An FST resulting from expanding the input RTN.
   """
   cdef vector[fst.LabelFstClassPair] _pairs
-  cdef int64 root_label
   cdef int64 label
-  cdef _Fst ifst
-  it = iter(pairs)
-  (root_label, ifst) = next(it)
-  _pairs.push_back(fst.LabelFstClassPair(root_label, ifst._fst.get()))
+  cdef _Fst pfst
+  for (label, pfst) in pairs:
+    _pairs.push_back(fst.LabelFstClassPair(label, pfst._fst.get()))
   cdef unique_ptr[fst.VectorFstClass] tfst
-  tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
-  for (label, ifst) in it:
-    _pairs.push_back(fst.LabelFstClassPair(label, ifst._fst.get()))
+  tfst.reset(new fst.VectorFstClass(_pairs[0].second.ArcType()))
   cdef fst.ReplaceLabelType cal = _get_replace_label_type(
-      tostring(call_arc_labeling), epsilon_on_replace)
+      tostring(call_arc_labeling),
+      epsilon_on_replace)
   cdef fst.ReplaceLabelType ral = _get_replace_label_type(
-      tostring(return_arc_labeling), epsilon_on_replace)
+      tostring(return_arc_labeling),
+      epsilon_on_replace)
   cdef unique_ptr[fst.ReplaceOptions] opts
-  opts.reset(new fst.ReplaceOptions(root_label, cal, ral, return_label))
+  opts.reset(new fst.ReplaceOptions(_pairs[0].first, cal, ral, return_label))
   fst.Replace(_pairs, tfst.get(), deref(opts))
   return _init_MutableFst(tfst.release())
 
@@ -4000,7 +4062,9 @@ cdef vector[fst.WeightClass] *_shortestdistance(_Fst ifst,
     fst.ShortestDistance(deref(ifst._fst), distance.get(), True, delta)
   else:
     opts.reset(new fst.ShortestDistanceOptions(
-        _get_queue_type(tostring(queue_type)), fst.ANY_ARC_FILTER, nstate,
+        _get_queue_type(tostring(queue_type)),
+        fst.ANY_ARC_FILTER,
+        nstate,
         delta))
     fst.ShortestDistance(deref(ifst._fst), distance.get(), deref(opts))
   return distance.release()
@@ -4086,7 +4150,11 @@ cpdef _MutableFst shortestpath(_Fst ifst,
   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)
   cdef unique_ptr[fst.ShortestPathOptions] opts
   opts.reset(new fst.ShortestPathOptions(_get_queue_type(tostring(queue_type)),
-                                         nshortest, unique, delta, wc, nstate))
+                                         nshortest,
+                                         unique,
+                                         delta,
+                                         wc,
+                                         nstate))
   fst.ShortestPath(deref(ifst._fst), tfst.get(), deref(opts))
   return _init_MutableFst(tfst.release())
 
@@ -4113,8 +4181,6 @@ cpdef _Fst statemap(_Fst ifst, map_type):
 
   Raises:
     FstArgError: Unknown map type.
-
-  See also: `arcmap`.
   """
   return _map(ifst, fst.kDelta, map_type, 1., None)
 
@@ -4243,10 +4309,17 @@ cdef class Compiler(object):
     """
     cdef unique_ptr[fst.FstClass] tfst
     tfst.reset(fst.CompileFstInternal(deref(self._sstrm),
-        b"<pywrapfst>", self._fst_type, self._arc_type, self._isymbols,
-        self._osymbols, self._ssymbols, self._acceptor, self._keep_isymbols,
-        self._keep_osymbols, self._keep_state_numbering,
-        self._allow_negative_labels))
+                                      b"<pywrapfst>",
+                                      self._fst_type,
+                                      self._arc_type,
+                                      self._isymbols,
+                                      self._osymbols,
+                                      self._ssymbols,
+                                      self._acceptor,
+                                      self._keep_isymbols,
+                                      self._keep_osymbols,
+                                      self._keep_state_numbering,
+                                      self._allow_negative_labels))
     self._sstrm.reset(new stringstream())
     if tfst.get() == NULL:
       raise FstOpError("Compilation failed")
@@ -4301,9 +4374,9 @@ cdef class FarReader(object):
     return "<{} FarReader at 0x{:x}>".format(self.far_type(), id(self))
 
   @classmethod
-  def open(cls, *filenames):
+  def open(cls, *sources):
     """
-    FarReader.open(*filenames)
+    FarReader.open(*sources)
 
     Creates a FarReader object.
 
@@ -4311,7 +4384,7 @@ cdef class FarReader(object):
     more FAR files on disk.
 
     Args:
-      *filenames: The string location of one or more input FAR files.
+      *sources: The string location of one or more input FAR files.
 
     Returns:
       A new FarReader instance.
@@ -4319,13 +4392,13 @@ cdef class FarReader(object):
     Raises:
       FstIOError: Read failed.
     """
-    cdef vector[string] filename_strings
-    for filename in filenames:
-      filename_strings.push_back(tostring(filename))
+    cdef vector[string] source_strings
+    for source in sources:
+      source_strings.push_back(tostring(source))
     cdef unique_ptr[fst.FarReaderClass] tfar
-    tfar.reset(fst.FarReaderClass.Open(filename_strings))
+    tfar.reset(fst.FarReaderClass.Open(source_strings))
     if tfar.get() == NULL:
-      raise FstIOError("Read failed: {!r}".format(filenames))
+      raise FstIOError("Read failed: {!r}".format(sources))
     cdef FarReader result = FarReader.__new__(FarReader)
     result._reader.reset(tfar.release())
     return result
@@ -4452,7 +4525,7 @@ cdef class FarWriter(object):
     return "<{} FarWriter at 0x{:x}>".format(self.far_type(), id(self))
 
   @classmethod
-  def create(cls, filename, arc_type=b"standard", far_type=b"default"):
+  def create(cls, source, arc_type=b"standard", far_type=b"default"):
     """
     FarWriter.
 
@@ -4462,7 +4535,7 @@ cdef class FarWriter(object):
     arc type, and FAR type.
 
     Args:
-      filename: The string location for the output FAR files.
+      source: The string location for the output FAR files.
       arc_type: A string indicating the arc type.
       far_type: A string indicating the FAR type; one of: "fst", "stlist",
           "sttable", "sstable", "default".
@@ -4475,9 +4548,11 @@ cdef class FarWriter(object):
     """
     cdef fst.FarType ft = fst.GetFarType(tostring(far_type))
     cdef fst.FarWriterClass *tfar = fst.FarWriterClass.Create(
-        tostring(filename), tostring(arc_type), ft)
+        tostring(source),
+        tostring(arc_type),
+        ft)
     if tfar == NULL:
-      raise FstIOError("Open failed: {!r}".format(filename))
+      raise FstIOError("Open failed: {!r}".format(source))
     cdef FarWriter result = FarWriter.__new__(FarWriter)
     result._writer.reset(tfar)
     return result
@@ -4543,5 +4618,6 @@ cdef class FarWriter(object):
   def __setitem__(self, key, _Fst fst):
     self.add(key, fst)
 
+
 # Masks fst_error_fatal in-module.
 fst.FLAGS_fst_error_fatal = False
index 29929b4..114067c 100644 (file)
@@ -1,13 +1,12 @@
 AM_CPPFLAGS = -I$(srcdir)/../../include -I$(srcdir)/../../bin $(ICU_CPPFLAGS)
+LIBS = ../../lib/libfst.la -lm $(DL_LIBS)
 
 if HAVE_BIN
 bin_PROGRAMS = fstspecial
 
-LDADD = ../../script/libfstscript.la \
-        ../../lib/libfst.la -lm $(DL_LIBS)
-
 fstspecial_SOURCES = fstspecial.cc phi-fst.cc rho-fst.cc sigma-fst.cc
 fstspecial_CPPFLAGS = $(AM_CPPFLAGS)
+fstspecial_LDADD = ../../script/libfstscript.la
 endif
 
 libfstdir = @libfstdir@
@@ -16,17 +15,13 @@ 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 17:0:0 -lm $(DL_LIBS)
-libfstspecial_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
+libfstspecial_la_LDFLAGS = -version-info 17:0:0
 
 phi_fst_la_SOURCES = phi-fst.cc
-phi_fst_la_LDFLAGS = -module
-phi_fst_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
+phi_fst_la_LDFLAGS = -avoid-version -module
 
 rho_fst_la_SOURCES = rho-fst.cc
-rho_fst_la_LDFLAGS = -module
-rho_fst_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
+rho_fst_la_LDFLAGS = -avoid-version -module
 
 sigma_fst_la_SOURCES = sigma-fst.cc
-sigma_fst_la_LDFLAGS = -module
-sigma_fst_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
+sigma_fst_la_LDFLAGS = -avoid-version -module
index 23a718f..72fbedf 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -92,7 +92,7 @@ host_triplet = @host@
 @HAVE_BIN_TRUE@bin_PROGRAMS = fstspecial$(EXEEXT)
 subdir = src/extensions/special
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_python_devel.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
        $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
@@ -104,6 +104,9 @@ CONFIG_HEADER = $(top_builddir)/config.h \
        $(top_builddir)/src/include/fst/config.h
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)" \
+       "$(DESTDIR)$(libfstdir)"
+PROGRAMS = $(bin_PROGRAMS)
 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
 am__vpath_adj = case $$p in \
     $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
@@ -131,12 +134,8 @@ am__uninstall_files_from_dir = { \
     || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
          $(am__cd) "$$dir" && rm -f $$files; }; \
   }
-am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libfstdir)" \
-       "$(DESTDIR)$(bindir)"
 LTLIBRARIES = $(lib_LTLIBRARIES) $(libfst_LTLIBRARIES)
-am__DEPENDENCIES_1 =
-libfstspecial_la_DEPENDENCIES = ../../lib/libfst.la \
-       $(am__DEPENDENCIES_1)
+libfstspecial_la_LIBADD =
 am_libfstspecial_la_OBJECTS = phi-fst.lo rho-fst.lo sigma-fst.lo
 libfstspecial_la_OBJECTS = $(am_libfstspecial_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
@@ -147,25 +146,24 @@ libfstspecial_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
        $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
        $(AM_CXXFLAGS) $(CXXFLAGS) $(libfstspecial_la_LDFLAGS) \
        $(LDFLAGS) -o $@
-phi_fst_la_DEPENDENCIES = ../../lib/libfst.la $(am__DEPENDENCIES_1)
+phi_fst_la_LIBADD =
 am_phi_fst_la_OBJECTS = phi-fst.lo
 phi_fst_la_OBJECTS = $(am_phi_fst_la_OBJECTS)
 phi_fst_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
        $(CXXFLAGS) $(phi_fst_la_LDFLAGS) $(LDFLAGS) -o $@
-rho_fst_la_DEPENDENCIES = ../../lib/libfst.la $(am__DEPENDENCIES_1)
+rho_fst_la_LIBADD =
 am_rho_fst_la_OBJECTS = rho-fst.lo
 rho_fst_la_OBJECTS = $(am_rho_fst_la_OBJECTS)
 rho_fst_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
        $(CXXFLAGS) $(rho_fst_la_LDFLAGS) $(LDFLAGS) -o $@
-sigma_fst_la_DEPENDENCIES = ../../lib/libfst.la $(am__DEPENDENCIES_1)
+sigma_fst_la_LIBADD =
 am_sigma_fst_la_OBJECTS = sigma-fst.lo
 sigma_fst_la_OBJECTS = $(am_sigma_fst_la_OBJECTS)
 sigma_fst_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
        $(CXXFLAGS) $(sigma_fst_la_LDFLAGS) $(LDFLAGS) -o $@
-PROGRAMS = $(bin_PROGRAMS)
 am__fstspecial_SOURCES_DIST = fstspecial.cc phi-fst.cc rho-fst.cc \
        sigma-fst.cc
 @HAVE_BIN_TRUE@am_fstspecial_OBJECTS =  \
@@ -174,9 +172,7 @@ am__fstspecial_SOURCES_DIST = fstspecial.cc phi-fst.cc rho-fst.cc \
 @HAVE_BIN_TRUE@        fstspecial-rho-fst.$(OBJEXT) \
 @HAVE_BIN_TRUE@        fstspecial-sigma-fst.$(OBJEXT)
 fstspecial_OBJECTS = $(am_fstspecial_OBJECTS)
-fstspecial_LDADD = $(LDADD)
-@HAVE_BIN_TRUE@fstspecial_DEPENDENCIES = ../../script/libfstscript.la \
-@HAVE_BIN_TRUE@        ../../lib/libfst.la $(am__DEPENDENCIES_1)
+@HAVE_BIN_TRUE@fstspecial_DEPENDENCIES = ../../script/libfstscript.la
 AM_V_P = $(am__v_P_@AM_V@)
 am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
 am__v_P_0 = false
@@ -191,7 +187,12 @@ am__v_at_0 = @
 am__v_at_1 = 
 DEFAULT_INCLUDES = 
 depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/fstspecial-fstspecial.Po \
+       ./$(DEPDIR)/fstspecial-phi-fst.Po \
+       ./$(DEPDIR)/fstspecial-rho-fst.Po \
+       ./$(DEPDIR)/fstspecial-sigma-fst.Po ./$(DEPDIR)/phi-fst.Plo \
+       ./$(DEPDIR)/rho-fst.Plo ./$(DEPDIR)/sigma-fst.Plo
 am__mv = mv -f
 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
        $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
@@ -282,7 +283,7 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
+LIBS = ../../lib/libfst.la -lm $(DL_LIBS)
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -310,7 +311,7 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
@@ -381,25 +382,19 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 AM_CPPFLAGS = -I$(srcdir)/../../include -I$(srcdir)/../../bin $(ICU_CPPFLAGS)
-@HAVE_BIN_TRUE@LDADD = ../../script/libfstscript.la \
-@HAVE_BIN_TRUE@        ../../lib/libfst.la -lm $(DL_LIBS)
-
 @HAVE_BIN_TRUE@fstspecial_SOURCES = fstspecial.cc phi-fst.cc rho-fst.cc sigma-fst.cc
 @HAVE_BIN_TRUE@fstspecial_CPPFLAGS = $(AM_CPPFLAGS)
+@HAVE_BIN_TRUE@fstspecial_LDADD = ../../script/libfstscript.la
 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 17:0:0 -lm $(DL_LIBS)
-libfstspecial_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
+libfstspecial_la_LDFLAGS = -version-info 17:0:0
 phi_fst_la_SOURCES = phi-fst.cc
-phi_fst_la_LDFLAGS = -module
-phi_fst_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
+phi_fst_la_LDFLAGS = -avoid-version -module
 rho_fst_la_SOURCES = rho-fst.cc
-rho_fst_la_LDFLAGS = -module
-rho_fst_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
+rho_fst_la_LDFLAGS = -avoid-version -module
 sigma_fst_la_SOURCES = sigma-fst.cc
-sigma_fst_la_LDFLAGS = -module
-sigma_fst_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
+sigma_fst_la_LDFLAGS = -avoid-version -module
 all: all-am
 
 .SUFFIXES:
@@ -421,8 +416,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
          *config.status*) \
            cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
          *) \
-           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
        esac;
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@@ -433,6 +428,55 @@ $(top_srcdir)/configure:  $(am__configure_deps)
 $(ACLOCAL_M4):  $(am__aclocal_m4_deps)
        cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 $(am__aclocal_m4_deps):
+install-binPROGRAMS: $(bin_PROGRAMS)
+       @$(NORMAL_INSTALL)
+       @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+       if test -n "$$list"; then \
+         echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+         $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+       fi; \
+       for p in $$list; do echo "$$p $$p"; done | \
+       sed 's/$(EXEEXT)$$//' | \
+       while read p p1; do if test -f $$p \
+        || test -f $$p1 \
+         ; then echo "$$p"; echo "$$p"; else :; fi; \
+       done | \
+       sed -e 'p;s,.*/,,;n;h' \
+           -e 's|.*|.|' \
+           -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+       sed 'N;N;N;s,\n, ,g' | \
+       $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+         { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+           if ($$2 == $$4) files[d] = files[d] " " $$1; \
+           else { print "f", $$3 "/" $$4, $$1; } } \
+         END { for (d in files) print "f", d, files[d] }' | \
+       while read type dir files; do \
+           if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+           test -z "$$files" || { \
+           echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+           $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+           } \
+       ; done
+
+uninstall-binPROGRAMS:
+       @$(NORMAL_UNINSTALL)
+       @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+       files=`for p in $$list; do echo "$$p"; done | \
+         sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+             -e 's/$$/$(EXEEXT)/' \
+       `; \
+       test -n "$$list" || exit 0; \
+       echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+       cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+       @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
+       echo " rm -f" $$list; \
+       rm -f $$list || exit $$?; \
+       test -n "$(EXEEXT)" || exit 0; \
+       list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+       echo " rm -f" $$list; \
+       rm -f $$list
 
 install-libLTLIBRARIES: $(lib_LTLIBRARIES)
        @$(NORMAL_INSTALL)
@@ -515,55 +559,6 @@ rho-fst.la: $(rho_fst_la_OBJECTS) $(rho_fst_la_DEPENDENCIES) $(EXTRA_rho_fst_la_
 
 sigma-fst.la: $(sigma_fst_la_OBJECTS) $(sigma_fst_la_DEPENDENCIES) $(EXTRA_sigma_fst_la_DEPENDENCIES) 
        $(AM_V_CXXLD)$(sigma_fst_la_LINK) -rpath $(libfstdir) $(sigma_fst_la_OBJECTS) $(sigma_fst_la_LIBADD) $(LIBS)
-install-binPROGRAMS: $(bin_PROGRAMS)
-       @$(NORMAL_INSTALL)
-       @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
-       if test -n "$$list"; then \
-         echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
-         $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
-       fi; \
-       for p in $$list; do echo "$$p $$p"; done | \
-       sed 's/$(EXEEXT)$$//' | \
-       while read p p1; do if test -f $$p \
-        || test -f $$p1 \
-         ; then echo "$$p"; echo "$$p"; else :; fi; \
-       done | \
-       sed -e 'p;s,.*/,,;n;h' \
-           -e 's|.*|.|' \
-           -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
-       sed 'N;N;N;s,\n, ,g' | \
-       $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
-         { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
-           if ($$2 == $$4) files[d] = files[d] " " $$1; \
-           else { print "f", $$3 "/" $$4, $$1; } } \
-         END { for (d in files) print "f", d, files[d] }' | \
-       while read type dir files; do \
-           if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
-           test -z "$$files" || { \
-           echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
-           $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
-           } \
-       ; done
-
-uninstall-binPROGRAMS:
-       @$(NORMAL_UNINSTALL)
-       @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
-       files=`for p in $$list; do echo "$$p"; done | \
-         sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
-             -e 's/$$/$(EXEEXT)/' \
-       `; \
-       test -n "$$list" || exit 0; \
-       echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
-       cd "$(DESTDIR)$(bindir)" && rm -f $$files
-
-clean-binPROGRAMS:
-       @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
-       echo " rm -f" $$list; \
-       rm -f $$list || exit $$?; \
-       test -n "$(EXEEXT)" || exit 0; \
-       list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
-       echo " rm -f" $$list; \
-       rm -f $$list
 
 fstspecial$(EXEEXT): $(fstspecial_OBJECTS) $(fstspecial_DEPENDENCIES) $(EXTRA_fstspecial_DEPENDENCIES) 
        @rm -f fstspecial$(EXEEXT)
@@ -575,13 +570,19 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstspecial-fstspecial.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstspecial-phi-fst.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstspecial-rho-fst.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstspecial-sigma-fst.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/phi-fst.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rho-fst.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sigma-fst.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstspecial-fstspecial.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstspecial-phi-fst.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstspecial-rho-fst.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstspecial-sigma-fst.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/phi-fst.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rho-fst.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sigma-fst.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+       @$(MKDIR_P) $(@D)
+       @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
 
 .cc.o:
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -721,7 +722,10 @@ cscopelist-am: $(am__tagged_files)
 distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
-distdir: $(DISTFILES)
+distdir: $(BUILT_SOURCES)
+       $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
        @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        list='$(DISTFILES)'; \
@@ -753,11 +757,11 @@ distdir: $(DISTFILES)
        done
 check-am: all-am
 check: check-am
-all-am: Makefile $(LTLIBRARIES) $(PROGRAMS)
+all-am: Makefile $(PROGRAMS) $(LTLIBRARIES)
 install-binPROGRAMS: install-libLTLIBRARIES
 
 installdirs:
-       for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libfstdir)" "$(DESTDIR)$(bindir)"; do \
+       for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libfstdir)"; do \
          test -z "$$dir" || $(MKDIR_P) "$$dir"; \
        done
 install: install-am
@@ -796,7 +800,13 @@ clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
        clean-libfstLTLIBRARIES clean-libtool mostlyclean-am
 
 distclean: distclean-am
-       -rm -rf ./$(DEPDIR)
+               -rm -f ./$(DEPDIR)/fstspecial-fstspecial.Po
+       -rm -f ./$(DEPDIR)/fstspecial-phi-fst.Po
+       -rm -f ./$(DEPDIR)/fstspecial-rho-fst.Po
+       -rm -f ./$(DEPDIR)/fstspecial-sigma-fst.Po
+       -rm -f ./$(DEPDIR)/phi-fst.Plo
+       -rm -f ./$(DEPDIR)/rho-fst.Plo
+       -rm -f ./$(DEPDIR)/sigma-fst.Plo
        -rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
        distclean-tags
@@ -842,7 +852,13 @@ install-ps-am:
 installcheck-am:
 
 maintainer-clean: maintainer-clean-am
-       -rm -rf ./$(DEPDIR)
+               -rm -f ./$(DEPDIR)/fstspecial-fstspecial.Po
+       -rm -f ./$(DEPDIR)/fstspecial-phi-fst.Po
+       -rm -f ./$(DEPDIR)/fstspecial-rho-fst.Po
+       -rm -f ./$(DEPDIR)/fstspecial-sigma-fst.Po
+       -rm -f ./$(DEPDIR)/phi-fst.Plo
+       -rm -f ./$(DEPDIR)/rho-fst.Plo
+       -rm -f ./$(DEPDIR)/sigma-fst.Plo
        -rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
@@ -864,7 +880,7 @@ uninstall-am: uninstall-binPROGRAMS uninstall-libLTLIBRARIES \
 
 .MAKE: install-am install-strip
 
-.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
        clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
        clean-libfstLTLIBRARIES clean-libtool cscopelist-am ctags \
        ctags-am distclean distclean-compile distclean-generic \
index 97177bf..e13122a 100644 (file)
@@ -1,9 +1,12 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/fst.h>
 #include <fst/extensions/special/phi-fst.h>
 
+#include <fst/arc.h>
+#include <fst/fst.h>
+#include <fst/register.h>
+
 DEFINE_int64(phi_fst_phi_label, 0,
              "Label of transitions to be interpreted as phi ('failure') "
               "transitions");
@@ -19,16 +22,16 @@ const char phi_fst_type[] = "phi";
 const char input_phi_fst_type[] = "input_phi";
 const char output_phi_fst_type[] = "output_phi";
 
-static FstRegisterer<StdPhiFst> PhiFst_StdArc_registerer;
-static FstRegisterer<LogPhiFst> PhiFst_LogArc_registerer;
-static FstRegisterer<Log64PhiFst> PhiFst_Log64Arc_registerer;
+REGISTER_FST(PhiFst, StdArc);
+REGISTER_FST(PhiFst, LogArc);
+REGISTER_FST(PhiFst, Log64Arc);
 
-static FstRegisterer<StdInputPhiFst> InputPhiFst_StdArc_registerer;
-static FstRegisterer<LogInputPhiFst> InputPhiFst_LogArc_registerer;
-static FstRegisterer<Log64InputPhiFst> InputPhiFst_Log64Arc_registerer;
+REGISTER_FST(InputPhiFst, StdArc);
+REGISTER_FST(InputPhiFst, LogArc);
+REGISTER_FST(InputPhiFst, Log64Arc);
 
-static FstRegisterer<StdOutputPhiFst> OutputPhiFst_StdArc_registerer;
-static FstRegisterer<LogOutputPhiFst> OutputPhiFst_LogArc_registerer;
-static FstRegisterer<Log64OutputPhiFst> OutputPhiFst_Log64Arc_registerer;
+REGISTER_FST(OutputPhiFst, StdArc);
+REGISTER_FST(OutputPhiFst, LogArc);
+REGISTER_FST(OutputPhiFst, Log64Arc);
 
 }  // namespace fst
index 023d432..6fa8be9 100644 (file)
@@ -3,7 +3,9 @@
 
 #include <fst/extensions/special/rho-fst.h>
 
+#include <fst/arc.h>
 #include <fst/fst.h>
+#include <fst/register.h>
 
 DEFINE_int64(rho_fst_rho_label, 0,
              "Label of transitions to be interpreted as rho ('rest') "
@@ -18,16 +20,16 @@ const char rho_fst_type[] = "rho";
 const char input_rho_fst_type[] = "input_rho";
 const char output_rho_fst_type[] = "output_rho";
 
-static FstRegisterer<StdRhoFst> RhoFst_StdArc_registerer;
-static FstRegisterer<LogRhoFst> RhoFst_LogArc_registerer;
-static FstRegisterer<Log64RhoFst> RhoFst_Log64Arc_registerer;
+REGISTER_FST(RhoFst, StdArc);
+REGISTER_FST(RhoFst, LogArc);
+REGISTER_FST(RhoFst, Log64Arc);
 
-static FstRegisterer<StdInputRhoFst> InputRhoFst_StdArc_registerer;
-static FstRegisterer<LogInputRhoFst> InputRhoFst_LogArc_registerer;
-static FstRegisterer<Log64InputRhoFst> InputRhoFst_Log64Arc_registerer;
+REGISTER_FST(InputRhoFst, StdArc);
+REGISTER_FST(InputRhoFst, LogArc);
+REGISTER_FST(InputRhoFst, Log64Arc);
 
-static FstRegisterer<StdOutputRhoFst> OutputRhoFst_StdArc_registerer;
-static FstRegisterer<LogOutputRhoFst> OutputRhoFst_LogArc_registerer;
-static FstRegisterer<Log64OutputRhoFst> OutputRhoFst_Log64Arc_registerer;
+REGISTER_FST(OutputRhoFst, StdArc);
+REGISTER_FST(OutputRhoFst, LogArc);
+REGISTER_FST(OutputRhoFst, Log64Arc);
 
 }  // namespace fst
index 30cd6a8..3d8a907 100644 (file)
@@ -3,7 +3,9 @@
 
 #include <fst/extensions/special/sigma-fst.h>
 
+#include <fst/arc.h>
 #include <fst/fst.h>
+#include <fst/register.h>
 
 DEFINE_int64(sigma_fst_sigma_label, 0,
              "Label of transitions to be interpreted as sigma ('any') "
@@ -18,16 +20,16 @@ const char sigma_fst_type[] = "sigma";
 const char input_sigma_fst_type[] = "input_sigma";
 const char output_sigma_fst_type[] = "output_sigma";
 
-static FstRegisterer<StdSigmaFst> SigmaFst_StdArc_registerer;
-static FstRegisterer<LogSigmaFst> SigmaFst_LogArc_registerer;
-static FstRegisterer<Log64SigmaFst> SigmaFst_Log64Arc_registerer;
+REGISTER_FST(SigmaFst, StdArc);
+REGISTER_FST(SigmaFst, LogArc);
+REGISTER_FST(SigmaFst, Log64Arc);
 
-static FstRegisterer<StdInputSigmaFst> InputSigmaFst_StdArc_registerer;
-static FstRegisterer<LogInputSigmaFst> InputSigmaFst_LogArc_registerer;
-static FstRegisterer<Log64InputSigmaFst> InputSigmaFst_Log64Arc_registerer;
+REGISTER_FST(InputSigmaFst, StdArc);
+REGISTER_FST(InputSigmaFst, LogArc);
+REGISTER_FST(InputSigmaFst, Log64Arc);
 
-static FstRegisterer<StdOutputSigmaFst> OutputSigmaFst_StdArc_registerer;
-static FstRegisterer<LogOutputSigmaFst> OutputSigmaFst_LogArc_registerer;
-static FstRegisterer<Log64OutputSigmaFst> OutputSigmaFst_Log64Arc_registerer;
+REGISTER_FST(OutputSigmaFst, StdArc);
+REGISTER_FST(OutputSigmaFst, LogArc);
+REGISTER_FST(OutputSigmaFst, Log64Arc);
 
 }  // namespace fst
index 3702a5e..b503830 100644 (file)
@@ -87,16 +87,15 @@ fst/script/intersect.h fst/script/invert.h fst/script/isomorphic.h \
 fst/script/map.h fst/script/minimize.h fst/script/print-impl.h \
 fst/script/print.h fst/script/project.h fst/script/prune.h \
 fst/script/push.h fst/script/randequivalent.h fst/script/randgen.h \
-fst/script/register.h fst/script/relabel.h fst/script/replace.h \
-fst/script/reverse.h fst/script/reweight.h fst/script/rmepsilon.h \
-fst/script/script-impl.h fst/script/shortest-distance.h \
-fst/script/shortest-path.h fst/script/stateiterator-class.h \
-fst/script/synchronize.h fst/script/text-io.h fst/script/topsort.h \
-fst/script/union.h fst/script/weight-class.h fst/script/fstscript-decl.h \
-fst/script/verify.h
+fst/script/relabel.h fst/script/replace.h fst/script/reverse.h \
+fst/script/reweight.h fst/script/rmepsilon.h fst/script/script-impl.h \
+fst/script/shortest-distance.h fst/script/shortest-path.h \
+fst/script/stateiterator-class.h fst/script/synchronize.h \
+fst/script/text-io.h fst/script/topsort.h fst/script/union.h \
+fst/script/weight-class.h fst/script/fstscript-decl.h fst/script/verify.h
 
-test_include_headers = fst/test/algo_test.h fst/test/fst_test.h \
-fst/test/rand-fst.h fst/test/weight-tester.h
+test_include_headers = fst/test/algo_test.h fst/test/compactors.h \
+fst/test/fst_test.h fst/test/rand-fst.h fst/test/weight-tester.h
 
 nobase_include_HEADERS = fst/accumulator.h fst/add-on.h fst/arc-arena.h \
 fst/arc-map.h fst/arc.h fst/arcfilter.h fst/arcsort.h fst/bi-table.h \
index c930c33..356e6c6 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -90,7 +90,7 @@ build_triplet = @build@
 host_triplet = @host@
 subdir = src/include
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_python_devel.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
        $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
@@ -205,8 +205,7 @@ am__nobase_include_HEADERS_DIST = fst/accumulator.h fst/add-on.h \
        fst/script/print-impl.h fst/script/print.h \
        fst/script/project.h fst/script/prune.h fst/script/push.h \
        fst/script/randequivalent.h fst/script/randgen.h \
-       fst/script/register.h fst/script/relabel.h \
-       fst/script/replace.h fst/script/reverse.h \
+       fst/script/relabel.h fst/script/replace.h fst/script/reverse.h \
        fst/script/reweight.h fst/script/rmepsilon.h \
        fst/script/script-impl.h fst/script/shortest-distance.h \
        fst/script/shortest-path.h fst/script/stateiterator-class.h \
@@ -216,7 +215,7 @@ am__nobase_include_HEADERS_DIST = fst/accumulator.h fst/add-on.h \
        fst/script/verify.h fst/extensions/special/phi-fst.h \
        fst/extensions/special/rho-fst.h \
        fst/extensions/special/sigma-fst.h fst/test/algo_test.h \
-       fst/test/fst_test.h fst/test/rand-fst.h \
+       fst/test/compactors.h fst/test/fst_test.h fst/test/rand-fst.h \
        fst/test/weight-tester.h
 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
 am__vpath_adj = case $$p in \
@@ -335,7 +334,7 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
@@ -480,16 +479,15 @@ fst/script/intersect.h fst/script/invert.h fst/script/isomorphic.h \
 fst/script/map.h fst/script/minimize.h fst/script/print-impl.h \
 fst/script/print.h fst/script/project.h fst/script/prune.h \
 fst/script/push.h fst/script/randequivalent.h fst/script/randgen.h \
-fst/script/register.h fst/script/relabel.h fst/script/replace.h \
-fst/script/reverse.h fst/script/reweight.h fst/script/rmepsilon.h \
-fst/script/script-impl.h fst/script/shortest-distance.h \
-fst/script/shortest-path.h fst/script/stateiterator-class.h \
-fst/script/synchronize.h fst/script/text-io.h fst/script/topsort.h \
-fst/script/union.h fst/script/weight-class.h fst/script/fstscript-decl.h \
-fst/script/verify.h
+fst/script/relabel.h fst/script/replace.h fst/script/reverse.h \
+fst/script/reweight.h fst/script/rmepsilon.h fst/script/script-impl.h \
+fst/script/shortest-distance.h fst/script/shortest-path.h \
+fst/script/stateiterator-class.h fst/script/synchronize.h \
+fst/script/text-io.h fst/script/topsort.h fst/script/union.h \
+fst/script/weight-class.h fst/script/fstscript-decl.h fst/script/verify.h
 
-test_include_headers = fst/test/algo_test.h fst/test/fst_test.h \
-fst/test/rand-fst.h fst/test/weight-tester.h
+test_include_headers = fst/test/algo_test.h fst/test/compactors.h \
+fst/test/fst_test.h fst/test/rand-fst.h fst/test/weight-tester.h
 
 nobase_include_HEADERS = fst/accumulator.h fst/add-on.h fst/arc-arena.h \
 fst/arc-map.h fst/arc.h fst/arcfilter.h fst/arcsort.h fst/bi-table.h \
@@ -548,8 +546,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
          *config.status*) \
            cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
          *) \
-           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
        esac;
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@@ -643,7 +641,10 @@ cscopelist-am: $(am__tagged_files)
 distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
-distdir: $(DISTFILES)
+distdir: $(BUILT_SOURCES)
+       $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
        @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        list='$(DISTFILES)'; \
index 0254725..e74a637 100644 (file)
@@ -47,8 +47,8 @@ enum MapSymbolsAction {
 };
 
 // The ArcMapper interfaces defines how arcs and final weights are mapped.
-// This is useful for implementing operations that do not change the number of
-// arcs (except possibly superfinal arcs).
+// This is useful for implementing operations that apply to each arc separately
+// and do not change the number of arcs (except possibly superfinal arcs).
 //
 // template <class A, class B>
 // class ArcMapper {
index e5c9f49..2aa3314 100644 (file)
@@ -52,11 +52,11 @@ struct CacheImplOptions {
 };
 
 // Cache flags.
-constexpr uint32 kCacheFinal = 0x0001;   // Final weight has been cached.
-constexpr uint32 kCacheArcs = 0x0002;    // Arcs have been cached.
-constexpr uint32 kCacheInit = 0x0004;    // Initialized by GC.
-constexpr uint32 kCacheRecent = 0x0008;  // Visited since GC.
-constexpr uint32 kCacheFlags =
+constexpr uint8 kCacheFinal = 0x01;   // Final weight has been cached.
+constexpr uint8 kCacheArcs = 0x02;    // Arcs have been cached.
+constexpr uint8 kCacheInit = 0x04;    // Initialized by GC.
+constexpr uint8 kCacheRecent = 0x08;  // Visited since GC.
+constexpr uint8 kCacheFlags =
     kCacheFinal | kCacheArcs | kCacheInit | kCacheRecent;
 
 // Cache state, with arcs stored in a per-state std::vector.
@@ -112,7 +112,7 @@ class CacheState {
   const Arc *Arcs() const { return !arcs_.empty() ? &arcs_[0] : nullptr; }
 
   // Accesses flags; used by the caller.
-  uint32 Flags() const { return flags_; }
+  uint8 Flags() const { return flags_; }
 
   // Accesses ref count; used by the caller.
   int RefCount() const { return ref_count_; }
@@ -175,7 +175,7 @@ class CacheState {
   }
 
   // Sets status flags; used by the caller.
-  void SetFlags(uint32 flags, uint32 mask) const {
+  void SetFlags(uint8 flags, uint8 mask) const {
     flags_ &= ~mask;
     flags_ |= flags;
   }
@@ -213,7 +213,7 @@ class CacheState {
   size_t niepsilons_;                    // # of input epsilons.
   size_t noepsilons_;                    // # of output epsilons.
   std::vector<Arc, ArcAllocator> arcs_;  // Arcs representation.
-  mutable uint32 flags_;
+  mutable uint8 flags_;
   mutable int ref_count_;  // If 0, available for GC.
 };
 
@@ -1218,9 +1218,9 @@ class CacheArcIterator {
 
   void Seek(size_t a) { i_ = a; }
 
-  constexpr uint32 Flags() const { return kArcValueFlags; }
+  constexpr uint8 Flags() const { return kArcValueFlags; }
 
-  void SetFlags(uint32 flags, uint32 mask) {}
+  void SetFlags(uint8 flags, uint8 mask) {}
 
  private:
   const State *state_;
@@ -1266,9 +1266,9 @@ class CacheMutableArcIterator
 
   void SetValue(const Arc &arc) final { state_->SetArc(arc, i_); }
 
-  uint32 Flags() const final { return kArcValueFlags; }
+  uint8 Flags() const final { return kArcValueFlags; }
 
-  void SetFlags(uint32, uint32) final {}
+  void SetFlags(uint8, uint8) final {}
 
  private:
   size_t i_;
index b0e377e..efcc20c 100644 (file)
@@ -60,8 +60,8 @@ void Closure(RationalFst<Arc> *fst, ClosureType closure_type) {
 struct ClosureFstOptions : RationalFstOptions {
   ClosureType type;
 
-  ClosureFstOptions(const RationalFstOptions &opts,
-                    ClosureType type = CLOSURE_STAR)
+  explicit ClosureFstOptions(const RationalFstOptions &opts,
+                             ClosureType type = CLOSURE_STAR)
       : RationalFstOptions(opts), type(type) {}
 
   explicit ClosureFstOptions(ClosureType type = CLOSURE_STAR) : type(type) {}
index aee4fcf..e657cd2 100644 (file)
@@ -35,15 +35,20 @@ struct CompactFstOptions : public CacheOptions {
   explicit CompactFstOptions(const CacheOptions &opts) : CacheOptions(opts) {}
 };
 
-// New upcoming (Fst) Compactor interface - currently used internally
-// by CompactFstImpl.
+// New (Fst) Compactor interface - used by CompactFst.  This interface
+// allows complete flexibility in how the compaction is accomplished.
 //
 // class Compactor {
 //  public:
-//   // Constructor from the Fst to be compacted.
-//   Compactor(const Fst<Arc> &fst, ...);
-//   // Copy constructor
-//   Compactor(const Compactor &compactor, bool safe = false)
+//   // Constructor from the Fst to be compacted.  If compactor is present,
+//   // only optional state should be copied from it.  Examples of this
+//   // optional state include compression level or ArcCompactors.
+//   explicit Compactor(const Fst<Arc> &fst,
+//                      shared_ptr<Compactor> compactor = nullptr);
+//   // Copy constructor.  Must make a thread-safe copy suitable for use by
+//   // by Fst::Copy(/*safe=*/true).  Only thread-unsafe data structures
+//   // need to be deeply copied.
+//   Compactor(const Compactor &compactor);
 //   // Default constructor (optional, see comment below).
 //   Compactor();
 //
@@ -57,33 +62,50 @@ struct CompactFstOptions : public CacheOptions {
 //   class State {
 //    public:
 //     State();  // Required, corresponds to kNoStateId.
-//     State(const Compactor *c, StateId);  // Accessor for StateId 's'.
+//     State(const Compactor *c, StateId s);  // Accessor for StateId 's'.
 //     StateId GetStateId() const;
 //     Weight Final() const;
 //     size_t NumArcs() const;
-//     Arc GetArc(size_t i, uint32 f) const;
+//     // Gets the 'i'th arc for the state. Requires i < NumArcs().
+//     Arc GetArc(size_t i, uint8 flags) 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.
+//   template <typename A>
 //   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.
+//
+//   // Returns the properties that are always when an FST with the
+//   // specified properties is compacted using this compactor.
+//   // This function should clear bits for properties that no longer
+//   // hold and set those for properties that are known to hold.
+//   uint64 Properties(uint64 props) const;
+//
+//   // Returns a string identifying the type of compactor.
 //   static const std::string &Type();
-//   // Return true if an error has occured.
+//
+//   // Returns true if an error has occurred.
 //   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);
+//   static Compactor *Read(std::istream &strm, const FstReadOptions &opts,
+//                          const FstHeader &hdr);
 // };
 //
 
-// Old (Arc) Compactor Interface:
+// Old ArcCompactor Interface:
+//
+// This interface is not deprecated; it, along with DefaultCompactStore and
+// other Stores that implement its interface, is simply more constrained
+// by essentially forcing the implementation to use an index array
+// and an arc array, but giving flexibility in how those are implemented.
+// This interface may still be useful and more convenient if that is the
+// desired representation.
 //
 // The ArcCompactor class determines how arcs and final weights are compacted
 // and expanded.
@@ -106,6 +128,14 @@ struct CompactFstOptions : public CacheOptions {
 //
 // class ArcCompactor {
 //  public:
+//   // Default constructor (optional, see comment below).
+//   ArcCompactor();
+//
+//   // Copy constructor.  Must make a thread-safe copy suitable for use by
+//   // by Fst::Copy(/*safe=*/true).  Only thread-unsafe data structures
+//   // need to be deeply copied.
+//   ArcCompactor(const ArcCompactor &);
+//
 //   // Element is the type of the compacted transitions.
 //   using Element = ...
 //
@@ -125,7 +155,8 @@ struct CompactFstOptions : public CacheOptions {
 //   bool Compatible(const Fst<A> &fst) const;
 //
 //   // Returns the properties that are always true for an FST compacted using
-//   // this compactor
+//   // this compactor.  Any Fst with the inverse of these properties should
+//   // be incompatible.
 //   uint64 Properties() const;
 //
 //   // Returns a string identifying the type of compactor.
@@ -136,9 +167,6 @@ struct CompactFstOptions : public CacheOptions {
 //
 //   // Reads a compactor from a file.
 //   static ArcCompactor *Read(std::istream &strm);
-//
-//   // Default constructor (optional, see comment below).
-//   ArcCompactor();
 // };
 //
 // The default constructor is only required for FST_REGISTER to work (i.e.,
@@ -151,20 +179,22 @@ struct CompactFstOptions : public CacheOptions {
 //   FSTERROR() << "Compactor: No default constructor";
 // }
 
-// Default implementation data for CompactFst, which can shared between
-// otherwise independent copies.
+// Default implementation data for DefaultCompactor.  DefaultCompactStore
+// is thread-safe and can be shared between otherwise independent copies.
+// Only old-style ArcCompactors are supported because the DefaultCompactStore
+// constructors use the old API.
 //
 // The implementation contains two arrays: 'states_' and 'compacts_'.
 //
 // For fixed out-degree compactors, the 'states_' array is unallocated. The
-// 'compacts_' contains the compacted transitions. Its size is 'ncompacts_'.
-// The outgoing transitions at a given state are stored consecutively. For a
-// given state 's', its 'compactor.Size()' outgoing transitions (including
-// superfinal transition when 's' is final), are stored in position
-// ['s*compactor.Size()', '(s+1)*compactor.Size()').
+// 'compacts_' array contains the compacted transitions. Its size is
+// 'ncompacts_'. The outgoing transitions at a given state are stored
+// consecutively. For a given state 's', its 'compactor.Size()' outgoing
+// transitions (including a superfinal transition when 's' is final), are stored
+// in positions ['s*compactor.Size()', '(s+1)*compactor.Size()').
 //
 // For variable out-degree compactors, the states_ array has size
-// 'nstates_ + 1' and contains pointers to positions into 'compacts_'. For a
+// 'nstates_ + 1' and contains positions in the 'compacts_' array. For a
 // given state 's', the compacted transitions of 's' are stored in positions
 // ['states_[s]', 'states_[s + 1]') in 'compacts_'. By convention,
 // 'states_[nstates_] == ncompacts_'.
@@ -176,36 +206,37 @@ struct CompactFstOptions : public CacheOptions {
 template <class Element, class Unsigned>
 class DefaultCompactStore {
  public:
-  DefaultCompactStore()
-      : states_(nullptr),
-        compacts_(nullptr),
-        nstates_(0),
-        ncompacts_(0),
-        narcs_(0),
-        start_(kNoStateId),
-        error_(false) {}
-
-  template <class Arc, class Compactor>
-  DefaultCompactStore(const Fst<Arc> &fst, const Compactor &compactor);
-
-  template <class Iterator, class Compactor>
-  DefaultCompactStore(const Iterator &begin, const Iterator &end,
-                      const Compactor &compactor);
+  DefaultCompactStore() = default;
+
+  template <class Arc, class ArcCompactor>
+  DefaultCompactStore(const Fst<Arc> &fst, const ArcCompactor &arc_compactor);
+
+  template <class Iterator, class ArcCompactor>
+  DefaultCompactStore(const Iterator begin, const Iterator end,
+                      const ArcCompactor &arc_compactor);
 
   ~DefaultCompactStore() {
     if (!states_region_) delete[] states_;
     if (!compacts_region_) delete[] compacts_;
   }
 
-  template <class Compactor>
-  static DefaultCompactStore<Element, Unsigned> *Read(
-      std::istream &strm, const FstReadOptions &opts, const FstHeader &hdr,
-      const Compactor &compactor);
+  template <class ArcCompactor>
+  static DefaultCompactStore *Read(std::istream &strm,
+                                   const FstReadOptions &opts,
+                                   const FstHeader &hdr,
+                                   const ArcCompactor &arc_compactor);
 
   bool Write(std::ostream &strm, const FstWriteOptions &opts) const;
 
+  // Returns the starting index in 'compacts_' of the transitions
+  // for state 'i'.  See class-level comment for further details.
+  // Requires that the DefaultCompactStore was constructed with a
+  // variable out-degree compactor.  Requires 0 <= i <= NumStates().
+  // By convention, States(NumStates()) == NumCompacts().
   Unsigned States(ssize_t i) const { return states_[i]; }
 
+  // Returns the compacted Element at position i.  See class-level comment
+  // for further details.  Requires 0 <= i < NumCompacts().
   const Element &Compacts(size_t i) const { return compacts_[i]; }
 
   size_t NumStates() const { return nstates_; }
@@ -224,26 +255,19 @@ class DefaultCompactStore {
  private:
   std::unique_ptr<MappedFile> states_region_;
   std::unique_ptr<MappedFile> compacts_region_;
-  Unsigned *states_;
-  Element *compacts_;
-  size_t nstates_;
-  size_t ncompacts_;
-  size_t narcs_;
-  ssize_t start_;
-  bool error_;
+  Unsigned *states_ = nullptr;
+  Element *compacts_ = nullptr;
+  size_t nstates_  = 0;
+  size_t ncompacts_ = 0;
+  size_t narcs_ = 0;
+  ssize_t start_ = kNoStateId;
+  bool error_ = false;
 };
 
 template <class Element, class Unsigned>
-template <class Arc, class Compactor>
+template <class Arc, class ArcCompactor>
 DefaultCompactStore<Element, Unsigned>::DefaultCompactStore(
-    const Fst<Arc> &fst, const Compactor &compactor)
-    : states_(nullptr),
-      compacts_(nullptr),
-      nstates_(0),
-      ncompacts_(0),
-      narcs_(0),
-      start_(kNoStateId),
-      error_(false) {
+    const Fst<Arc> &fst, const ArcCompactor &arc_compactor) {
   using StateId = typename Arc::StateId;
   using Weight = typename Arc::Weight;
   start_ = fst.Start();
@@ -255,16 +279,16 @@ DefaultCompactStore<Element, Unsigned>::DefaultCompactStore(
     narcs_ += fst.NumArcs(s);
     if (fst.Final(s) != Weight::Zero()) ++nfinals;
   }
-  if (compactor.Size() == -1) {
+  if (arc_compactor.Size() == -1) {
     states_ = new Unsigned[nstates_ + 1];
     ncompacts_ = narcs_ + nfinals;
     compacts_ = new Element[ncompacts_];
     states_[nstates_] = ncompacts_;
   } else {
     states_ = nullptr;
-    ncompacts_ = nstates_ * compactor.Size();
+    ncompacts_ = nstates_ * arc_compactor.Size();
     if ((narcs_ + nfinals) != ncompacts_) {
-      FSTERROR() << "DefaultCompactStore: Compactor incompatible with FST";
+      FSTERROR() << "DefaultCompactStore: ArcCompactor incompatible with FST";
       error_ = true;
       return;
     }
@@ -274,71 +298,65 @@ DefaultCompactStore<Element, Unsigned>::DefaultCompactStore(
   size_t fpos = 0;
   for (size_t s = 0; s < nstates_; ++s) {
     fpos = pos;
-    if (compactor.Size() == -1) states_[s] = pos;
+    if (arc_compactor.Size() == -1) states_[s] = pos;
     if (fst.Final(s) != Weight::Zero()) {
-      compacts_[pos++] = compactor.Compact(
+      compacts_[pos++] = arc_compactor.Compact(
           s, Arc(kNoLabel, kNoLabel, fst.Final(s), kNoStateId));
     }
     for (ArcIterator<Fst<Arc>> aiter(fst, s); !aiter.Done(); aiter.Next()) {
-      compacts_[pos++] = compactor.Compact(s, aiter.Value());
+      compacts_[pos++] = arc_compactor.Compact(s, aiter.Value());
     }
-    if ((compactor.Size() != -1) && (pos != fpos + compactor.Size())) {
-      FSTERROR() << "DefaultCompactStore: Compactor incompatible with FST";
+    if ((arc_compactor.Size() != -1) && (pos != fpos + arc_compactor.Size())) {
+      FSTERROR() << "DefaultCompactStore: ArcCompactor incompatible with FST";
       error_ = true;
       return;
     }
   }
   if (pos != ncompacts_) {
-    FSTERROR() << "DefaultCompactStore: Compactor incompatible with FST";
+    FSTERROR() << "DefaultCompactStore: ArcCompactor incompatible with FST";
     error_ = true;
     return;
   }
 }
 
 template <class Element, class Unsigned>
-template <class Iterator, class Compactor>
+template <class Iterator, class ArcCompactor>
 DefaultCompactStore<Element, Unsigned>::DefaultCompactStore(
-    const Iterator &begin, const Iterator &end, const Compactor &compactor)
-    : states_(nullptr),
-      compacts_(nullptr),
-      nstates_(0),
-      ncompacts_(0),
-      narcs_(0),
-      start_(kNoStateId),
-      error_(false) {
-  using Arc = typename Compactor::Arc;
+    const Iterator begin, const Iterator end,
+    const ArcCompactor &arc_compactor) {
+  using Arc = typename ArcCompactor::Arc;
   using Weight = typename Arc::Weight;
-  if (compactor.Size() != -1) {
+  if (arc_compactor.Size() != -1) {
     ncompacts_ = std::distance(begin, end);
-    if (compactor.Size() == 1) {
+    if (arc_compactor.Size() == 1) {
       // For strings, allows implicit final weight. Empty input is the empty
       // string.
       if (ncompacts_ == 0) {
         ++ncompacts_;
       } else {
         const auto arc =
-            compactor.Expand(ncompacts_ - 1, *(begin + (ncompacts_ - 1)));
+            arc_compactor.Expand(ncompacts_ - 1, *(begin + (ncompacts_ - 1)));
         if (arc.ilabel != kNoLabel) ++ncompacts_;
       }
     }
-    if (ncompacts_ % compactor.Size()) {
+    if (ncompacts_ % arc_compactor.Size()) {
       FSTERROR() << "DefaultCompactStore: Size of input container incompatible"
-                 << " with compactor";
+                 << " with arc compactor";
       error_ = true;
       return;
     }
     if (ncompacts_ == 0) return;
     start_ = 0;
-    nstates_ = ncompacts_ / compactor.Size();
+    nstates_ = ncompacts_ / arc_compactor.Size();
     compacts_ = new Element[ncompacts_];
     size_t i = 0;
     Iterator it = begin;
     for (; it != end; ++it, ++i) {
       compacts_[i] = *it;
-      if (compactor.Expand(i, *it).ilabel != kNoLabel) ++narcs_;
+      if (arc_compactor.Expand(i, *it).ilabel != kNoLabel) ++narcs_;
     }
     if (i < ncompacts_) {
-      compacts_[i] = compactor.Compact(
+      compacts_[i] = arc_compactor.Compact(
           i, Arc(kNoLabel, kNoLabel, Weight::One(), kNoStateId));
     }
   } else {
@@ -346,7 +364,7 @@ DefaultCompactStore<Element, Unsigned>::DefaultCompactStore(
     // Count # of states, arcs and compacts.
     auto it = begin;
     for (size_t i = 0; it != end; ++it, ++i) {
-      const auto arc = compactor.Expand(i, *it);
+      const auto arc = arc_compactor.Expand(i, *it);
       if (arc.ilabel != kNoLabel) {
         ++narcs_;
         ++ncompacts_;
@@ -362,7 +380,7 @@ DefaultCompactStore<Element, Unsigned>::DefaultCompactStore(
     size_t i = 0;
     size_t s = 0;
     for (it = begin; it != end; ++it) {
-      const auto arc = compactor.Expand(i, *it);
+      const auto arc = arc_compactor.Expand(i, *it);
       if (arc.ilabel != kNoLabel) {
         compacts_[i++] = *it;
       } else {
@@ -379,18 +397,16 @@ DefaultCompactStore<Element, Unsigned>::DefaultCompactStore(
 }
 
 template <class Element, class Unsigned>
-template <class Compactor>
+template <class ArcCompactor>
 DefaultCompactStore<Element, Unsigned>
-    *DefaultCompactStore<Element, Unsigned>::Read(std::istream &strm,
-                                                  const FstReadOptions &opts,
-                                                  const FstHeader &hdr,
-                                                  const Compactor &compactor) {
-  std::unique_ptr<DefaultCompactStore<Element, Unsigned>> data(
-      new DefaultCompactStore<Element, Unsigned>());
+    *DefaultCompactStore<Element, Unsigned>::Read(
+        std::istream &strm, const FstReadOptions &opts, const FstHeader &hdr,
+        const ArcCompactor &arc_compactor) {
+  std::unique_ptr<DefaultCompactStore> data(new DefaultCompactStore);
   data->start_ = hdr.Start();
   data->nstates_ = hdr.NumStates();
   data->narcs_ = hdr.NumArcs();
-  if (compactor.Size() == -1) {
+  if (arc_compactor.Size() == -1) {
     if ((hdr.GetFlags() & FstHeader::IS_ALIGNED) && !AlignInput(strm)) {
       LOG(ERROR) << "DefaultCompactStore::Read: Alignment failed: "
                  << opts.source;
@@ -408,8 +424,9 @@ DefaultCompactStore<Element, Unsigned>
   } else {
     data->states_ = nullptr;
   }
-  data->ncompacts_ = compactor.Size() == -1 ? data->states_[data->nstates_]
-                                            : data->nstates_ * compactor.Size();
+  data->ncompacts_ = arc_compactor.Size() == -1
+                         ? data->states_[data->nstates_]
+                         : data->nstates_ * arc_compactor.Size();
   if ((hdr.GetFlags() & FstHeader::IS_ALIGNED) && !AlignInput(strm)) {
     LOG(ERROR) << "DefaultCompactStore::Read: Alignment failed: "
                << opts.source;
@@ -436,7 +453,7 @@ bool DefaultCompactStore<Element, Unsigned>::Write(
                  << opts.source;
       return false;
     }
-    strm.write(reinterpret_cast<char *>(states_),
+    strm.write(reinterpret_cast<const char *>(states_),
                (nstates_ + 1) * sizeof(Unsigned));
   }
   if (opts.align && !AlignOutput(strm)) {
@@ -444,7 +461,8 @@ bool DefaultCompactStore<Element, Unsigned>::Write(
                << opts.source;
     return false;
   }
-  strm.write(reinterpret_cast<char *>(compacts_), ncompacts_ * sizeof(Element));
+  strm.write(reinterpret_cast<const char *>(compacts_),
+             ncompacts_ * sizeof(Element));
   strm.flush();
   if (!strm) {
     LOG(ERROR) << "DefaultCompactStore::Write: Write failed: " << opts.source;
@@ -461,36 +479,42 @@ const std::string &DefaultCompactStore<Element, Unsigned>::Type() {
 
 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>>
+// Wraps an old-style arc compactor and a compact store as a new Fst compactor.
+// S must be thread-safe.
+template <class AC, class U,
+          class S /*= DefaultCompactStore<typename AC::Element, U>*/>
 class DefaultCompactor {
  public:
-  using ArcCompactor = C;
+  using ArcCompactor = AC;
   using Unsigned = U;
   using CompactStore = S;
-  using Element = typename C::Element;
-  using Arc = typename C::Arc;
+  using Element = typename AC::Element;
+  using Arc = typename AC::Arc;
   using StateId = typename Arc::StateId;
   using Weight = typename Arc::Weight;
-  using State = DefaultCompactState<C, U, S>;
+  using State = DefaultCompactState<AC, U, S>;
   friend State;
 
   DefaultCompactor()
       : arc_compactor_(nullptr), compact_store_(nullptr) {}
 
   // Constructs from Fst.
+  explicit DefaultCompactor(const Fst<Arc> &fst,
+                            ArcCompactor &&arc_compactor = ArcCompactor())
+      : DefaultCompactor(
+            fst, std::make_shared<ArcCompactor>(std::move(arc_compactor))) {}
+
   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)
+                   std::shared_ptr<DefaultCompactor> compactor)
       : arc_compactor_(compactor->arc_compactor_),
-        compact_store_(compactor->compact_store_ == nullptr ?
-                       std::make_shared<S>(fst, *arc_compactor_) :
-                       compactor->compact_store_) {}
+        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,
@@ -498,21 +522,49 @@ class DefaultCompactor {
       : arc_compactor_(std::move(arc_compactor)),
         compact_store_(std::move(compact_store)) {}
 
-  // Constructs from set of compact elements (when arc_compactor.Size() != -1).
+  // The following 2 constructors take as input two iterators delimiting a set
+  // of (already) compacted transitions, starting with the transitions out of
+  // the initial state. The format of the input differs for fixed out-degree
+  // and variable out-degree arc compactors.
+  //
+  // - For fixed out-degree arc compactors, the final weight (encoded as a
+  // compacted transition) needs to be given only for final states. All strings
+  // (arc compactor of size 1) will be assume to be terminated by a final state
+  // even when the final state is not implicitely given.
+  //
+  // - For variable out-degree arc compactors, the final weight (encoded as a
+  // compacted transition) needs to be given for all states and must appeared
+  // first in the list (for state s, final weight of s, followed by outgoing
+  // transitons in s).
+  //
+  // These 2 constructors allows the direct construction of a CompactArcFst
+  // without first creating a more memory-hungry regular FST. This is useful
+  // when memory usage is severely constrained.
+  //
+  // Usage:
+  // CompactArcFst<...> fst(
+  //     std::make_shared<CompactArcFst<...>::Compactor>(b, e));
   template <class Iterator>
-  DefaultCompactor(const Iterator &b, const Iterator &e,
-                   std::shared_ptr<C> arc_compactor)
+  DefaultCompactor(const Iterator b, const Iterator e,
+                   std::shared_ptr<ArcCompactor> 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())),
+  template <class Iterator>
+  DefaultCompactor(const Iterator b, const Iterator e)
+      : DefaultCompactor(b, e, std::make_shared<ArcCompactor>()) {}
+
+  // Copy constructor.  This makes a thread-safe copy, so requires that
+  // CompactStore is thread-safe.
+  DefaultCompactor(const DefaultCompactor &compactor)
+      : arc_compactor_(
+            std::make_shared<ArcCompactor>(*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())),
+      : arc_compactor_(
+            std::make_shared<ArcCompactor>(*compactor.GetArcCompactor())),
         compact_store_(compactor.SharedCompactStore()) {}
 
   StateId Start() const { return compact_store_->Start(); }
@@ -523,21 +575,25 @@ class DefaultCompactor {
     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));
+  static DefaultCompactor *Read(std::istream &strm, const FstReadOptions &opts,
+                                const FstHeader &hdr) {
+    std::shared_ptr<ArcCompactor> arc_compactor(ArcCompactor::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);
+    return new DefaultCompactor(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(); }
+  uint64 Properties(uint64 props) const {
+    // ArcCompactor properties can just be or-ed in since it is assumed that
+    // if the ArcCompactor sets a property, any FST with the inverse
+    // property is incompatible.
+    return arc_compactor_->Properties() | props;
+  }
 
   bool IsCompatible(const Fst<Arc> &fst) const {
     return arc_compactor_->Compatible(fst);
@@ -552,7 +608,7 @@ class DefaultCompactor {
       std::string type = "compact";
       if (sizeof(U) != sizeof(uint32)) type += std::to_string(8 * sizeof(U));
       type += "_";
-      type += C::Type();
+      type += ArcCompactor::Type();
       if (CompactStore::Type() != "compact") {
         type += "_";
         type += CompactStore::Type();
@@ -574,8 +630,8 @@ class DefaultCompactor {
   }
 
   // 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);
+  Arc ComputeArc(StateId s, Unsigned i, uint8 flags) const {
+    return arc_compactor_->Expand(s, compact_store_->Compacts(i), flags);
   }
 
  private:
@@ -598,30 +654,31 @@ class DefaultCompactor {
 
 // Default implementation of state attributes accessor class for
 // DefaultCompactor. Use of efficient specialization strongly encouraged.
-template <class C, class U, class S>
+template <class ArcCompactor, class U, class S>
 class DefaultCompactState {
  public:
-  using Arc = typename C::Arc;
+  using Arc = typename ArcCompactor::Arc;
   using StateId = typename Arc::StateId;
   using Weight = typename Arc::Weight;
+  using Compactor = DefaultCompactor<ArcCompactor, U, S>;
 
   DefaultCompactState() = default;
 
-  DefaultCompactState(const DefaultCompactor<C, U, S> *compactor, StateId s)
+  DefaultCompactState(const Compactor *compactor, StateId s)
       : compactor_(compactor),
         s_(s),
         range_(compactor->CompactsRange(s)),
         has_final_(
             range_.second != 0 &&
-            compactor->ComputeArc(s, range_.first,
-                                 kArcILabelValue).ilabel == kNoLabel) {
+            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) {
+  void Set(const Compactor *compactor, StateId s) {
     compactor_ = compactor;
     s_ = s;
     range_ = compactor->CompactsRange(s);
@@ -645,35 +702,36 @@ class DefaultCompactState {
 
   size_t NumArcs() const { return range_.second; }
 
-  Arc GetArc(size_t i, uint32 f) const {
-    return compactor_->ComputeArc(s_, range_.first + i, f);
+  Arc GetArc(size_t i, uint8 flags) const {
+    return compactor_->ComputeArc(s_, range_.first + i, flags);
   }
 
  private:
-  const DefaultCompactor<C, U, S> *compactor_ = nullptr;  // borrowed ref.
+  const Compactor *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>> {
+template <class ArcCompactor, class U>
+class DefaultCompactState<
+    ArcCompactor, U, DefaultCompactStore<typename ArcCompactor::Element, U>> {
  public:
-  using Arc = typename C::Arc;
+  using Arc = typename ArcCompactor::Arc;
   using StateId = typename Arc::StateId;
   using Weight = typename Arc::Weight;
-  using CompactStore = DefaultCompactStore<typename C::Element, U>;
+  using CompactStore = DefaultCompactStore<typename ArcCompactor::Element, U>;
+  using Compactor = DefaultCompactor<ArcCompactor, U, CompactStore>;
 
   DefaultCompactState() = default;
 
-  DefaultCompactState(
-      const DefaultCompactor<C, U, CompactStore> *compactor, StateId s)
+  DefaultCompactState(const Compactor *compactor, StateId s)
       : arc_compactor_(compactor->GetArcCompactor()), s_(s) {
     Init(compactor);
   }
 
-  void Set(const DefaultCompactor<C, U, CompactStore> *compactor, StateId s) {
+  void Set(const Compactor *compactor, StateId s) {
     arc_compactor_ = compactor->GetArcCompactor();
     s_ = s;
     has_final_ = false;
@@ -689,12 +747,12 @@ class DefaultCompactState<C, U, DefaultCompactStore<typename C::Element, U>> {
 
   size_t NumArcs() const { return num_arcs_; }
 
-  Arc GetArc(size_t i, uint32 f) const {
-    return arc_compactor_->Expand(s_, compacts_[i], f);
+  Arc GetArc(size_t i, uint8 flags) const {
+    return arc_compactor_->Expand(s_, compacts_[i], flags);
   }
 
  private:
-  void Init(const DefaultCompactor<C, U, CompactStore> *compactor) {
+  void Init(const Compactor *compactor) {
     const auto *store = compactor->GetCompactStore();
     U offset;
     if (!compactor->HasFixedOutdegree()) {  // Variable out-degree compactor.
@@ -716,24 +774,28 @@ class DefaultCompactState<C, U, DefaultCompactStore<typename C::Element, U>> {
   }
 
  private:
-  const C *arc_compactor_ = nullptr;               // Borrowed reference.
-  const typename C::Element *compacts_ = nullptr;  // Borrowed reference.
+  const ArcCompactor *arc_compactor_ = nullptr;  // Borrowed reference.
+  const typename ArcCompactor::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;
-
 template <class F, class G>
 void Cast(const F &, G *);
 
+template <class CompactArcFST, class FST>
+bool WriteCompactArcFst(
+    const FST &fst,
+    const typename CompactArcFST::Compactor::ArcCompactor &arc_compactor,
+    std::ostream &strm, const FstWriteOptions &opts);
+
 namespace internal {
 
 // Implementation class for CompactFst, which contains parametrizeable
 // Fst data storage (DefaultCompactStore by default) and Fst cache.
+// C's copy constructor must make a thread-safe copy.
 template <class Arc, class C, class CacheStore = DefaultCacheStore<Arc>>
 class CompactFstImpl
     : public CacheBaseImpl<typename CacheStore::State, CacheStore> {
@@ -768,7 +830,7 @@ class CompactFstImpl
   CompactFstImpl(const Fst<Arc> &fst, std::shared_ptr<Compactor> compactor,
                  const CompactFstOptions &opts)
       : ImplBase(opts),
-        compactor_(std::make_shared<Compactor>(fst, compactor)) {
+        compactor_(std::make_shared<Compactor>(fst, std::move(compactor))) {
     SetType(Compactor::Type());
     SetInputSymbols(fst.InputSymbols());
     SetOutputSymbols(fst.OutputSymbols());
@@ -783,19 +845,20 @@ class CompactFstImpl
       SetProperties(kError, kError);
       return;
     }
-    SetProperties(copy_properties | kStaticProperties);
+    SetProperties(compactor_->Properties(copy_properties) | kStaticProperties);
   }
 
   CompactFstImpl(std::shared_ptr<Compactor> compactor,
                  const CompactFstOptions &opts)
-      : ImplBase(opts),
-        compactor_(compactor) {
+      : ImplBase(opts), compactor_(std::move(compactor)) {
     SetType(Compactor::Type());
-    SetProperties(kStaticProperties | compactor_->Properties());
+    SetProperties(kStaticProperties | compactor_->Properties(0));
     if (compactor_->Error()) SetProperties(kError, kError);
   }
 
-  CompactFstImpl(const CompactFstImpl<Arc, Compactor, CacheStore> &impl)
+  // Makes a thread-safe copy; requires that Compactor's copy constructor
+  // does so as well.
+  CompactFstImpl(const CompactFstImpl &impl)
       : ImplBase(impl),
         compactor_(impl.compactor_ == nullptr ?
                    std::make_shared<Compactor>() :
@@ -806,13 +869,14 @@ class CompactFstImpl
     SetOutputSymbols(impl.OutputSymbols());
   }
 
-  // Allows to change the cache store from OtherI to I.
+  // Allows to change the cache store from OtherCacheStore to CacheStore.
   template <class OtherCacheStore>
-  CompactFstImpl(const CompactFstImpl<Arc, Compactor, OtherCacheStore> &impl)
+  explicit CompactFstImpl(
+      const CompactFstImpl<Arc, Compactor, OtherCacheStore> &impl)
       : ImplBase(CacheOptions(impl.GetCacheGc(), impl.GetCacheLimit())),
-        compactor_(impl.compactor_ == nullptr ?
-                   std::make_shared<Compactor>() :
-                   std::make_shared<Compactor>(*impl.compactor_)) {
+        compactor_(impl.compactor_ == nullptr
+                       ? std::make_shared<Compactor>()
+                       : std::make_shared<Compactor>(*impl.compactor_)) {
     SetType(impl.Type());
     SetProperties(impl.Properties());
     SetInputSymbols(impl.InputSymbols());
@@ -855,23 +919,23 @@ class CompactFstImpl
 
   size_t CountEpsilons(StateId s, bool output_epsilons) {
     compactor_->SetState(s, &state_);
-    const uint32 f = output_epsilons ? kArcOLabelValue : kArcILabelValue;
+    const uint8 flags = output_epsilons ? kArcOLabelValue : kArcILabelValue;
     size_t num_eps = 0;
-    for (size_t i = 0; i < state_.NumArcs(); ++i) {
-      const auto& arc = state_.GetArc(i, f);
+    const size_t num_arcs = state_.NumArcs();
+    for (size_t i = 0; i < num_arcs; ++i) {
+      const auto &arc = state_.GetArc(i, flags);
       const auto label = output_epsilons ? arc.olabel : arc.ilabel;
-      if (label == 0)
+      if (label == 0) {
         ++num_eps;
-      else if (label > 0)
+      } else if (label > 0) {
         break;
+      }
     }
     return num_eps;
   }
 
-  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>());
+  static CompactFstImpl *Read(std::istream &strm, const FstReadOptions &opts) {
+    std::unique_ptr<CompactFstImpl> impl(new CompactFstImpl);
     FstHeader hdr;
     if (!impl->ReadHeader(strm, opts, kMinFileVersion, &hdr)) {
       return nullptr;
@@ -912,7 +976,8 @@ class CompactFstImpl
 
   void Expand(StateId s) {
     compactor_->SetState(s, &state_);
-    for (size_t i = 0; i < state_.NumArcs(); ++i)
+    const size_t num_arcs = state_.NumArcs();
+    for (size_t i = 0; i < num_arcs; ++i)
       PushArc(s, state_.GetArc(i, kArcValueFlags));
     SetArcs(s);
     if (!HasFinal(s)) SetFinal(s, state_.Final());
@@ -924,7 +989,7 @@ class CompactFstImpl
     // TODO(allauzen): is this correct? is this needed?
     // TODO(allauzen): consider removing and forcing this through direct calls
     // to compactor.
-    compactor_ = compactor;
+    compactor_ = std::move(compactor);
   }
 
   // Properties always true of this FST class.
@@ -942,10 +1007,12 @@ class CompactFstImpl
   }
 
  private:
-  // Allows access during write.
-  template <class AnyArc, class ArcCompactor, class Unsigned,
-            class CompactStore, class AnyCacheStore>
-  friend class ::fst::CompactFst;  // allow access during write.
+  // For k*Version constants.
+  template <class CompactArcFST, class FST>
+  friend bool ::fst::WriteCompactArcFst(
+      const FST &fst,
+      const typename CompactArcFST::Compactor::ArcCompactor &arc_compactor,
+      std::ostream &strm, const FstWriteOptions &opts);
 
   // Current unaligned file format version.
   static constexpr int kFileVersion = 2;
@@ -970,141 +1037,95 @@ constexpr int CompactFstImpl<Arc, Compactor, CacheStore>::kAlignedFileVersion;
 template <class Arc, class Compactor, class CacheStore>
 constexpr int CompactFstImpl<Arc, Compactor, CacheStore>::kMinFileVersion;
 
+// Returns the compactor for the CompactFst; intended to be called as
+// GetCompactor<CompactorType>(fst), which returns the compactor only if it
+// is of the specified type and otherwise nullptr (via the overload below).
+template <class Compactor, class Arc>
+const Compactor *GetCompactor(const CompactFst<Arc, Compactor> &fst) {
+  return fst.GetCompactor();
+}
+
+template <class Compactor, class Arc>
+const Compactor *GetCompactor(const Fst<Arc> &fst) {
+  return nullptr;
+}
+
 }  // namespace internal
 
 // This class attaches interface to implementation and handles reference
-// 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 ArcCompactor, class Unsigned, class CompactStore,
-          class CacheStore>
+// counting, delegating most methods to ImplToExpandedFst.
+// (Template argument defaults are declared in fst-decl.h.)
+template <class A, class C, class CacheStore>
 class CompactFst
-    : public ImplToExpandedFst<internal::CompactFstImpl<
-          A,
-          DefaultCompactor<ArcCompactor, Unsigned, CompactStore>,
-          CacheStore>> {
+    : public ImplToExpandedFst<internal::CompactFstImpl<A, C, CacheStore>> {
  public:
   template <class F, class G>
   void friend Cast(const F &, G *);
 
   using Arc = A;
-  using StateId = typename A::StateId;
-  using Compactor = DefaultCompactor<ArcCompactor, Unsigned, CompactStore>;
-  using Impl = internal::CompactFstImpl<A, Compactor, CacheStore>;
+  using StateId = typename Arc::StateId;
+  using Compactor = C;
+  using Impl = internal::CompactFstImpl<Arc, Compactor, CacheStore>;
   using Store = CacheStore;  // for CacheArcIterator
 
-  friend class StateIterator<
-      CompactFst<A, ArcCompactor, Unsigned, CompactStore, CacheStore>>;
-  friend class ArcIterator<
-      CompactFst<A, ArcCompactor, Unsigned, CompactStore, CacheStore>>;
+  // These iterators do not need to be friends, but allow specializations
+  // of them to have internal access.
+  friend class StateIterator<CompactFst>;
+  friend class ArcIterator<CompactFst>;
 
   CompactFst() : ImplToExpandedFst<Impl>(std::make_shared<Impl>()) {}
 
-  // If data is not nullptr, it is assumed to be already initialized.
-  explicit CompactFst(
-      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>(
-                    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<ArcCompactor> compactor,
-      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, data),
-                                   opts)) {}
-
-  // The following 2 constructors take as input two iterators delimiting a set
-  // of (already) compacted transitions, starting with the transitions out of
-  // the initial state. The format of the input differs for fixed out-degree
-  // and variable out-degree compactors.
-  //
-  // - For fixed out-degree compactors, the final weight (encoded as a
-  // compacted transition) needs to be given only for final states. All strings
-  // (compactor of size 1) will be assume to be terminated by a final state
-  // even when the final state is not implicitely given.
-  //
-  // - For variable out-degree compactors, the final weight (encoded as a
-  // compacted transition) needs to be given for all states and must appeared
-  // first in the list (for state s, final weight of s, followed by outgoing
-  // transitons in s).
-  //
-  // These 2 constructors allows the direct construction of a CompactFst
-  // without first creating a more memory-hungry regular FST. This is useful
-  // when memory usage is severely constrained.
-  template <class Iterator>
-  explicit CompactFst(const Iterator &begin, const Iterator &end,
-                      const ArcCompactor &compactor = ArcCompactor(),
+  explicit CompactFst(const Fst<Arc> &fst,
                       const CompactFstOptions &opts = CompactFstOptions())
+      : CompactFst(fst, std::make_shared<Compactor>(fst), opts) {}
+
+  CompactFst(const Fst<Arc> &fst, std::shared_ptr<Compactor> compactor,
+             const CompactFstOptions &opts = CompactFstOptions())
       : ImplToExpandedFst<Impl>(
-            std::make_shared<Impl>(
-                std::make_shared<Compactor>(
-                    begin, end, std::make_shared<ArcCompactor>(compactor)),
-                opts)) {}
+            std::make_shared<Impl>(fst, std::move(compactor), opts)) {}
 
-  template <class Iterator>
-  CompactFst(const Iterator &begin, const Iterator &end,
-             std::shared_ptr<ArcCompactor> compactor,
+  // Convenience constructor taking a Compactor rvalue ref.  Avoids
+  // clutter of make_shared<Compactor> at call site.
+  CompactFst(const Fst<Arc> &fst, Compactor &&compactor,
              const CompactFstOptions &opts = CompactFstOptions())
+      : CompactFst(fst, std::make_shared<Compactor>(std::move(compactor)),
+                   opts) {}
+
+  explicit CompactFst(std::shared_ptr<Compactor> compactor,
+                      const CompactFstOptions &opts = CompactFstOptions())
       : ImplToExpandedFst<Impl>(
-            std::make_shared<Impl>(
-                std::make_shared<Compactor>(begin, end, compactor), opts)) {}
+            std::make_shared<Impl>(std::move(compactor), opts)) {}
 
   // See Fst<>::Copy() for doc.
-  CompactFst(
-      const CompactFst<A, ArcCompactor, Unsigned, CompactStore, CacheStore>
-      &fst,
-      bool safe = false)
+  CompactFst(const CompactFst &fst, bool safe = false)
       : ImplToExpandedFst<Impl>(fst, safe) {}
 
   // Get a copy of this CompactFst. See Fst<>::Copy() for further doc.
-  CompactFst<A, ArcCompactor, Unsigned, CompactStore, CacheStore> *Copy(
-      bool safe = false) const override {
-    return new CompactFst<A, ArcCompactor, Unsigned, CompactStore, CacheStore>(
-        *this, safe);
+  CompactFst *Copy(bool safe = false) const override {
+    return new CompactFst(*this, safe);
   }
 
   // Read a CompactFst from an input stream; return nullptr on error
-  static CompactFst<A, ArcCompactor, Unsigned, CompactStore, CacheStore> *Read(
-      std::istream &strm, const FstReadOptions &opts) {
+  static CompactFst *Read(std::istream &strm, const FstReadOptions &opts) {
     auto *impl = Impl::Read(strm, opts);
-    return impl ? new CompactFst<A, ArcCompactor, Unsigned, CompactStore,
-                                 CacheStore>(std::shared_ptr<Impl>(impl))
-                : nullptr;
+    return impl ? new CompactFst(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, ArcCompactor, Unsigned, CompactStore, CacheStore> *Read(
-      const std::string &filename) {
-    auto *impl = ImplToExpandedFst<Impl>::Read(filename);
-    return impl ? new CompactFst<A, ArcCompactor, Unsigned, CompactStore,
-                                 CacheStore>(std::shared_ptr<Impl>(impl))
-                : nullptr;
+  // Empty source reads from standard input
+  static CompactFst *Read(const std::string &source) {
+    auto *impl = ImplToExpandedFst<Impl>::Read(source);
+    return impl ? new CompactFst(std::shared_ptr<Impl>(impl)) : nullptr;
   }
 
   bool Write(std::ostream &strm, const FstWriteOptions &opts) const override {
     return GetImpl()->Write(strm, opts);
   }
 
-  bool Write(const std::string &filename) const override {
-    return Fst<Arc>::WriteFile(filename);
+  bool Write(const std::string &source) const override {
+    return Fst<Arc>::WriteFile(source);
   }
 
-  template <class FST>
-  static bool WriteFst(const FST &fst, const ArcCompactor &compactor,
-                       std::ostream &strm, const FstWriteOptions &opts);
-
   void InitStateIterator(StateIteratorData<Arc> *data) const override {
     GetImpl()->InitStateIterator(data);
   }
@@ -1114,15 +1135,13 @@ class CompactFst
   }
 
   MatcherBase<Arc> *InitMatcher(MatchType match_type) const override {
-    return new SortedMatcher<
-        CompactFst<A, ArcCompactor, Unsigned, CompactStore, CacheStore>>(
-        *this, match_type);
+    return new SortedMatcher<CompactFst>(*this, match_type);
   }
 
-  template <class Iterator>
-  void SetCompactElements(const Iterator &b, const Iterator &e) {
-    GetMutableImpl()->SetCompactor(std::make_shared<Compactor>(
-        b, e, std::make_shared<ArcCompactor>()));
+  const Compactor *GetCompactor() const { return GetImpl()->GetCompactor(); }
+
+  void SetCompactor(std::shared_ptr<Compactor> compactor) {
+    GetMutableImpl()->SetCompactor(std::move(compactor));
   }
 
  private:
@@ -1130,44 +1149,39 @@ class CompactFst
   using ImplToFst<Impl, ExpandedFst<Arc>>::GetMutableImpl;
 
   explicit CompactFst(std::shared_ptr<Impl> impl)
-      : ImplToExpandedFst<Impl>(impl) {}
-
-  // Use overloading to extract the type of the argument.
-  static Impl *GetImplIfCompactFst(
-      const CompactFst<A, ArcCompactor, Unsigned, CompactStore, CacheStore>
-          &compact_fst) {
-    return compact_fst.GetImpl();
-  }
-
-  // This does not give privileged treatment to subclasses of CompactFst.
-  template <typename NonCompactFst>
-  static Impl *GetImplIfCompactFst(const NonCompactFst &fst) {
-    return nullptr;
-  }
+      : ImplToExpandedFst<Impl>(std::move(impl)) {}
 
   CompactFst &operator=(const CompactFst &fst) = delete;
 };
 
-// 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 ArcCompactor, class Unsigned, class CompactStore,
-          class CacheStore>
-template <class FST>
-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;
+// Writes FST in ArcCompacted format, with a possible pass over the machine
+// before writing to compute the number of states and arcs.
+template <class CompactArcFST, class FST>
+bool WriteCompactArcFst(
+    const FST &fst,
+    const typename CompactArcFST::Compactor::ArcCompactor &arc_compactor,
+    std::ostream &strm, const FstWriteOptions &opts) {
+  using Arc = typename CompactArcFST::Arc;
+  using Compactor = typename CompactArcFST::Compactor;
+  using ArcCompactor = typename Compactor::ArcCompactor;
+  using CompactStore = typename Compactor::CompactStore;
   using Element = typename ArcCompactor::Element;
+  using Impl = typename CompactArcFST::Impl;
+  using Unsigned = typename Compactor::Unsigned;
+  using Weight = typename Arc::Weight;
   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->GetCompactor()->GetCompactStore()->NumArcs();
-    num_states = impl->GetCompactor()->GetCompactStore()->NumStates();
-    first_pass_compactor = *impl->GetCompactor()->GetArcCompactor();
+  auto first_pass_arc_compactor = arc_compactor;
+  // Note that GetCompactor will only return non-null if the compactor has the
+  // exact type Compactor == CompactArcFst::Compactor.  This is what we want;
+  // other types must do an extra pass to set the arc compactor state.
+  if (const Compactor *const compactor =
+          internal::GetCompactor<Compactor>(fst)) {
+    num_arcs = compactor->NumArcs();
+    num_states = compactor->NumStates();
+    first_pass_arc_compactor = *compactor->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
@@ -1179,12 +1193,12 @@ bool CompactFst<A, ArcCompactor, Unsigned, CompactStore, CacheStore>::WriteFst(
       const auto s = siter.Value();
       ++num_states;
       if (fst.Final(s) != Weight::Zero()) {
-        first_pass_compactor.Compact(
+        first_pass_arc_compactor.Compact(
             s, Arc(kNoLabel, kNoLabel, fst.Final(s), kNoStateId));
       }
       for (ArcIterator<FST> aiter(fst, s); !aiter.Done(); aiter.Next()) {
         ++num_arcs;
-        first_pass_compactor.Compact(s, aiter.Value());
+        first_pass_arc_compactor.Compact(s, aiter.Value());
       }
     }
   }
@@ -1203,17 +1217,17 @@ bool CompactFst<A, ArcCompactor, Unsigned, CompactStore, CacheStore>::WriteFst(
     type += CompactStore::Type();
   }
   const auto copy_properties = fst.Properties(kCopyProperties, true);
-  if ((copy_properties & kError) || !compactor.Compatible(fst)) {
+  if ((copy_properties & kError) || !arc_compactor.Compatible(fst)) {
     FSTERROR() << "Fst incompatible with compactor";
     return false;
   }
   uint64 properties = copy_properties | Impl::kStaticProperties;
   internal::FstImpl<Arc>::WriteFstHeader(fst, strm, opts, file_version, type,
                                          properties, &hdr);
-  first_pass_compactor.Write(strm);
-  if (first_pass_compactor.Size() == -1) {
+  first_pass_arc_compactor.Write(strm);
+  if (first_pass_arc_compactor.Size() == -1) {
     if (opts.align && !AlignOutput(strm)) {
-      LOG(ERROR) << "CompactFst::Write: Alignment failed: " << opts.source;
+      LOG(ERROR) << "WriteCompactArcFst: Alignment failed: " << opts.source;
       return false;
     }
     Unsigned compacts = 0;
@@ -1230,23 +1244,23 @@ bool CompactFst<A, ArcCompactor, Unsigned, CompactStore, CacheStore>::WriteFst(
   if (opts.align && !AlignOutput(strm)) {
     LOG(ERROR) << "Could not align file during write after writing states";
   }
-  const auto &second_pass_compactor = compactor;
+  const auto &second_pass_arc_compactor = arc_compactor;
   Element element;
   for (StateIterator<FST> siter(fst); !siter.Done(); siter.Next()) {
     const auto s = siter.Value();
     if (fst.Final(s) != Weight::Zero()) {
-      element = second_pass_compactor.Compact(
-          s, A(kNoLabel, kNoLabel, fst.Final(s), kNoStateId));
+      element = second_pass_arc_compactor.Compact(
+          s, Arc(kNoLabel, kNoLabel, fst.Final(s), kNoStateId));
       strm.write(reinterpret_cast<const char *>(&element), sizeof(element));
     }
     for (ArcIterator<FST> aiter(fst, s); !aiter.Done(); aiter.Next()) {
-      element = second_pass_compactor.Compact(s, aiter.Value());
+      element = second_pass_arc_compactor.Compact(s, aiter.Value());
       strm.write(reinterpret_cast<const char *>(&element), sizeof(element));
     }
   }
   strm.flush();
   if (!strm) {
-    LOG(ERROR) << "CompactFst::WriteFst: Write failed: " << opts.source;
+    LOG(ERROR) << "WriteCompactArcFst: Write failed: " << opts.source;
     return false;
   }
   return true;
@@ -1254,17 +1268,13 @@ bool CompactFst<A, ArcCompactor, 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 ArcCompactor, class Unsigned, class CompactStore,
-          class CacheStore>
-class StateIterator<
-    CompactFst<Arc, ArcCompactor, Unsigned, CompactStore, CacheStore>> {
+template <class Arc, class Compactor, class CacheStore>
+class StateIterator<CompactFst<Arc, Compactor, CacheStore>> {
  public:
   using StateId = typename Arc::StateId;
 
-  explicit StateIterator(
-      const CompactFst<Arc, ArcCompactor, Unsigned, CompactStore,
-                       CacheStore> &fst)
-      : nstates_(fst.GetImpl()->NumStates()), s_(0) {}
+  explicit StateIterator(const CompactFst<Arc, Compactor, CacheStore> &fst)
+      : nstates_(fst.NumStates()), s_(0) {}
 
   bool Done() const { return s_ >= nstates_; }
 
@@ -1281,24 +1291,19 @@ class StateIterator<
 
 // Specialization for CompactFst. Never caches,
 // always iterates over the underlying compact elements.
-template <class Arc, class ArcCompactor, class Unsigned,
-          class CompactStore, class CacheStore>
-class ArcIterator<CompactFst<
-    Arc, ArcCompactor, Unsigned, CompactStore, CacheStore>> {
+template <class Arc, class Compactor, class CacheStore>
+class ArcIterator<CompactFst<Arc, Compactor, CacheStore>> {
  public:
   using StateId = typename Arc::StateId;
-  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),
+  ArcIterator(const CompactFst<Arc, Compactor, CacheStore> &fst, StateId s)
+      : state_(fst.GetCompactor(), s),
         pos_(0),
+        num_arcs_(state_.NumArcs()),
         flags_(kArcValueFlags) {}
 
-  bool Done() const { return pos_ >= state_.NumArcs(); }
+  bool Done() const { return pos_ >= num_arcs_; }
 
   const Arc &Value() const {
     arc_ = state_.GetArc(pos_, flags_);
@@ -1313,18 +1318,20 @@ class ArcIterator<CompactFst<
 
   void Seek(size_t pos) { pos_ = pos; }
 
-  uint32 Flags() const { return flags_; }
+  uint8 Flags() const { return flags_; }
 
-  void SetFlags(uint32 f, uint32 m) {
-    flags_ &= ~m;
-    flags_ |= (f & kArcValueFlags);
+  void SetFlags(uint8 flags, uint8 mask) {
+    flags_ &= ~mask;
+    flags_ |= (flags & kArcValueFlags);
   }
 
  private:
   State state_;
   size_t pos_;
+  // Cache the value of NumArcs(), since it is used in Done() and may be slow.
+  size_t num_arcs_;
   mutable Arc arc_;
-  uint32 flags_;
+  uint8 flags_;
 };
 
 // ArcCompactor for unweighted string FSTs.
@@ -1340,7 +1347,7 @@ class StringCompactor {
 
   Element Compact(StateId s, const Arc &arc) const { return arc.ilabel; }
 
-  Arc Expand(StateId s, const Element &p, uint32 f = kArcValueFlags) const {
+  Arc Expand(StateId s, const Element &p, uint8 flags = kArcValueFlags) const {
     return Arc(p, p, Weight::One(), p != kNoLabel ? s + 1 : kNoStateId);
   }
 
@@ -1380,7 +1387,7 @@ class WeightedStringCompactor {
     return std::make_pair(arc.ilabel, arc.weight);
   }
 
-  Arc Expand(StateId s, const Element &p, uint32 f = kArcValueFlags) const {
+  Arc Expand(StateId s, const Element &p, uint8 flags = kArcValueFlags) const {
     return Arc(p.first, p.first, p.second,
                p.first != kNoLabel ? s + 1 : kNoStateId);
   }
@@ -1421,7 +1428,7 @@ class UnweightedAcceptorCompactor {
     return std::make_pair(arc.ilabel, arc.nextstate);
   }
 
-  Arc Expand(StateId s, const Element &p, uint32 f = kArcValueFlags) const {
+  Arc Expand(StateId s, const Element &p, uint8 flags = kArcValueFlags) const {
     return Arc(p.first, p.first, Weight::One(), p.second);
   }
 
@@ -1463,7 +1470,7 @@ class AcceptorCompactor {
                           arc.nextstate);
   }
 
-  Arc Expand(StateId s, const Element &p, uint32 f = kArcValueFlags) const {
+  Arc Expand(StateId s, const Element &p, uint8 flags = kArcValueFlags) const {
     return Arc(p.first.first, p.first.first, p.first.second, p.second);
   }
 
@@ -1504,7 +1511,7 @@ class UnweightedCompactor {
                           arc.nextstate);
   }
 
-  Arc Expand(StateId s, const Element &p, uint32 f = kArcValueFlags) const {
+  Arc Expand(StateId s, const Element &p, uint8 flags = kArcValueFlags) const {
     return Arc(p.first.first, p.first.second, Weight::One(), p.second);
   }
 
@@ -1530,22 +1537,22 @@ class UnweightedCompactor {
 };
 
 template <class Arc, class Unsigned /* = uint32 */>
-using CompactStringFst = CompactFst<Arc, StringCompactor<Arc>, Unsigned>;
+using CompactStringFst = CompactArcFst<Arc, StringCompactor<Arc>, Unsigned>;
 
 template <class Arc, class Unsigned /* = uint32 */>
 using CompactWeightedStringFst =
-    CompactFst<Arc, WeightedStringCompactor<Arc>, Unsigned>;
+    CompactArcFst<Arc, WeightedStringCompactor<Arc>, Unsigned>;
 
 template <class Arc, class Unsigned /* = uint32 */>
-using CompactAcceptorFst = CompactFst<Arc, AcceptorCompactor<Arc>, Unsigned>;
+using CompactAcceptorFst = CompactArcFst<Arc, AcceptorCompactor<Arc>, Unsigned>;
 
 template <class Arc, class Unsigned /* = uint32 */>
 using CompactUnweightedFst =
-    CompactFst<Arc, UnweightedCompactor<Arc>, Unsigned>;
+    CompactArcFst<Arc, UnweightedCompactor<Arc>, Unsigned>;
 
 template <class Arc, class Unsigned /* = uint32 */>
 using CompactUnweightedAcceptorFst =
-    CompactFst<Arc, UnweightedAcceptorCompactor<Arc>, Unsigned>;
+    CompactArcFst<Arc, UnweightedAcceptorCompactor<Arc>, Unsigned>;
 
 using StdCompactStringFst = CompactStringFst<StdArc, uint32>;
 
@@ -1558,6 +1565,22 @@ using StdCompactUnweightedFst = CompactUnweightedFst<StdArc, uint32>;
 using StdCompactUnweightedAcceptorFst =
     CompactUnweightedAcceptorFst<StdArc, uint32>;
 
+// Convenience function to make a CompactStringFst from a sequence
+// of Arc::Labels.  LabelIterator must be an input iterator.
+template <class Arc, class Unsigned = uint32, class LabelIterator>
+inline CompactStringFst<Arc, Unsigned> MakeCompactStringFst(
+    const LabelIterator begin, const LabelIterator end) {
+  using CompactStringFst = CompactStringFst<Arc, Unsigned>;
+  using Compactor = typename CompactStringFst::Compactor;
+  return CompactStringFst(std::make_shared<Compactor>(begin, end));
+}
+
+template <class LabelIterator>
+inline StdCompactStringFst MakeStdCompactStringFst(const LabelIterator begin,
+                                                   const LabelIterator end) {
+  return MakeCompactStringFst<StdArc>(begin, end);
+}
+
 }  // namespace fst
 
 #endif  // FST_COMPACT_FST_H_
index ba1afd0..d44e79c 100644 (file)
 #include <cstdlib>
 #include <cstring>
 #include <iostream>
+#include <memory>
 #include <string>
+#include <type_traits>
+#include <utility>
 #include <vector>
 
 #if defined(__GNUC__) || defined(__clang__)
@@ -43,8 +46,10 @@ void FailedNewHandler();
 namespace fst {
 
 // Downcasting.
-template<typename To, typename From>
-inline To down_cast(From* f) { return static_cast<To>(f); }
+template <typename To, typename From>
+inline To down_cast(From *f) {
+  return static_cast<To>(f);
+}
 
 // Bitcasting.
 template <class Dest, class Source>
@@ -56,35 +61,21 @@ inline Dest bit_cast(const Source &source) {
   return dest;
 }
 
-// Check sums
+// Checksums.
 class CheckSummer {
  public:
-  CheckSummer() : count_(0) {
-    check_sum_.resize(kCheckSumLength, '\0');
-  }
-
-  void Reset() {
-    count_ = 0;
-    for (int i = 0; i < kCheckSumLength; ++i) check_sum_[i] = '\0';
-  }
-
-  void Update(void const *data, int size) {
-    const char *p = reinterpret_cast<const char *>(data);
-    for (int i = 0; i < size; ++i) {
-      check_sum_[(count_++) % kCheckSumLength] ^= p[i];
-    }
-  }
-
-  void Update(std::string const &data) {
-    for (int i = 0; i < data.size(); ++i) {
-      check_sum_[(count_++) % kCheckSumLength] ^= data[i];
-    }
-  }
+  CheckSummer();
+
+  void Reset();
+
+  void Update(void const *data, int size);
+
+  void Update(std::string const &data);
 
   std::string Digest() { return check_sum_; }
 
  private:
-  static const int kCheckSumLength = 32;
+  constexpr static int kCheckSumLength = 32;
   int count_;
   std::string check_sum_;
 
@@ -92,6 +83,58 @@ class CheckSummer {
   CheckSummer &operator=(const CheckSummer &) = delete;
 };
 
+// Defines make_unique and make_unique_default_init using a standard definition
+// that should be compatible with the C++14 and C++20 (respectively)
+// definitions.
+// TODO(kbg): Remove these once we migrate to C++14 and C++20.
+
+template <typename T, typename... Args>
+std::unique_ptr<T> make_unique(Args &&... args) {
+  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
+}
+
+template <typename T>
+std::unique_ptr<T[]> make_unique(size_t n) {
+  return std::unique_ptr<T>(new typename std::remove_extent<T>::type[n]());
+}
+
+template <typename T>
+std::unique_ptr<T> make_unique_default_init() {
+  return std::unique_ptr<T>(new T);
+}
+
+template <typename T>
+std::unique_ptr<T[]> make_unique_default_init(size_t n) {
+  return std::unique_ptr<T>(new typename std::remove_extent<T>::type[n]);
+}
+
+template <typename T>
+std::unique_ptr<T> WrapUnique(T *ptr) {
+  return std::unique_ptr<T>(ptr);
+}
+
+// String munging.
+
+std::string StringJoin(const std::vector<std::string> &elements,
+                       const std::string &delim);
+
+std::string StringJoin(const std::vector<std::string> &elements,
+                       const char *delim);
+
+std::string StringJoin(const std::vector<std::string> &elements, char delim);
+
+std::vector<std::string> StringSplit(const std::string &full,
+                                     const std::string &delim);
+
+std::vector<std::string> StringSplit(const std::string &full,
+                                     const char *delim);
+
+std::vector<std::string> StringSplit(const std::string &full, char delim);
+
+void StripTrailingAsciiWhitespace(std::string *full);
+
+std::string StripTrailingAsciiWhitespace(const std::string &full);
+
 }  // namespace fst
 
 #endif  // FST_LIB_COMPAT_H_
index 13145e5..fa097bf 100644 (file)
@@ -50,7 +50,7 @@ class ComplementFstImpl : public FstImpl<A> {
 
   explicit ComplementFstImpl(const Fst<Arc> &fst) : fst_(fst.Copy()) {
     SetType("complement");
-    uint64 props = fst.Properties(kILabelSorted, false);
+    const auto props = fst.Properties(kILabelSorted, false);
     SetProperties(ComplementProperties(props), kCopyProperties);
     SetInputSymbols(fst.InputSymbols());
     SetOutputSymbols(fst.OutputSymbols());
@@ -66,7 +66,7 @@ class ComplementFstImpl : public FstImpl<A> {
 
   StateId Start() const {
     if (Properties(kError)) return kNoStateId;
-    auto start = fst_->Start();
+    const auto start = fst_->Start();
     return start != kNoStateId ? start + 1 : 0;
   }
 
@@ -247,9 +247,9 @@ class ArcIterator<ComplementFst<Arc>> : public ArcIteratorBase<Arc> {
     pos_ = a;
   }
 
-  uint32 Flags() const final { return kArcValueFlags; }
+  uint8 Flags() const final { return kArcValueFlags; }
 
-  void SetFlags(uint32, uint32) final {}
+  void SetFlags(uint8, uint8) final {}
 
  private:
   std::unique_ptr<ArcIterator<Fst<Arc>>> aiter_;
index 1066d09..a2a50c8 100644 (file)
@@ -143,10 +143,10 @@ class ComposeFstImplBase
   using CacheImpl::SetFinal;
   using CacheImpl::SetStart;
 
-  ComposeFstImplBase(const CacheImplOptions<CacheStore> &opts)
+  explicit ComposeFstImplBase(const CacheImplOptions<CacheStore> &opts)
       : CacheImpl(opts) {}
 
-  ComposeFstImplBase(const CacheOptions &opts) : CacheImpl(opts) {}
+  explicit ComposeFstImplBase(const CacheOptions &opts) : CacheImpl(opts) {}
 
   ComposeFstImplBase(const ComposeFstImplBase &impl) : CacheImpl(impl, true) {
     SetType(impl.Type());
index 74d22c2..8ff9227 100644 (file)
@@ -9,6 +9,7 @@
 #include <algorithm>
 #include <vector>
 
+#include <fst/expanded-fst.h>
 #include <fst/mutable-fst.h>
 #include <fst/rational.h>
 
@@ -77,6 +78,13 @@ void Concat(MutableFst<Arc> *fst1, const Fst<Arc> &fst2) {
   }
 }
 
+// Computes the concatentation of two FSTs. This version modifies its
+// RationalFst input (in first position).
+template <class Arc>
+void Concat(RationalFst<Arc> *fst1, const Fst<Arc> &fst2) {
+  fst1->GetMutableImpl()->AddConcat(fst2, true);
+}
+
 // Computes the concatentation of two FSTs.  This version modifies its
 // MutableFst argument (in second position).
 //
@@ -134,11 +142,12 @@ void Concat(const Fst<Arc> &fst1, MutableFst<Arc> *fst2) {
   }
 }
 
-// Computes the concatentation of two FSTs. This version modifies its
-// RationalFst input (in first position).
+// Same as the above but can handle arbitrarily many left-hand-side FSTs,
+// preallocating the states.
 template <class Arc>
-void Concat(RationalFst<Arc> *fst1, const Fst<Arc> &fst2) {
-  fst1->GetMutableImpl()->AddConcat(fst2, true);
+void Concat(const std::vector<const Fst<Arc> *> &fsts1, MutableFst<Arc> *fst2) {
+  fst2->ReserveStates(CountStates(fsts1) + fst2->NumStates());
+  for (const auto *fst1 : fsts1) Concat(*fst1, fst2);
 }
 
 // Computes the concatentation of two FSTs. This version modifies its
index 8d53f2b..902f3d8 100644 (file)
@@ -273,10 +273,10 @@ class ConstFst : public ImplToExpandedFst<internal::ConstFstImpl<A, Unsigned>> {
                 : nullptr;
   }
 
-  // Read a ConstFst from a file; return nullptr on error; empty filename reads
+  // Read a ConstFst from a file; return nullptr on error; empty source reads
   // from standard input.
-  static ConstFst<A, Unsigned> *Read(const std::string &filename) {
-    auto *impl = ImplToExpandedFst<Impl>::Read(filename);
+  static ConstFst<A, Unsigned> *Read(const std::string &source) {
+    auto *impl = ImplToExpandedFst<Impl>::Read(source);
     return impl ? new ConstFst<A, Unsigned>(std::shared_ptr<Impl>(impl))
                 : nullptr;
   }
@@ -285,8 +285,8 @@ class ConstFst : public ImplToExpandedFst<internal::ConstFstImpl<A, Unsigned>> {
     return WriteFst(*this, strm, opts);
   }
 
-  bool Write(const std::string &filename) const override {
-    return Fst<Arc>::WriteFile(filename);
+  bool Write(const std::string &source) const override {
+    return Fst<Arc>::WriteFile(source);
   }
 
   template <class FST>
@@ -467,9 +467,9 @@ class ArcIterator<ConstFst<Arc, Unsigned>> {
 
   void Seek(size_t a) { i_ = a; }
 
-  constexpr uint32 Flags() const { return kArcValueFlags; }
+  constexpr uint8 Flags() const { return kArcValueFlags; }
 
-  void SetFlags(uint32, uint32) {}
+  void SetFlags(uint8, uint8) {}
 
  private:
   const Arc *arcs_;
index 8613699..1473908 100644 (file)
@@ -714,12 +714,15 @@ class DeterminizeFsaImpl : public DeterminizeFstImplBase<Arc> {
   const std::vector<Weight> *in_dist_;  // Distance to final NFA states.
   std::vector<Weight> *out_dist_;       // Distance to final DFA states.
 
-  // FIXME(kbg): Ought to be static const?
-  CommonDivisor common_divisor_;
+  static const CommonDivisor common_divisor_;
   std::unique_ptr<Filter> filter_;
   std::unique_ptr<StateTable> state_table_;
 };
 
+template <class Arc, class CommonDivisor, class Filter, class StateTable>
+const CommonDivisor DeterminizeFsaImpl<Arc, CommonDivisor, Filter,
+                                       StateTable>::common_divisor_{};
+
 // Implementation of delayed determinization for transducers. Transducer
 // determinization is implemented by mapping the input to the Gallic semiring as
 // an acceptor whose weights contain the output strings and using acceptor
@@ -864,7 +867,7 @@ class DeterminizeFst : public ImplToFst<internal::DeterminizeFstImplBase<A>> {
       : ImplToFst<Impl>(CreateImpl(fst)) {}
 
   template <class CommonDivisor, class Filter, class StateTable>
-  DeterminizeFst(
+  explicit DeterminizeFst(
       const Fst<Arc> &fst,
       const DeterminizeFstOptions<Arc, CommonDivisor, Filter, StateTable>
           &opts =
index b0fba3a..0eb90b0 100644 (file)
@@ -670,11 +670,11 @@ class EditFst : public ImplToMutableFst<
     return impl ? new EditFst<Arc>(std::shared_ptr<Impl>(impl)) : nullptr;
   }
 
-  // Reads an EditFst from a file, returning nullptr on error. If the filename
+  // Reads an EditFst from a file, returning nullptr on error. If the source
   // argument is an empty string, it reads from standard input.
   static EditFst<Arc, WrappedFstT, MutableFstT> *Read(
-      const std::string &filename) {
-    auto *impl = ImplToExpandedFst<Impl, MutableFst<Arc>>::Read(filename);
+      const std::string &source) {
+    auto *impl = ImplToExpandedFst<Impl, MutableFst<Arc>>::Read(source);
     return impl ? new EditFst<Arc, WrappedFstT, MutableFstT>(
                       std::shared_ptr<Impl>(impl))
                 : nullptr;
@@ -684,8 +684,8 @@ class EditFst : public ImplToMutableFst<
     return GetImpl()->Write(strm, opts);
   }
 
-  bool Write(const std::string &filename) const override {
-    return Fst<Arc>::WriteFile(filename);
+  bool Write(const std::string &source) const override {
+    return Fst<Arc>::WriteFile(source);
   }
 
   void InitStateIterator(StateIteratorData<Arc> *data) const override {
index 14e307d..2b19edd 100644 (file)
 #include <vector>
 
 #include <fst/log.h>
-#include <fstream>
-
 #include <fst/arc-map.h>
+#include <fstream>
 #include <fst/rmfinalepsilon.h>
 
-
 namespace fst {
 
 enum EncodeType { ENCODE = 1, DECODE = 2 };
 
-static constexpr uint32 kEncodeLabels = 0x0001;
-static constexpr uint32 kEncodeWeights = 0x0002;
-static constexpr uint32 kEncodeFlags = 0x0003;
+static constexpr uint8 kEncodeLabels = 0x01;
+static constexpr uint8 kEncodeWeights = 0x02;
+static constexpr uint8 kEncodeFlags = 0x03;
 
 namespace internal {
 
-static constexpr uint32 kEncodeHasISymbols = 0x0004;
-static constexpr uint32 kEncodeHasOSymbols = 0x0008;
+// Bits storing whether or not an encode table has input and/or output symbol
+// tables, for internal use only.
+static constexpr uint8 kEncodeHasISymbols = 0x04;
+static constexpr uint8 kEncodeHasOSymbols = 0x08;
+
+// Identifies stream data as an encode table (and its endianity).
+static const int32 kEncodeMagicNumber = 2128178506;
+// TODO(b/141172858): deprecated, remove by 2020-01-01.
+static const int32 kEncodeDeprecatedMagicNumber = 2129983209;
+
+}  // namespace internal
+
+// Header for the encoder table.
+class EncodeTableHeader {
+ public:
+  EncodeTableHeader() = default;
+
+  // Getters.
+
+  const std::string &ArcType() const { return arctype_; }
+
+  uint8 Flags() const { return flags_; }
+
+  size_t Size() const { return size_; }
+
+  // Setters.
 
-// Identifies stream data as an encode table (and its endianity)
-static const int32 kEncodeMagicNumber = 2129983209;
+  void SetArcType(const std::string &arctype) { arctype_ = arctype; }
+
+  void SetFlags(uint8 flags) { flags_ = flags; }
+
+  void SetSize(size_t size) { size_ = size; }
+
+  // IO.
+
+  bool Read(std::istream &strm, const std::string &source);
+
+  bool Write(std::ostream &strm, const std::string &source) const;
+
+ private:
+  std::string arctype_;
+  uint8 flags_;
+  size_t size_;
+};
+
+namespace internal {
 
 // The following class encapsulates implementation details for the encoding and
-// decoding of label/weight tuples used for encoding and decoding of FSTs. The
-// EncodeTable is bidirectional. I.e, it stores both the Tuple of encode labels
+// decoding of label/weight triples used for encoding and decoding of FSTs. The
+// EncodeTable is bidirectional, i.e, it stores both the Triple of encode labels
 // and weights to a unique label, and the reverse.
 template <class Arc>
 class EncodeTable {
@@ -47,99 +86,104 @@ class EncodeTable {
   using Weight = typename Arc::Weight;
 
   // Encoded data consists of arc input/output labels and arc weight.
-  struct Tuple {
-    Tuple() {}
-
-    Tuple(Label ilabel_, Label olabel_, Weight weight_)
-        : ilabel(ilabel_), olabel(olabel_), weight(std::move(weight_)) {}
+  struct Triple {
+    Triple() = default;
+
+    Triple(Label ilabel, Label olabel, Weight weight)
+        : ilabel(ilabel), olabel(olabel), weight(std::move(weight)) {}
+
+    // Constructs from arc and flags.
+    Triple(const Arc &arc, uint8 flags)
+        : ilabel(arc.ilabel),
+          olabel(flags & kEncodeLabels ? arc.olabel : 0),
+          weight(flags & kEncodeWeights ? arc.weight : Weight::One()) {}
+
+    static std::unique_ptr<Triple> Read(std::istream &strm) {
+      auto triple = fst::make_unique<Triple>();
+      ReadType(strm, &triple->ilabel);
+      ReadType(strm, &triple->olabel);
+      ReadType(strm, &triple->weight);
+      return triple;
+    }
 
-    Tuple(const Tuple &tuple)
-        : ilabel(tuple.ilabel),
-          olabel(tuple.olabel),
-          weight(std::move(tuple.weight)) {}
+    // Exploited below for TripleEqual functor.
+    bool operator==(const Triple &other) const {
+      return (ilabel == other.ilabel && olabel == other.olabel &&
+              weight == other.weight);
+    }
 
     Label ilabel;
     Label olabel;
     Weight weight;
   };
 
-  // Comparison object for hashing EncodeTable Tuple(s).
-  class TupleEqual {
-   public:
-    bool operator()(const Tuple *x, const Tuple *y) const {
-      return (x->ilabel == y->ilabel && x->olabel == y->olabel &&
-              x->weight == y->weight);
-    }
+  // Equality functor for two Triple pointers.
+  struct TripleEqual {
+    bool operator()(const Triple *x, const Triple *y) const { return *x == *y; }
   };
 
-  // Hash function for EncodeTabe Tuples. Based on the encode flags
-  // we either hash the labels, weights or combination of them.
-  class TupleKey {
+  // Hash functor for one Triple pointer.
+  class TripleHash {
    public:
-    TupleKey() : encode_flags_(kEncodeLabels | kEncodeWeights) {}
-
-    TupleKey(const TupleKey &key) : encode_flags_(key.encode_flags_) {}
+    explicit TripleHash(uint8 flags) : flags_(flags) {}
 
-    explicit TupleKey(uint32 encode_flags) : encode_flags_(encode_flags) {}
-
-    size_t operator()(const Tuple *x) const {
-      size_t hash = x->ilabel;
+    size_t operator()(const Triple *triple) const {
+      size_t hash = triple->ilabel;
       static constexpr int lshift = 5;
       static constexpr int rshift = CHAR_BIT * sizeof(size_t) - 5;
-      if (encode_flags_ & kEncodeLabels) {
-        hash = hash << lshift ^ hash >> rshift ^ x->olabel;
+      if (flags_ & kEncodeLabels) {
+        hash = hash << lshift ^ hash >> rshift ^ triple->olabel;
       }
-      if (encode_flags_ & kEncodeWeights) {
-        hash = hash << lshift ^ hash >> rshift ^ x->weight.Hash();
+      if (flags_ & kEncodeWeights) {
+        hash = hash << lshift ^ hash >> rshift ^ triple->weight.Hash();
       }
       return hash;
     }
 
    private:
-    int32 encode_flags_;
+    uint8 flags_;
   };
 
-  explicit EncodeTable(uint32 encode_flags)
-      : flags_(encode_flags), encode_hash_(1024, TupleKey(encode_flags)) {}
-
-  using EncodeHash = std::unordered_map<const Tuple *, Label, TupleKey,
-                                        TupleEqual>;
+  explicit EncodeTable(uint8 flags)
+      : flags_(flags), triple2label_(1024, TripleHash(flags)) {}
 
   // Given an arc, encodes either input/output labels or input/costs or both.
   Label Encode(const Arc &arc) {
-    std::unique_ptr<Tuple> tuple(
-        new Tuple(arc.ilabel, flags_ & kEncodeLabels ? arc.olabel : 0,
-                  flags_ & kEncodeWeights ? arc.weight : Weight::One()));
-    auto insert_result =
-        encode_hash_.emplace(tuple.get(), encode_tuples_.size() + 1);
-    if (insert_result.second) encode_tuples_.push_back(std::move(tuple));
-    return insert_result.first->second;
+    // Encoding weights of a weighted superfinal transition could result in
+    // a clash with a true epsilon arc; to avoid this we hallucinate kNoLabel
+    // labels instead.
+    if (arc.nextstate == kNoStateId && (flags_ & kEncodeWeights)) {
+      return Encode(fst::make_unique<Triple>(kNoLabel, kNoLabel, arc.weight));
+    } else {
+      return Encode(fst::make_unique<Triple>(arc, flags_));
+    }
   }
 
   // Given an arc, looks up its encoded label or returns kNoLabel if not found.
   Label GetLabel(const Arc &arc) const {
-    const Tuple tuple(arc.ilabel, flags_ & kEncodeLabels ? arc.olabel : 0,
-                      flags_ & kEncodeWeights ? arc.weight : Weight::One());
-    auto it = encode_hash_.find(&tuple);
-    return (it == encode_hash_.end()) ?  kNoLabel : it->second;
+    const Triple triple(arc, flags_);
+    auto it = triple2label_.find(&triple);
+    return (it == triple2label_.end()) ? kNoLabel : it->second;
   }
 
   // Given an encoded arc label, decodes back to input/output labels and costs.
-  const Tuple *Decode(Label key) const {
-    if (key < 1 || key > encode_tuples_.size()) {
-      LOG(ERROR) << "EncodeTable::Decode: Unknown decode key: " << key;
+  const Triple *Decode(Label label) const {
+    if (label < 1 || label > triples_.size()) {
+      LOG(ERROR) << "EncodeTable::Decode: Unknown decode label: " << label;
       return nullptr;
     }
-    return encode_tuples_[key - 1].get();
+    return triples_[label - 1].get();
   }
 
-  size_t Size() const { return encode_tuples_.size(); }
+  size_t Size() const { return triples_.size(); }
+
+  static EncodeTable<Arc> *Read(std::istream &strm, const std::string &source);
 
   bool Write(std::ostream &strm, const std::string &source) const;
 
-  static EncodeTable<Arc> *Read(std::istream &strm, const std::string &source);
+  // This is masked to hide internal-only isymbol and osymbol bits.
 
-  uint32 Flags() const { return flags_ & kEncodeFlags; }
+  uint8 Flags() const { return flags_ & kEncodeFlags; }
 
   const SymbolTable *InputSymbols() const { return isymbols_.get(); }
 
@@ -166,68 +210,39 @@ class EncodeTable {
   }
 
  private:
-  uint32 flags_;
-  std::vector<std::unique_ptr<Tuple>> encode_tuples_;
-  EncodeHash encode_hash_;
-  std::unique_ptr<SymbolTable> isymbols_;  // Pre-encoded input symbol table.
-  std::unique_ptr<SymbolTable> osymbols_;  // Pre-encoded output symbol table.
+  Label Encode(std::unique_ptr<Triple> triple) {
+    auto insert_result =
+        triple2label_.emplace(triple.get(), triples_.size() + 1);
+    if (insert_result.second) triples_.push_back(std::move(triple));
+    return insert_result.first->second;
+  }
+
+  uint8 flags_;
+  std::vector<std::unique_ptr<Triple>> triples_;
+  std::unordered_map<const Triple *, Label, TripleHash, TripleEqual>
+      triple2label_;
+  std::unique_ptr<SymbolTable> isymbols_;
+  std::unique_ptr<SymbolTable> osymbols_;
 
   EncodeTable(const EncodeTable &) = delete;
   EncodeTable &operator=(const EncodeTable &) = delete;
 };
 
 template <class Arc>
-bool EncodeTable<Arc>::Write(std::ostream &strm,
-                             const std::string &source) const {
-  WriteType(strm, kEncodeMagicNumber);
-  WriteType(strm, flags_);
-  const int64 size = encode_tuples_.size();
-  WriteType(strm, size);
-  for (const auto &tuple : encode_tuples_) {
-    WriteType(strm, tuple->ilabel);
-    WriteType(strm, tuple->olabel);
-    tuple->weight.Write(strm);
-  }
-  if (flags_ & kEncodeHasISymbols) isymbols_->Write(strm);
-  if (flags_ & kEncodeHasOSymbols) osymbols_->Write(strm);
-  strm.flush();
-  if (!strm) {
-    LOG(ERROR) << "EncodeTable::Write: Write failed: " << source;
-    return false;
-  }
-  return true;
-}
-
-template <class Arc>
 EncodeTable<Arc> *EncodeTable<Arc>::Read(std::istream &strm,
                                          const std::string &source) {
-  int32 magic_number = 0;
-  ReadType(strm, &magic_number);
-  if (magic_number != kEncodeMagicNumber) {
-    LOG(ERROR) << "EncodeTable::Read: Bad encode table header: " << source;
-    return nullptr;
-  }
-  uint32 flags;
-  ReadType(strm, &flags);
-  int64 size;
-  ReadType(strm, &size);
-  if (!strm) {
-    LOG(ERROR) << "EncodeTable::Read: Read failed: " << source;
-    return nullptr;
-  }
-  std::unique_ptr<EncodeTable<Arc>> table(new EncodeTable<Arc>(flags));
+  EncodeTableHeader hdr;
+  if (!hdr.Read(strm, source)) return nullptr;
+  const auto flags = hdr.Flags();
+  const auto size = hdr.Size();
+  auto table = fst::make_unique<EncodeTable>(flags);
   for (int64 i = 0; i < size; ++i) {
-    std::unique_ptr<Tuple> tuple(new Tuple());
-    ReadType(strm, &tuple->ilabel);
-    ReadType(strm, &tuple->olabel);
-    tuple->weight.Read(strm);
-    if (!strm) {
-      LOG(ERROR) << "EncodeTable::Read: Read failed: " << source;
-      return nullptr;
-    }
-    table->encode_tuples_.push_back(std::move(tuple));
-    table->encode_hash_[table->encode_tuples_.back().get()] =
-        table->encode_tuples_.size();
+    auto triple = fst::make_unique<Triple>();
+    ReadType(strm, &triple->ilabel);
+    ReadType(strm, &triple->olabel);
+    ReadType(strm, &triple->weight);
+    table->triples_.emplace_back(std::move(triple));
+    table->triple2label_[table->triples_.back().get()] = table->triples_.size();
   }
   if (flags & kEncodeHasISymbols) {
     table->isymbols_.reset(SymbolTable::Read(strm, source));
@@ -235,9 +250,36 @@ EncodeTable<Arc> *EncodeTable<Arc>::Read(std::istream &strm,
   if (flags & kEncodeHasOSymbols) {
     table->osymbols_.reset(SymbolTable::Read(strm, source));
   }
+  if (!strm) {
+    LOG(ERROR) << "EncodeTable::Read: Read failed: " << source;
+    return nullptr;
+  }
   return table.release();
 }
 
+template <class Arc>
+bool EncodeTable<Arc>::Write(std::ostream &strm,
+                             const std::string &source) const {
+  EncodeTableHeader hdr;
+  hdr.SetArcType(Arc::Type());
+  hdr.SetFlags(flags_);  // Real flags, not masked ones.
+  hdr.SetSize(Size());
+  if (!hdr.Write(strm, source)) return false;
+  for (const auto &triple : triples_) {
+    WriteType(strm, triple->ilabel);
+    WriteType(strm, triple->olabel);
+    WriteType(strm, triple->weight);
+  }
+  if (flags_ & kEncodeHasISymbols) isymbols_->Write(strm);
+  if (flags_ & kEncodeHasOSymbols) osymbols_->Write(strm);
+  strm.flush();
+  if (!strm) {
+    LOG(ERROR) << "EncodeTable::Write: Write failed: " << source;
+    return false;
+  }
+  return true;
+}
+
 }  // namespace internal
 
 // A mapper to encode/decode weighted transducers. Encoding of an FST is used
@@ -262,7 +304,7 @@ class EncodeMapper {
   using Weight = typename Arc::Weight;
 
  public:
-  EncodeMapper(uint32 flags, EncodeType type)
+  explicit EncodeMapper(uint8 flags, EncodeType type = ENCODE)
       : flags_(flags),
         type_(type),
         table_(std::make_shared<internal::EncodeTable<Arc>>(flags)),
@@ -297,6 +339,8 @@ class EncodeMapper {
     return MAP_CLEAR_SYMBOLS;
   }
 
+  uint8 Flags() const { return flags_; }
+
   uint64 Properties(uint64 inprops) {
     uint64 outprops = inprops;
     if (error_) outprops |= kError;
@@ -312,39 +356,36 @@ class EncodeMapper {
     return outprops & mask;
   }
 
-  uint32 Flags() const { return flags_; }
-
   EncodeType Type() const { return type_; }
 
-  bool Write(std::ostream &strm, const std::string &source) const {
-    return table_->Write(strm, source);
-  }
-
-  bool Write(const std::string &filename) const {
-    std::ofstream strm(filename,
-                             std::ios_base::out | std::ios_base::binary);
-    if (!strm) {
-      LOG(ERROR) << "EncodeMap: Can't open file: " << filename;
-      return false;
-    }
-    return Write(strm, filename);
-  }
-
   static EncodeMapper<Arc> *Read(std::istream &strm, const std::string &source,
                                  EncodeType type = ENCODE) {
     auto *table = internal::EncodeTable<Arc>::Read(strm, source);
     return table ? new EncodeMapper(table->Flags(), type, table) : nullptr;
   }
 
-  static EncodeMapper<Arc> *Read(const std::string &filename,
+  static EncodeMapper<Arc> *Read(const std::string &source,
                                  EncodeType type = ENCODE) {
-    std::ifstream strm(filename,
-                            std::ios_base::in | std::ios_base::binary);
+    std::ifstream strm(source, std::ios_base::in | std::ios_base::binary);
     if (!strm) {
-      LOG(ERROR) << "EncodeMap: Can't open file: " << filename;
+      LOG(ERROR) << "EncodeMapper: Can't open file: " << source;
       return nullptr;
     }
-    return Read(strm, filename, type);
+    return Read(strm, source, type);
+  }
+
+  bool Write(std::ostream &strm, const std::string &source) const {
+    return table_->Write(strm, source);
+  }
+
+  bool Write(const std::string &source) const {
+    std::ofstream strm(source,
+                             std::ios_base::out | std::ios_base::binary);
+    if (!strm) {
+      LOG(ERROR) << "EncodeMapper: Can't open file: " << source;
+      return false;
+    }
+    return Write(strm, source);
   }
 
   const SymbolTable *InputSymbols() const { return table_->InputSymbols(); }
@@ -360,12 +401,12 @@ class EncodeMapper {
   }
 
  private:
-  uint32 flags_;
+  uint8 flags_;
   EncodeType type_;
   std::shared_ptr<internal::EncodeTable<Arc>> table_;
   bool error_;
 
-  explicit EncodeMapper(uint32 flags, EncodeType type,
+  explicit EncodeMapper(uint8 flags, EncodeType type,
                         internal::EncodeTable<Arc> *table)
       : flags_(flags), type_(type), table_(table), error_(false) {}
 
@@ -375,9 +416,12 @@ class EncodeMapper {
 template <class Arc>
 Arc EncodeMapper<Arc>::operator()(const Arc &arc) {
   if (type_ == ENCODE) {
-    if ((arc.nextstate == kNoStateId && !(flags_ & kEncodeWeights)) ||
-        (arc.nextstate == kNoStateId && (flags_ & kEncodeWeights) &&
-         arc.weight == Weight::Zero())) {
+    // If this arc is a hallucinated final state, and we're either not encoding
+    // weights, or we're encoding weights but this is non-final, we use an
+    // identity-encoding.
+    if (arc.nextstate == kNoStateId &&
+        ((!(flags_ & kEncodeWeights) ||
+          ((flags_ & kEncodeWeights) && arc.weight == Weight::Zero())))) {
       return arc;
     } else {
       const auto label = table_->Encode(arc);
@@ -399,15 +443,18 @@ Arc EncodeMapper<Arc>::operator()(const Arc &arc) {
         FSTERROR() << "EncodeMapper: Weight-encoded arc has non-trivial weight";
         error_ = true;
       }
-      const auto tuple = table_->Decode(arc.ilabel);
-      if (!tuple) {
+      const auto triple = table_->Decode(arc.ilabel);
+      if (!triple) {
         FSTERROR() << "EncodeMapper: Decode failed";
         error_ = true;
         return Arc(kNoLabel, kNoLabel, Weight::NoWeight(), arc.nextstate);
+      } else if (triple->ilabel == kNoLabel) {
+        // Hallucinated kNoLabel from a weighted superfinal transition.
+        return Arc(0, 0, triple->weight, arc.nextstate);
       } else {
-        return Arc(tuple->ilabel,
-                   flags_ & kEncodeLabels ? tuple->olabel : arc.olabel,
-                   flags_ & kEncodeWeights ? tuple->weight : arc.weight,
+        return Arc(triple->ilabel,
+                   flags_ & kEncodeLabels ? triple->olabel : arc.olabel,
+                   flags_ & kEncodeWeights ? triple->weight : arc.weight,
                    arc.nextstate);
       }
     }
index ed89c6c..ffc89c6 100644 (file)
 
 namespace fst {
 
-constexpr uint32 kEqualFsts = 0x0001;
-constexpr uint32 kEqualFstTypes = 0x0002;
-constexpr uint32 kEqualCompatProperties = 0x0004;
-constexpr uint32 kEqualCompatSymbols = 0x0008;
-constexpr uint32 kEqualAll =
+constexpr uint8 kEqualFsts = 0x01;
+constexpr uint8 kEqualFstTypes = 0x02;
+constexpr uint8 kEqualCompatProperties = 0x04;
+constexpr uint8 kEqualCompatSymbols = 0x08;
+constexpr uint8 kEqualAll =
     kEqualFsts | kEqualFstTypes | kEqualCompatProperties | kEqualCompatSymbols;
 
 class WeightApproxEqual {
@@ -31,17 +31,17 @@ class WeightApproxEqual {
   }
 
  private:
-  float delta_;
+  const float delta_;
 };
 
-// Tests if two Fsts have the same states and arcs in the same order (when
-// etype & kEqualFst).
-// Also optional checks equality of Fst types (etype & kEqualFstTypes) and
-// compatibility of stored properties (etype & kEqualCompatProperties) and
-// of symbol tables (etype & kEqualCompatSymbols).
+// Tests if two FSTs have the same states and arcs in the same order (when
+// etype & kEqualFst); optionally, also checks equality of FST types
+// (etype & kEqualFstTypes) and compatibility of stored properties
+// (etype & kEqualCompatProperties) and of symbol tables
+// (etype & kEqualCompatSymbols).
 template <class Arc, class WeightEqual>
-bool Equal(const Fst<Arc> &fst1, const Fst<Arc> &fst2,
-           WeightEqual weight_equal, uint32 etype = kEqualFsts) {
+bool Equal(const Fst<Arc> &fst1, const Fst<Arc> &fst2, WeightEqual weight_equal,
+           uint8 etype = kEqualFsts) {
   if ((etype & kEqualFstTypes) && (fst1.Type() != fst2.Type())) {
     VLOG(1) << "Equal: Mismatched FST types (" << fst1.Type() << " != "
             << fst2.Type() << ")";
@@ -148,8 +148,8 @@ bool Equal(const Fst<Arc> &fst1, const Fst<Arc> &fst2,
 }
 
 template <class Arc>
-bool Equal(const Fst<Arc> &fst1, const Fst<Arc> &fst2,
-           float delta = kDelta, uint32 etype = kEqualFsts) {
+bool Equal(const Fst<Arc> &fst1, const Fst<Arc> &fst2, float delta = kDelta,
+           uint8 etype = kEqualFsts) {
   return Equal(fst1, fst2, WeightApproxEqual(delta), etype);
 }
 
@@ -158,12 +158,11 @@ bool Equal(const Fst<Arc> &fst1, const Fst<Arc> &fst2,
 // since it is a better match than double -> float narrowing, but
 // the instantiation will fail.
 template <class Arc>
-bool Equal(const Fst<Arc> &fst1, const Fst<Arc> &fst2,
-           double delta, uint32 etype = kEqualFsts) {
+bool Equal(const Fst<Arc> &fst1, const Fst<Arc> &fst2, double delta,
+           uint8 etype = kEqualFsts) {
   return Equal(fst1, fst2, WeightApproxEqual(static_cast<float>(delta)), etype);
 }
 
-
 }  // namespace fst
 
 #endif  // FST_EQUAL_H_
index 2392895..0e73b10 100644 (file)
@@ -11,6 +11,7 @@
 #include <istream>
 #include <memory>
 #include <string>
+#include <vector>
 
 #include <fst/log.h>
 #include <fstream>
@@ -60,16 +61,16 @@ class ExpandedFst : public Fst<A> {
   }
 
   // Read an ExpandedFst from a file; return NULL on error.
-  // Empty filename reads from standard input.
-  static ExpandedFst<Arc> *Read(const std::string &filename) {
-    if (!filename.empty()) {
-      std::ifstream strm(filename,
+  // Empty source reads from standard input.
+  static ExpandedFst<Arc> *Read(const std::string &source) {
+    if (!source.empty()) {
+      std::ifstream strm(source,
                               std::ios_base::in | std::ios_base::binary);
       if (!strm) {
-        LOG(ERROR) << "ExpandedFst::Read: Can't open file: " << filename;
+        LOG(ERROR) << "ExpandedFst::Read: Can't open file: " << source;
         return nullptr;
       }
-      return Read(strm, FstReadOptions(filename));
+      return Read(strm, FstReadOptions(source));
     } else {
       return Read(std::cin, FstReadOptions("standard input"));
     }
@@ -133,16 +134,16 @@ class ImplToExpandedFst : public ImplToFst<Impl, FST> {
   }
 
   // Read FST implementation from a file; return NULL on error.
-  // Empty filename reads from standard input.
-  static Impl *Read(const std::string &filename) {
-    if (!filename.empty()) {
-      std::ifstream strm(filename,
+  // Empty source reads from standard input.
+  static Impl *Read(const std::string &source) {
+    if (!source.empty()) {
+      std::ifstream strm(source,
                               std::ios_base::in | std::ios_base::binary);
       if (!strm) {
-        LOG(ERROR) << "ExpandedFst::Read: Can't open file: " << filename;
+        LOG(ERROR) << "ExpandedFst::Read: Can't open file: " << source;
         return nullptr;
       }
-      return Impl::Read(strm, FstReadOptions(filename));
+      return Impl::Read(strm, FstReadOptions(source));
     } else {
       return Impl::Read(std::cin, FstReadOptions("standard input"));
     }
@@ -165,6 +166,15 @@ typename Arc::StateId CountStates(const Fst<Arc> &fst) {
   }
 }
 
+// Function to return the number of states in a vector of FSTs, counting them if
+// necessary.
+template <class Arc>
+typename Arc::StateId CountStates(const std::vector<const Fst<Arc> *> &fsts) {
+  typename Arc::StateId nstates = 0;
+  for (const auto *fst : fsts) nstates += CountStates(*fst);
+  return nstates;
+}
+
 // Function to return the number of arcs in an FST.
 template <class F>
 size_t CountArcs(const F &fst) {
index 5675c64..ce6048b 100644 (file)
@@ -766,28 +766,28 @@ void Compress(const Fst<Arc> &fst, std::ostream &strm) {
 }
 
 template <class Arc>
-bool Compress(const Fst<Arc> &fst, const std::string &filename,
+bool Compress(const Fst<Arc> &fst, const std::string &source,
               const bool gzip = false) {
   if (gzip) {
       std::stringstream strm;
       Compress(fst, strm);
-      OGzFile gzfile(filename);
+      OGzFile gzfile(source);
       if (!gzfile) {
         LOG(ERROR) << "Compress: Can't open file: "
-                   << (filename.empty() ? "standard output" : filename);
+                   << (source.empty() ? "standard output" : source);
         return false;
       }
       gzfile.Write(strm);
       if (!gzfile) {
         LOG(ERROR) << "Compress: Can't write to file: "
-                   << (filename.empty() ? "standard output" : filename);
+                   << (source.empty() ? "standard output" : source);
         return false;
       }
-  } else if (!filename.empty()) {
-    std::ofstream strm(filename,
+  } else if (!source.empty()) {
+    std::ofstream strm(source,
                              std::ios_base::out | std::ios_base::binary);
     if (!strm) {
-      LOG(ERROR) << "Compress: Can't open file: " << filename;
+      LOG(ERROR) << "Compress: Can't open file: " << source;
       return false;
     }
     Compress(fst, strm);
@@ -807,29 +807,28 @@ bool Decompress(std::istream &strm, const std::string &source,
 
 // Returns true on success.
 template <class Arc>
-bool Decompress(const std::string &filename, MutableFst<Arc> *fst,
+bool Decompress(const std::string &source, MutableFst<Arc> *fst,
                 const bool gzip = false) {
   if (gzip) {
-    IGzFile gzfile(filename);
+    IGzFile gzfile(source);
     if (!gzfile) {
       LOG(ERROR) << "Decompress: Can't open file: "
-                 << (filename.empty() ? "standard input" : filename);
+                 << (source.empty() ? "standard input" : source);
       return false;
     }
-    Decompress(*gzfile.Read(), filename, fst);
+    Decompress(*gzfile.Read(), source, fst);
     if (!gzfile) {
       LOG(ERROR) << "Decompress: Can't read from file: "
-                 << (filename.empty() ? "standard input" : filename);
+                 << (source.empty() ? "standard input" : source);
       return false;
     }
-  } else if (!filename.empty()) {
-    std::ifstream strm(filename,
-                            std::ios_base::in | std::ios_base::binary);
+  } else if (!source.empty()) {
+    std::ifstream strm(source, std::ios_base::in | std::ios_base::binary);
     if (!strm) {
-      LOG(ERROR) << "Decompress: Can't open file: " << filename;
+      LOG(ERROR) << "Decompress: Can't open file: " << source;
       return false;
     }
-    Decompress(strm, filename, fst);
+    Decompress(strm, source, fst);
   } else {
     Decompress(std::cin, "standard input", fst);
   }
index 648e94c..e015a11 100644 (file)
@@ -22,13 +22,12 @@ using CompressArgs = WithReturnValue<bool, CompressInnerArgs>;
 template <class Arc>
 void Compress(CompressArgs *args) {
   const Fst<Arc> &fst = *std::get<0>(args->args).GetFst<Arc>();
-  const auto &filename = std::get<1>(args->args);
+  const auto &source = std::get<1>(args->args);
   const auto gzip = std::get<2>(args->args);
-  args->retval = Compress(fst, filename, gzip);
+  args->retval = Compress(fst, source, gzip);
 }
 
-bool Compress(const FstClass &fst, const std::string &filename,
-              const bool gzip);
+bool Compress(const FstClass &fst, const std::string &source, const bool gzip);
 
 using DecompressInnerArgs =
     std::tuple<const std::string &, MutableFstClass *, const bool>;
@@ -37,13 +36,13 @@ using DecompressArgs = WithReturnValue<bool, DecompressInnerArgs>;
 
 template <class Arc>
 void Decompress(DecompressArgs *args) {
-  const auto &filename = std::get<0>(args->args);
+  const auto &source = std::get<0>(args->args);
   MutableFst<Arc> *fst = std::get<1>(args->args)->GetMutableFst<Arc>();
   const auto gzip = std::get<2>(args->args);
-  args->retval = Decompress(filename, fst, gzip);
+  args->retval = Decompress(source, fst, gzip);
 }
 
-bool Decompress(const std::string &filename, MutableFstClass *fst,
+bool Decompress(const std::string &source, MutableFstClass *fst,
                 const bool gzip);
 
 }  // namespace script
index a561de1..a02cdc2 100644 (file)
@@ -27,9 +27,8 @@ namespace fst {
 // errors after construction or read/writing.
 class GzFile {
  public:
-  GzFile(const char *filename, const char *mode)
-      : gzfile_(gzopen(filename, mode)), error_(gzfile_ == nullptr) {
-  }
+  GzFile(const char *source, const char *mode)
+      : gzfile_(gzopen(source, mode)), error_(gzfile_ == nullptr) {}
 
   ~GzFile() { gzclose(gzfile_); }
 
@@ -50,15 +49,14 @@ class GzFile {
  private:
   gzFile gzfile_;
   bool error_;
-  bool close_me_ = false;
 };
 
 // Resource handle for writing stringstream to GzFile.
 class OGzFile {
  public:
-  explicit OGzFile(const std::string &filename) : OGzFile(filename.c_str()) {}
+  explicit OGzFile(const std::string &source) : OGzFile(source.c_str()) {}
 
-  explicit OGzFile(const char *filename) : gz_(GzFile(filename, "wb")) {}
+  explicit OGzFile(const char *source) : gz_(GzFile(source, "wb")) {}
 
   inline bool operator!() const { return !gz_; }
 
@@ -74,9 +72,9 @@ class OGzFile {
 // Resource handle for reading stringstream from GzFile.
 class IGzFile {
  public:
-  explicit IGzFile(const std::string &filename) : IGzFile(filename.c_str()) {}
+  explicit IGzFile(const std::string &source) : IGzFile(source.c_str()) {}
 
-  explicit IGzFile(const char *filename) : gz_(GzFile(filename, "rb")) {}
+  explicit IGzFile(const char *source) : gz_(GzFile(source, "rb")) {}
 
   inline bool operator!() const { return !gz_; }
 
index 599dda3..a0c99b8 100644 (file)
@@ -120,14 +120,14 @@ class StringReader {
 
 // Computes the minimal length required to encode each line number as a decimal
 // number, or zero if the file is not seekable.
-int KeySize(const char *filename);
+int KeySize(const char *source);
 
 template <class Arc>
-void FarCompileStrings(const std::vector<std::string> &in_fnames,
-                       const std::string &out_fname,
+void FarCompileStrings(const std::vector<std::string> &in_sources,
+                       const std::string &out_source,
                        const std::string &fst_type, const FarType &far_type,
                        int32 generate_keys, FarEntryType fet, FarTokenType tt,
-                       const std::string &symbols_fname,
+                       const std::string &symbols_source,
                        const std::string &unknown_symbol, bool keep_symbols,
                        bool initial_symbols, bool allow_negative_labels,
                        const std::string &key_prefix,
@@ -163,54 +163,55 @@ void FarCompileStrings(const std::vector<std::string> &in_fnames,
   }
   std::unique_ptr<const SymbolTable> syms;
   typename Arc::Label unknown_label = kNoLabel;
-  if (!symbols_fname.empty()) {
+  if (!symbols_source.empty()) {
     const SymbolTableTextOptions opts(allow_negative_labels);
-    syms.reset(SymbolTable::ReadText(symbols_fname, opts));
+    syms.reset(SymbolTable::ReadText(symbols_source, opts));
     if (!syms) {
       LOG(ERROR) << "FarCompileStrings: Error reading symbol table: "
-                 << symbols_fname;
+                 << symbols_source;
       return;
     }
     if (!unknown_symbol.empty()) {
       unknown_label = syms->Find(unknown_symbol);
       if (unknown_label == kNoLabel) {
         FSTERROR() << "FarCompileStrings: Label \"" << unknown_label
-                   << "\" missing from symbol table: " << symbols_fname;
+                   << "\" missing from symbol table: " << symbols_source;
         return;
       }
     }
   }
   std::unique_ptr<FarWriter<Arc>> far_writer(
-      FarWriter<Arc>::Create(out_fname, far_type));
+      FarWriter<Arc>::Create(out_source, far_type));
   if (!far_writer) return;
   int n = 0;
-  for (const auto &in_fname : in_fnames) {
+  for (const auto &in_source : in_sources) {
     // Don't try to call KeySize("").
-    if (generate_keys == 0 && in_fname.empty()) {
+    if (generate_keys == 0 && in_source.empty()) {
       FSTERROR() << "FarCompileStrings: Read from a file instead of stdin or"
                  << " set the --generate_keys flag.";
       return;
     }
-    const int key_size =
-        generate_keys ? generate_keys : (entry_type == StringReader<Arc>::FILE
-                                             ? 1 : KeySize(in_fname.c_str()));
+    const int key_size = generate_keys ? generate_keys
+                                       : (entry_type == StringReader<Arc>::FILE
+                                              ? 1
+                                              : KeySize(in_source.c_str()));
     if (key_size == 0) {
-      FSTERROR() << "FarCompileStrings: " << in_fname << " is not seekable.  "
+      FSTERROR() << "FarCompileStrings: " << in_source << " is not seekable.  "
                  << "Read from a file instead or set the --generate_keys flag.";
       return;
     }
     std::ifstream fstrm;
-    if (!in_fname.empty()) {
-      fstrm.open(in_fname);
+    if (!in_source.empty()) {
+      fstrm.open(in_source);
       if (!fstrm) {
-        FSTERROR() << "FarCompileStrings: Can't open file: " << in_fname;
+        FSTERROR() << "FarCompileStrings: Can't open file: " << in_source;
         return;
       }
     }
     std::istream &istrm = fstrm.is_open() ? fstrm : std::cin;
     bool keep_syms = keep_symbols;
     for (StringReader<Arc> reader(
-             istrm, in_fname.empty() ? "stdin" : in_fname, entry_type,
+             istrm, in_source.empty() ? "stdin" : in_source, entry_type,
              token_type, allow_negative_labels, syms.get(), unknown_label);
          !reader.Done(); reader.Next()) {
       ++n;
@@ -223,7 +224,7 @@ void FarCompileStrings(const std::vector<std::string> &in_fnames,
       if (initial_symbols) keep_syms = false;
       if (!fst) {
         FSTERROR() << "FarCompileStrings: Compiling string number " << n
-                   << " in file " << in_fname << " failed with token_type = "
+                   << " in file " << in_source << " failed with token_type = "
                    << (tt == FTT_BYTE
                            ? "byte"
                            : (tt == FTT_UTF8
@@ -243,14 +244,14 @@ void FarCompileStrings(const std::vector<std::string> &in_fnames,
       if (generate_keys > 0) {
         key = keybuf.str();
       } else {
-        auto *filename = new char[in_fname.size() + 1];
-        strcpy(filename, in_fname.c_str());
-        key = basename(filename);
+        auto *source = new char[in_source.size() + 1];
+        strcpy(source, in_source.c_str());  // NOLINT
+        key = basename(source);
         if (entry_type != StringReader<Arc>::FILE) {
           key += "-";
           key += keybuf.str();
         }
-        delete[] filename;
+        delete[] source;
       }
       far_writer->Add(key_prefix + key + key_suffix, *fst);
     }
index 26708fe..b2176ba 100644 (file)
 namespace fst {
 
 template <class Arc>
-void FarCreate(const std::vector<std::string> &in_fnames,
-               const std::string &out_fname, const int32 generate_keys,
+void FarCreate(const std::vector<std::string> &in_sources,
+               const std::string &out_source, const int32 generate_keys,
                const FarType &far_type, const std::string &key_prefix,
                const std::string &key_suffix) {
   std::unique_ptr<FarWriter<Arc>> far_writer(
-      FarWriter<Arc>::Create(out_fname, far_type));
+      FarWriter<Arc>::Create(out_source, far_type));
   if (!far_writer) return;
-  for (size_t i = 0; i < in_fnames.size(); ++i) {
-    std::unique_ptr<Fst<Arc>> ifst(Fst<Arc>::Read(in_fnames[i]));
+  for (size_t i = 0; i < in_sources.size(); ++i) {
+    std::unique_ptr<Fst<Arc>> ifst(Fst<Arc>::Read(in_sources[i]));
     if (!ifst) return;
     std::string key;
     if (generate_keys > 0) {
@@ -34,10 +34,10 @@ void FarCreate(const std::vector<std::string> &in_fnames,
       keybuf << i + 1;
       key = keybuf.str();
     } else {
-      auto *filename = new char[in_fnames[i].size() + 1];
-      strcpy(filename, in_fnames[i].c_str());
-      key = basename(filename);
-      delete[] filename;
+      auto *source = new char[in_sources[i].size() + 1];
+      strcpy(source, in_sources[i].c_str());  // NOLINT
+      key = basename(source);
+      delete[] source;
     }
     far_writer->Add(key_prefix + key + key_suffix, *ifst);
   }
index 86eb84c..376b282 100644 (file)
 namespace fst {
 
 template <class Arc>
-bool FarEqual(const std::string &filename1, const std::string &filename2,
+bool FarEqual(const std::string &source1, const std::string &source2,
               float delta = kDelta,
               const std::string &begin_key = std::string(),
               const std::string &end_key = std::string()) {
-  std::unique_ptr<FarReader<Arc>> reader1(FarReader<Arc>::Open(filename1));
+  std::unique_ptr<FarReader<Arc>> reader1(FarReader<Arc>::Open(source1));
   if (!reader1) {
-    LOG(ERROR) << "FarEqual: Could not open FAR file " << filename1;
+    LOG(ERROR) << "FarEqual: Could not open FAR file " << source1;
     return false;
   }
-  std::unique_ptr<FarReader<Arc>> reader2(FarReader<Arc>::Open(filename2));
+  std::unique_ptr<FarReader<Arc>> reader2(FarReader<Arc>::Open(source2));
   if (!reader2) {
-    LOG(ERROR) << "FarEqual: Could not open FAR file " << filename2;
+    LOG(ERROR) << "FarEqual: Could not open FAR file " << source2;
     return false;
   }
   if (!begin_key.empty()) {
index ffa645b..605f7f7 100644 (file)
@@ -17,42 +17,41 @@ namespace fst {
 
 template <class Arc>
 inline void FarWriteFst(const Fst<Arc> *fst, std::string key, std::string *okey,
-                        int *nrep, int32 generate_filenames, int i,
-                        const std::string &filename_prefix,
-                        const std::string &filename_suffix) {
+                        int *nrep, int32 generate_sources, int i,
+                        const std::string &source_prefix,
+                        const std::string &source_suffix) {
   if (key == *okey) {
     ++*nrep;
   } else {
     *nrep = 0;
   }
   *okey = key;
-  std::string ofilename;
-  if (generate_filenames) {
+  std::string osource;
+  if (generate_sources) {
     std::ostringstream tmp;
-    tmp.width(generate_filenames);
+    tmp.width(generate_sources);
     tmp.fill('0');
     tmp << i;
-    ofilename = tmp.str();
+    osource = tmp.str();
   } else {
     if (*nrep > 0) {
       std::ostringstream tmp;
       tmp << '.' << nrep;
       key.append(tmp.str().data(), tmp.str().size());
     }
-    ofilename = key;
+    osource = key;
   }
-  fst->Write(filename_prefix + ofilename + filename_suffix);
+  fst->Write(source_prefix + osource + source_suffix);
 }
 
 template <class Arc>
-void FarExtract(const std::vector<std::string> &ifilenames,
-                int32 generate_filenames, const std::string &keys,
+void FarExtract(const std::vector<std::string> &isources,
+                int32 generate_sources, const std::string &keys,
                 const std::string &key_separator,
                 const std::string &range_delimiter,
-                const std::string &filename_prefix,
-                const std::string &filename_suffix) {
-  std::unique_ptr<FarReader<Arc>> far_reader(
-      FarReader<Arc>::Open(ifilenames));
+                const std::string &source_prefix,
+                const std::string &source_suffix) {
+  std::unique_ptr<FarReader<Arc>> far_reader(FarReader<Arc>::Open(isources));
   if (!far_reader) return;
   std::string okey;
   int nrep = 0;
@@ -76,8 +75,8 @@ void FarExtract(const std::vector<std::string> &ifilenames,
           return;
         }
         const auto *fst = far_reader->GetFst();
-        FarWriteFst(fst, key, &okey, &nrep, generate_filenames, i,
-                    filename_prefix, filename_suffix);
+        FarWriteFst(fst, key, &okey, &nrep, generate_sources, i, source_prefix,
+                    source_suffix);
       } else if (range_vector.size() == 2) {  // A legal range
         std::string begin_key = range_vector[0];
         std::string end_key = range_vector[1];
@@ -93,8 +92,8 @@ void FarExtract(const std::vector<std::string> &ifilenames,
           const auto &ikey = far_reader->GetKey();
           if (end_key < ikey) break;
           const auto *fst = far_reader->GetFst();
-          FarWriteFst(fst, ikey, &okey, &nrep, generate_filenames, i,
-                      filename_prefix, filename_suffix);
+          FarWriteFst(fst, ikey, &okey, &nrep, generate_sources, i,
+                      source_prefix, source_suffix);
         }
       } else {
         LOG(ERROR) << "FarExtract: Illegal range specification " << key;
@@ -109,8 +108,8 @@ void FarExtract(const std::vector<std::string> &ifilenames,
   for (size_t i = 1; !far_reader->Done(); far_reader->Next(), ++i) {
     const auto &key = far_reader->GetKey();
     const auto *fst = far_reader->GetFst();
-    FarWriteFst(fst, key, &okey, &nrep, generate_filenames, i, filename_prefix,
-                filename_suffix);
+    FarWriteFst(fst, key, &okey, &nrep, generate_sources, i, source_prefix,
+                source_suffix);
   }
 }
 
index 57a0ec7..ee34f4e 100644 (file)
@@ -40,11 +40,11 @@ class FarReaderImplBase {
 template <class Arc>
 class FarReaderClassImpl : public FarReaderImplBase {
  public:
-  explicit FarReaderClassImpl(const std::string &filename)
-      : impl_(FarReader<Arc>::Open(filename)) {}
+  explicit FarReaderClassImpl(const std::string &source)
+      : impl_(FarReader<Arc>::Open(source)) {}
 
-  explicit FarReaderClassImpl(const std::vector<std::string> &filenames)
-      : impl_(FarReader<Arc>::Open(filenames)) {}
+  explicit FarReaderClassImpl(const std::vector<std::string> &sources)
+      : impl_(FarReader<Arc>::Open(sources)) {}
 
   const std::string &ArcType() const final { return Arc::Type(); }
 
@@ -126,9 +126,9 @@ class FarReaderClass {
 
   // Defined in the CC.
 
-  static FarReaderClass *Open(const std::string &filename);
+  static FarReaderClass *Open(const std::string &source);
 
-  static FarReaderClass *Open(const std::vector<std::string> &filenames);
+  static FarReaderClass *Open(const std::vector<std::string> &sources);
 
  private:
   template <class Arc>
@@ -164,9 +164,9 @@ class FarWriterImplBase {
 template <class Arc>
 class FarWriterClassImpl : public FarWriterImplBase {
  public:
-  explicit FarWriterClassImpl(const std::string &filename,
+  explicit FarWriterClassImpl(const std::string &source,
                               FarType type = FAR_DEFAULT)
-      : impl_(FarWriter<Arc>::Create(filename, type)) {}
+      : impl_(FarWriter<Arc>::Create(source, type)) {}
 
   bool Add(const std::string &key, const FstClass &fst) final {
     if (ArcType() != fst.ArcType()) {
@@ -203,7 +203,7 @@ using CreateFarWriterClassArgs =
 // Untemplated user-facing class holding a templated pimpl.
 class FarWriterClass {
  public:
-  static FarWriterClass *Create(const std::string &filename,
+  static FarWriterClass *Create(const std::string &source,
                                 const std::string &arc_type,
                                 FarType type = FAR_DEFAULT);
 
index 0cd01a9..f3958ef 100644 (file)
@@ -22,10 +22,10 @@ enum FarEntryType { FET_LINE, FET_FILE };
 
 enum FarTokenType { FTT_SYMBOL, FTT_BYTE, FTT_UTF8 };
 
-inline bool IsFst(const std::string &filename) {
-  std::ifstream strm(filename, std::ios_base::in | std::ios_base::binary);
+inline bool IsFst(const std::string &source) {
+  std::ifstream strm(source, std::ios_base::in | std::ios_base::binary);
   if (!strm) return false;
-  return IsFstHeader(strm, filename);
+  return IsFstHeader(strm, source);
 }
 
 // FST archive header class
@@ -35,27 +35,27 @@ class FarHeader {
 
   const std::string &FarType() const { return fartype_; }
 
-  bool Read(const std::string &filename) {
+  bool Read(const std::string &source) {
     FstHeader fsthdr;
-    if (filename.empty()) {
+    if (source.empty()) {
       // Header reading unsupported on stdin. Assumes STList and StdArc.
       fartype_ = "stlist";
       arctype_ = "standard";
       return true;
-    } else if (IsSTTable(filename)) {  // Checks if STTable.
-      ReadSTTableHeader(filename, &fsthdr);
+    } else if (IsSTTable(source)) {  // Checks if STTable.
+      ReadSTTableHeader(source, &fsthdr);
       fartype_ = "sttable";
       arctype_ = fsthdr.ArcType().empty() ? "unknown" : fsthdr.ArcType();
       return true;
-    } else if (IsSTList(filename)) {  // Checks if STList.
-      ReadSTListHeader(filename, &fsthdr);
+    } else if (IsSTList(source)) {  // Checks if STList.
+      ReadSTListHeader(source, &fsthdr);
       fartype_ = "stlist";
       arctype_ = fsthdr.ArcType().empty() ? "unknown" : fsthdr.ArcType();
       return true;
-    } else if (IsFst(filename)) {  // Checks if FST.
-      std::ifstream istrm(filename,
+    } else if (IsFst(source)) {  // Checks if FST.
+      std::ifstream istrm(source,
                                std::ios_base::in | std::ios_base::binary);
-      fsthdr.Read(istrm, filename);
+      fsthdr.Read(istrm, source);
       fartype_ = "fst";
       arctype_ = fsthdr.ArcType().empty() ? "unknown" : fsthdr.ArcType();
       return true;
@@ -82,7 +82,7 @@ class FarWriter {
   using Arc = A;
 
   // Creates a new (empty) FST archive; returns null on error.
-  static FarWriter *Create(const std::string &filename,
+  static FarWriter *Create(const std::string &source,
                            FarType type = FAR_DEFAULT);
 
   // Adds an FST to the end of an archive. Keys must be non-empty and
@@ -107,11 +107,11 @@ class FarReader {
 
   // Opens an existing FST archive in a single file; returns null on error.
   // Sets current position to the beginning of the achive.
-  static FarReader *Open(const std::string &filename);
+  static FarReader *Open(const std::string &source);
 
   // Opens an existing FST archive in multiple files; returns null on error.
   // Sets current position to the beginning of the achive.
-  static FarReader *Open(const std::vector<std::string> &filenames);
+  static FarReader *Open(const std::vector<std::string> &sources);
 
   // Resets current position to beginning of archive.
   virtual void Reset() = 0;
@@ -156,8 +156,8 @@ class STTableFarWriter : public FarWriter<A> {
  public:
   using Arc = A;
 
-  static STTableFarWriter *Create(const std::string &filename) {
-    auto *writer = STTableWriter<Fst<Arc>, FstWriter<Arc>>::Create(filename);
+  static STTableFarWriter *Create(const std::string &source) {
+    auto *writer = STTableWriter<Fst<Arc>, FstWriter<Arc>>::Create(source);
     return new STTableFarWriter(writer);
   }
 
@@ -181,8 +181,8 @@ class STListFarWriter : public FarWriter<A> {
  public:
   using Arc = A;
 
-  static STListFarWriter *Create(const std::string &filename) {
-    auto *writer = STListWriter<Fst<Arc>, FstWriter<Arc>>::Create(filename);
+  static STListFarWriter *Create(const std::string &source) {
+    auto *writer = STListWriter<Fst<Arc>, FstWriter<Arc>>::Create(source);
     return new STListFarWriter(writer);
   }
 
@@ -190,7 +190,7 @@ class STListFarWriter : public FarWriter<A> {
     writer_->Add(key, fst);
   }
 
-  constexpr FarType Type() const final { return FAR_STLIST; }
+  FarType Type() const final { return FAR_STLIST; }
 
   bool Error() const final { return writer_->Error(); }
 
@@ -202,15 +202,15 @@ class STListFarWriter : public FarWriter<A> {
 };
 
 template <class A>
-class FstFarWriter : public FarWriter<A> {
+class FstFarWriter final : public FarWriter<A> {
  public:
   using Arc = A;
 
-  explicit FstFarWriter(const std::string &filename)
-      : filename_(filename), error_(false), written_(false) {}
+  explicit FstFarWriter(const std::string &source)
+      : source_(source), error_(false), written_(false) {}
 
-  static FstFarWriter *Create(const std::string &filename) {
-    return new FstFarWriter(filename);
+  static FstFarWriter *Create(const std::string &source) {
+    return new FstFarWriter(source);
   }
 
   void Add(const std::string &key, const Fst<A> &fst) final {
@@ -218,35 +218,35 @@ class FstFarWriter : public FarWriter<A> {
       LOG(WARNING) << "FstFarWriter::Add: only one FST supported,"
                    << " subsequent entries discarded.";
     } else {
-      error_ = !fst.Write(filename_);
+      error_ = !fst.Write(source_);
       written_ = true;
     }
   }
 
-  constexpr FarType Type() const final { return FAR_FST; }
+  FarType Type() const final { return FAR_FST; }
 
   bool Error() const final { return error_; }
 
   ~FstFarWriter() final {}
 
  private:
-  std::string filename_;
+  std::string source_;
   bool error_;
   bool written_;
 };
 
 template <class Arc>
-FarWriter<Arc> *FarWriter<Arc>::Create(const std::string &filename,
+FarWriter<Arc> *FarWriter<Arc>::Create(const std::string &source,
                                        FarType type) {
   switch (type) {
     case FAR_DEFAULT:
-      if (filename.empty()) return STListFarWriter<Arc>::Create(filename);
+      if (source.empty()) return STListFarWriter<Arc>::Create(source);
     case FAR_STTABLE:
-      return STTableFarWriter<Arc>::Create(filename);
+      return STTableFarWriter<Arc>::Create(source);
     case FAR_STLIST:
-      return STListFarWriter<Arc>::Create(filename);
+      return STListFarWriter<Arc>::Create(source);
     case FAR_FST:
-      return FstFarWriter<Arc>::Create(filename);
+      return FstFarWriter<Arc>::Create(source);
     default:
       LOG(ERROR) << "FarWriter::Create: Unknown FAR type";
       return nullptr;
@@ -267,14 +267,14 @@ class STTableFarReader : public FarReader<A> {
  public:
   using Arc = A;
 
-  static STTableFarReader *Open(const std::string &filename) {
-    auto *reader = STTableReader<Fst<Arc>, FstReader<Arc>>::Open(filename);
+  static STTableFarReader *Open(const std::string &source) {
+    auto *reader = STTableReader<Fst<Arc>, FstReader<Arc>>::Open(source);
     if (!reader || reader->Error()) return nullptr;
     return new STTableFarReader(reader);
   }
 
-  static STTableFarReader *Open(const std::vector<std::string> &filenames) {
-    auto *reader = STTableReader<Fst<Arc>, FstReader<Arc>>::Open(filenames);
+  static STTableFarReader *Open(const std::vector<std::string> &sources) {
+    auto *reader = STTableReader<Fst<Arc>, FstReader<Arc>>::Open(sources);
     if (!reader || reader->Error()) return nullptr;
     return new STTableFarReader(reader);
   }
@@ -291,7 +291,7 @@ class STTableFarReader : public FarReader<A> {
 
   const Fst<Arc> *GetFst() const final { return reader_->GetEntry(); }
 
-  constexpr FarType Type() const final { return FAR_STTABLE; }
+  FarType Type() const final { return FAR_STTABLE; }
 
   bool Error() const final { return reader_->Error(); }
 
@@ -307,14 +307,14 @@ class STListFarReader : public FarReader<A> {
  public:
   using Arc = A;
 
-  static STListFarReader *Open(const std::string &filename) {
-    auto *reader = STListReader<Fst<Arc>, FstReader<Arc>>::Open(filename);
+  static STListFarReader *Open(const std::string &source) {
+    auto *reader = STListReader<Fst<Arc>, FstReader<Arc>>::Open(source);
     if (!reader || reader->Error()) return nullptr;
     return new STListFarReader(reader);
   }
 
-  static STListFarReader *Open(const std::vector<std::string> &filenames) {
-    auto *reader = STListReader<Fst<Arc>, FstReader<Arc>>::Open(filenames);
+  static STListFarReader *Open(const std::vector<std::string> &sources) {
+    auto *reader = STListReader<Fst<Arc>, FstReader<Arc>>::Open(sources);
     if (!reader || reader->Error()) return nullptr;
     return new STListFarReader(reader);
   }
@@ -331,7 +331,7 @@ class STListFarReader : public FarReader<A> {
 
   const Fst<Arc> *GetFst() const final { return reader_->GetEntry(); }
 
-  constexpr FarType Type() const final { return FAR_STLIST; }
+  FarType Type() const final { return FAR_STLIST; }
 
   bool Error() const final { return reader_->Error(); }
 
@@ -343,24 +343,24 @@ class STListFarReader : public FarReader<A> {
 };
 
 template <class A>
-class FstFarReader : public FarReader<A> {
+class FstFarReader final : public FarReader<A> {
  public:
   using Arc = A;
 
-  static FstFarReader *Open(const std::string &filename) {
-    std::vector<std::string> filenames;
-    filenames.push_back(filename);
-    return new FstFarReader<Arc>(filenames);
+  static FstFarReader *Open(const std::string &source) {
+    std::vector<std::string> sources;
+    sources.push_back(source);
+    return new FstFarReader<Arc>(sources);
   }
 
-  static FstFarReader *Open(const std::vector<std::string> &filenames) {
-    return new FstFarReader<Arc>(filenames);
+  static FstFarReader *Open(const std::vector<std::string> &sources) {
+    return new FstFarReader<Arc>(sources);
   }
 
-  explicit FstFarReader(const std::vector<std::string> &filenames)
-      : keys_(filenames), has_stdin_(false), pos_(0), error_(false) {
+  explicit FstFarReader(const std::vector<std::string> &sources)
+      : keys_(sources), has_stdin_(false), pos_(0), error_(false) {
     std::sort(keys_.begin(), keys_.end());
-    streams_.resize(keys_.size(), 0);
+    streams_.resize(keys_.size(), nullptr);
     for (size_t i = 0; i < keys_.size(); ++i) {
       if (keys_[i].empty()) {
         if (!has_stdin_) {
@@ -377,7 +377,7 @@ class FstFarReader : public FarReader<A> {
             keys_[i], std::ios_base::in | std::ios_base::binary);
         if (streams_[i]->fail()) {
           FSTERROR() << "FstFarReader::FstFarReader: Error reading file: "
-                     << filenames[i];
+                     << sources[i];
           error_ = true;
           return;
         }
@@ -421,7 +421,7 @@ class FstFarReader : public FarReader<A> {
 
   const Fst<Arc> *GetFst() const final { return fst_.get(); }
 
-  constexpr FarType Type() const final { return FAR_FST; }
+  FarType Type() const final { return FAR_FST; }
 
   bool Error() const final { return error_; }
 
@@ -454,29 +454,28 @@ class FstFarReader : public FarReader<A> {
 };
 
 template <class Arc>
-FarReader<Arc> *FarReader<Arc>::Open(const std::string &filename) {
-  if (filename.empty())
-    return STListFarReader<Arc>::Open(filename);
-  else if (IsSTTable(filename))
-    return STTableFarReader<Arc>::Open(filename);
-  else if (IsSTList(filename))
-    return STListFarReader<Arc>::Open(filename);
-  else if (IsFst(filename))
-    return FstFarReader<Arc>::Open(filename);
+FarReader<Arc> *FarReader<Arc>::Open(const std::string &source) {
+  if (source.empty())
+    return STListFarReader<Arc>::Open(source);
+  else if (IsSTTable(source))
+    return STTableFarReader<Arc>::Open(source);
+  else if (IsSTList(source))
+    return STListFarReader<Arc>::Open(source);
+  else if (IsFst(source))
+    return FstFarReader<Arc>::Open(source);
   return nullptr;
 }
 
 template <class Arc>
-FarReader<Arc> *FarReader<Arc>::Open(
-    const std::vector<std::string> &filenames) {
-  if (!filenames.empty() && filenames[0].empty())
-    return STListFarReader<Arc>::Open(filenames);
-  else if (!filenames.empty() && IsSTTable(filenames[0]))
-    return STTableFarReader<Arc>::Open(filenames);
-  else if (!filenames.empty() && IsSTList(filenames[0]))
-    return STListFarReader<Arc>::Open(filenames);
-  else if (!filenames.empty() && IsFst(filenames[0]))
-    return FstFarReader<Arc>::Open(filenames);
+FarReader<Arc> *FarReader<Arc>::Open(const std::vector<std::string> &sources) {
+  if (!sources.empty() && sources[0].empty())
+    return STListFarReader<Arc>::Open(sources);
+  else if (!sources.empty() && IsSTTable(sources[0]))
+    return STTableFarReader<Arc>::Open(sources);
+  else if (!sources.empty() && IsSTList(sources[0]))
+    return STListFarReader<Arc>::Open(sources);
+  else if (!sources.empty() && IsFst(sources[0]))
+    return FstFarReader<Arc>::Open(sources);
   return nullptr;
 }
 
index b54c42f..396a1ed 100644 (file)
@@ -30,14 +30,14 @@ namespace script {
 // only used to pass them deeper in the call graph. Be sure you understand why
 // this is so before using this struct for anything else!
 struct FarCompileStringsArgs {
-  const std::vector<std::string> &in_fnames;
-  const std::string &out_fname;
+  const std::vector<std::string> &in_sources;
+  const std::string &out_source;
   const std::string &fst_type;
   const FarType &far_type;
   const int32 generate_keys;
   const FarEntryType fet;
   const FarTokenType tt;
-  const std::string &symbols_fname;
+  const std::string &symbols_source;
   const std::string &unknown_symbol;
   const bool keep_symbols;
   const bool initial_symbols;
@@ -45,23 +45,23 @@ struct FarCompileStringsArgs {
   const std::string &key_prefix;
   const std::string &key_suffix;
 
-  FarCompileStringsArgs(const std::vector<std::string> &in_fnames,
-                        const std::string &out_fname,
+  FarCompileStringsArgs(const std::vector<std::string> &in_sources,
+                        const std::string &out_source,
                         const std::string &fst_type, const FarType &far_type,
                         int32 generate_keys, FarEntryType fet, FarTokenType tt,
-                        const std::string &symbols_fname,
+                        const std::string &symbols_source,
                         const std::string &unknown_symbol, bool keep_symbols,
                         bool initial_symbols, bool allow_negative_labels,
                         const std::string &key_prefix,
                         const std::string &key_suffix)
-      : in_fnames(in_fnames),
-        out_fname(out_fname),
+      : in_sources(in_sources),
+        out_source(out_source),
         fst_type(fst_type),
         far_type(far_type),
         generate_keys(generate_keys),
         fet(fet),
         tt(tt),
-        symbols_fname(symbols_fname),
+        symbols_source(symbols_source),
         unknown_symbol(unknown_symbol),
         keep_symbols(keep_symbols),
         initial_symbols(initial_symbols),
@@ -73,18 +73,18 @@ struct FarCompileStringsArgs {
 template <class Arc>
 void FarCompileStrings(FarCompileStringsArgs *args) {
   FarCompileStrings<Arc>(
-      args->in_fnames, args->out_fname, args->fst_type, args->far_type,
-      args->generate_keys, args->fet, args->tt, args->symbols_fname,
+      args->in_sources, args->out_source, args->fst_type, args->far_type,
+      args->generate_keys, args->fet, args->tt, args->symbols_source,
       args->unknown_symbol, args->keep_symbols, args->initial_symbols,
       args->allow_negative_labels, args->key_prefix, args->key_suffix);
 }
 
-void FarCompileStrings(const std::vector<std::string> &in_fnames,
-                       const std::string &out_fname,
+void FarCompileStrings(const std::vector<std::string> &in_sources,
+                       const std::string &out_source,
                        const std::string &arc_type, const std::string &fst_type,
                        const FarType &far_type, int32 generate_keys,
                        FarEntryType fet, FarTokenType tt,
-                       const std::string &symbols_fname,
+                       const std::string &symbols_source,
                        const std::string &unknown_symbol, bool keep_symbols,
                        bool initial_symbols, bool allow_negative_labels,
                        const std::string &key_prefix,
@@ -94,19 +94,19 @@ void FarCompileStrings(const std::vector<std::string> &in_fnames,
 // only used to pass them deeper in the call graph. Be sure you understand why
 // this is so before using this struct for anything else!
 struct FarCreateArgs {
-  const std::vector<std::string> &in_fnames;
-  const std::string &out_fname;
+  const std::vector<std::string> &in_sources;
+  const std::string &out_source;
   const int32 generate_keys;
   const FarType &far_type;
   const std::string &key_prefix;
   const std::string &key_suffix;
 
-  FarCreateArgs(const std::vector<std::string> &in_fnames,
-                const std::string &out_fname, const int32 generate_keys,
+  FarCreateArgs(const std::vector<std::string> &in_sources,
+                const std::string &out_source, const int32 generate_keys,
                 const FarType &far_type, const std::string &key_prefix,
                 const std::string &key_suffix)
-      : in_fnames(in_fnames),
-        out_fname(out_fname),
+      : in_sources(in_sources),
+        out_source(out_source),
         generate_keys(generate_keys),
         far_type(far_type),
         key_prefix(key_prefix),
@@ -115,12 +115,12 @@ struct FarCreateArgs {
 
 template <class Arc>
 void FarCreate(FarCreateArgs *args) {
-  FarCreate<Arc>(args->in_fnames, args->out_fname, args->generate_keys,
+  FarCreate<Arc>(args->in_sources, args->out_source, args->generate_keys,
                  args->far_type, args->key_prefix, args->key_suffix);
 }
 
-void FarCreate(const std::vector<std::string> &in_fnames,
-               const std::string &out_fname, const std::string &arc_type,
+void FarCreate(const std::vector<std::string> &in_sources,
+               const std::string &out_source, const std::string &arc_type,
                const int32 generate_keys, const FarType &far_type,
                const std::string &key_prefix, const std::string &key_suffix);
 
@@ -137,7 +137,7 @@ void FarEqual(FarEqualArgs *args) {
       std::get<3>(args->args), std::get<4>(args->args));
 }
 
-bool FarEqual(const std::string &filename1, const std::string &filename2,
+bool FarEqual(const std::string &source1, const std::string &source2,
               const std::string &arc_type, float delta = kDelta,
               const std::string &begin_key = std::string(),
               const std::string &end_key = std::string());
@@ -155,12 +155,12 @@ void FarExtract(FarExtractArgs *args) {
                            std::get<6>(*args));
 }
 
-void FarExtract(const std::vector<std::string> &ifilenames,
-                const std::string &arc_type, int32 generate_filenames,
+void FarExtract(const std::vector<std::string> &isources,
+                const std::string &arc_type, int32 generate_sources,
                 const std::string &keys, const std::string &key_separator,
                 const std::string &range_delimiter,
-                const std::string &filename_prefix,
-                const std::string &filename_suffix);
+                const std::string &source_prefix,
+                const std::string &source_suffix);
 
 using FarInfoArgs =
     std::tuple<const std::vector<std::string> &, const std::string &,
@@ -172,7 +172,7 @@ void FarInfo(FarInfoArgs *args) {
                         std::get<2>(*args), std::get<3>(*args));
 }
 
-void FarInfo(const std::vector<std::string> &filenames,
+void FarInfo(const std::vector<std::string> &sources,
              const std::string &arc_type, const std::string &begin_key,
              const std::string &end_key, const bool list_fsts);
 
@@ -187,7 +187,7 @@ void GetFarInfo(GetFarInfoArgs *args) {
                            std::get<4>(*args));
 }
 
-void GetFarInfo(const std::vector<std::string> &filenames,
+void GetFarInfo(const std::vector<std::string> &sources,
                 const std::string &arc_type, const std::string &begin_key,
                 const std::string &end_key, const bool list_fsts,
                 FarInfoData *);
@@ -205,64 +205,66 @@ void FarIsomorphic(FarIsomorphicArgs *args) {
       std::get<3>(args->args), std::get<4>(args->args));
 }
 
-bool FarIsomorphic(const std::string &filename1, const std::string &filename2,
+bool FarIsomorphic(const std::string &source1, const std::string &source2,
                    const std::string &arc_type, float delta = kDelta,
                    const std::string &begin_key = std::string(),
                    const std::string &end_key = std::string());
 
 struct FarPrintStringsArgs {
-  const std::vector<std::string> &ifilenames;
+  const std::vector<std::string> &isources;
   const FarEntryType entry_type;
   const FarTokenType token_type;
   const std::string &begin_key;
   const std::string &end_key;
   const bool print_key;
   const bool print_weight;
-  const std::string &symbols_fname;
+  const std::string &symbols_source;
   const bool initial_symbols;
-  const int32 generate_filenames;
-  const std::string &filename_prefix;
-  const std::string &filename_suffix;
-
-  FarPrintStringsArgs(
-      const std::vector<std::string> &ifilenames, const FarEntryType entry_type,
-      const FarTokenType token_type, const std::string &begin_key,
-      const std::string &end_key, const bool print_key, const bool print_weight,
-      const std::string &symbols_fname, const bool initial_symbols,
-      const int32 generate_filenames, const std::string &filename_prefix,
-      const std::string &filename_suffix)
-      : ifilenames(ifilenames),
+  const int32 generate_sources;
+  const std::string &source_prefix;
+  const std::string &source_suffix;
+
+  FarPrintStringsArgs(const std::vector<std::string> &isources,
+                      const FarEntryType entry_type,
+                      const FarTokenType token_type,
+                      const std::string &begin_key, const std::string &end_key,
+                      const bool print_key, const bool print_weight,
+                      const std::string &symbols_source,
+                      const bool initial_symbols, const int32 generate_sources,
+                      const std::string &source_prefix,
+                      const std::string &source_suffix)
+      : isources(isources),
         entry_type(entry_type),
         token_type(token_type),
         begin_key(begin_key),
         end_key(end_key),
         print_key(print_key),
         print_weight(print_weight),
-        symbols_fname(symbols_fname),
+        symbols_source(symbols_source),
         initial_symbols(initial_symbols),
-        generate_filenames(generate_filenames),
-        filename_prefix(filename_prefix),
-        filename_suffix(filename_suffix) {}
+        generate_sources(generate_sources),
+        source_prefix(source_prefix),
+        source_suffix(source_suffix) {}
 };
 
 template <class Arc>
 void FarPrintStrings(FarPrintStringsArgs *args) {
   fst::FarPrintStrings<Arc>(
-      args->ifilenames, args->entry_type, args->token_type, args->begin_key,
-      args->end_key, args->print_key, args->print_weight, args->symbols_fname,
-      args->initial_symbols, args->generate_filenames, args->filename_prefix,
-      args->filename_suffix);
+      args->isources, args->entry_type, args->token_type, args->begin_key,
+      args->end_key, args->print_key, args->print_weight, args->symbols_source,
+      args->initial_symbols, args->generate_sources, args->source_prefix,
+      args->source_suffix);
 }
 
-void FarPrintStrings(const std::vector<std::string> &ifilenames,
+void FarPrintStrings(const std::vector<std::string> &isources,
                      const std::string &arc_type, const FarEntryType entry_type,
                      const FarTokenType token_type,
                      const std::string &begin_key, const std::string &end_key,
                      const bool print_key, const bool print_weight,
-                     const std::string &symbols_fname,
-                     const bool initial_symbols, const int32 generate_filenames,
-                     const std::string &filename_prefix,
-                     const std::string &filename_suffix);
+                     const std::string &symbols_source,
+                     const bool initial_symbols, const int32 generate_sources,
+                     const std::string &source_prefix,
+                     const std::string &source_suffix);
 
 }  // namespace script
 }  // namespace fst
index 7100214..fa1ffaf 100644 (file)
@@ -48,11 +48,11 @@ struct FarInfoData {
 };
 
 template <class Arc>
-void GetFarInfo(const std::vector<std::string> &filenames,
+void GetFarInfo(const std::vector<std::string> &sources,
                 const std::string &begin_key, const std::string &end_key,
                 const bool list_fsts, FarInfoData *far_info) {
   *far_info = FarInfoData();
-  std::unique_ptr<FarReader<Arc>> reader(FarReader<Arc>::Open(filenames));
+  std::unique_ptr<FarReader<Arc>> reader(FarReader<Arc>::Open(sources));
   if (!reader) {
     LOG(ERROR) << "GetFarInfo: failed to create far reader.";
     return;
@@ -84,11 +84,11 @@ void GetFarInfo(const std::vector<std::string> &filenames,
 }
 
 template <class Arc>
-void FarInfo(const std::vector<std::string> &filenames,
+void FarInfo(const std::vector<std::string> &sources,
              const std::string &begin_key, const std::string &end_key,
              const bool list_fsts) {
   FarInfoData info;
-  GetFarInfo<Arc>(filenames, begin_key, end_key, list_fsts, &info);
+  GetFarInfo<Arc>(sources, begin_key, end_key, list_fsts, &info);
   if (!list_fsts) {
     std::cout << std::left << std::setw(50) << "far type" << info.far_type
               << std::endl;
index ede0efb..11373fb 100644 (file)
 namespace fst {
 
 template <class Arc>
-bool FarIsomorphic(const std::string &filename1, const std::string &filename2,
+bool FarIsomorphic(const std::string &source1, const std::string &source2,
                    float delta = kDelta,
                    const std::string &begin_key = std::string(),
                    const std::string &end_key = std::string()) {
-  std::unique_ptr<FarReader<Arc>> reader1(FarReader<Arc>::Open(filename1));
+  std::unique_ptr<FarReader<Arc>> reader1(FarReader<Arc>::Open(source1));
   if (!reader1) {
-    LOG(ERROR) << "FarIsomorphic: Cannot open FAR file " << filename1;
+    LOG(ERROR) << "FarIsomorphic: Cannot open FAR file " << source1;
     return false;
   }
-  std::unique_ptr<FarReader<Arc>> reader2(FarReader<Arc>::Open(filename2));
+  std::unique_ptr<FarReader<Arc>> reader2(FarReader<Arc>::Open(source2));
   if (!reader2) {
-    LOG(ERROR) << "FarIsomorphic: Cannot open FAR file " << filename2;
+    LOG(ERROR) << "FarIsomorphic: Cannot open FAR file " << source2;
     return false;
   }
   if (!begin_key.empty()) {
index b1e0747..c313d41 100644 (file)
@@ -21,14 +21,13 @@ DECLARE_string(far_field_separator);
 namespace fst {
 
 template <class Arc>
-void FarPrintStrings(const std::vector<std::string> &ifilenames,
+void FarPrintStrings(const std::vector<std::string> &isources,
                      FarEntryType entry_type, FarTokenType far_token_type,
                      const std::string &begin_key, const std::string &end_key,
                      bool print_key, bool print_weight,
-                     const std::string &symbols_fname, bool initial_symbols,
-                     int32 generate_filenames,
-                     const std::string &filename_prefix,
-                     const std::string &filename_suffix) {
+                     const std::string &symbols_source, bool initial_symbols,
+                     int32 generate_sources, const std::string &source_prefix,
+                     const std::string &source_suffix) {
   StringTokenType token_type;
   if (far_token_type == FTT_SYMBOL) {
     token_type = StringTokenType::SYMBOL;
@@ -41,17 +40,17 @@ void FarPrintStrings(const std::vector<std::string> &ifilenames,
     return;
   }
   std::unique_ptr<const SymbolTable> syms;
-  if (!symbols_fname.empty()) {
+  if (!symbols_source.empty()) {
     // TODO(kbg): Allow negative flag?
     const SymbolTableTextOptions opts(true);
-    syms.reset(SymbolTable::ReadText(symbols_fname, opts));
+    syms.reset(SymbolTable::ReadText(symbols_source, opts));
     if (!syms) {
       LOG(ERROR) << "FarPrintStrings: Error reading symbol table "
-                 << symbols_fname;
+                 << symbols_source;
       return;
     }
   }
-  std::unique_ptr<FarReader<Arc>> far_reader(FarReader<Arc>::Open(ifilenames));
+  std::unique_ptr<FarReader<Arc>> far_reader(FarReader<Arc>::Open(isources));
   if (!far_reader) return;
   if (!begin_key.empty()) far_reader->Find(begin_key);
   std::string okey;
@@ -81,18 +80,18 @@ void FarPrintStrings(const std::vector<std::string> &ifilenames,
       std::cout << std::endl;
     } else if (entry_type == FET_FILE) {
       std::stringstream sstrm;
-      if (generate_filenames) {
+      if (generate_sources) {
         sstrm.fill('0');
-        sstrm << std::right << std::setw(generate_filenames) << i;
+        sstrm << std::right << std::setw(generate_sources) << i;
       } else {
         sstrm << key;
         if (nrep > 0) sstrm << "." << nrep;
       }
-      std::string filename;
-      filename = filename_prefix + sstrm.str() + filename_suffix;
-      std::ofstream ostrm(filename);
+      std::string source;
+      source = source_prefix + sstrm.str() + source_suffix;
+      std::ofstream ostrm(source);
       if (!ostrm) {
-        LOG(ERROR) << "FarPrintStrings: Can't open file: " << filename;
+        LOG(ERROR) << "FarPrintStrings: Can't open file: " << source;
         return;
       }
       ostrm << str;
index 47c1980..d960e3e 100644 (file)
@@ -13,9 +13,9 @@
 namespace fst {
 namespace script {
 
-std::string LoadArcTypeFromFar(const std::string &far_fname);
+std::string LoadArcTypeFromFar(const std::string &far_source);
 
-std::string LoadArcTypeFromFst(const std::string &fst_fname);
+std::string LoadArcTypeFromFst(const std::string &fst_source);
 
 }  // namespace script
 }  // namespace fst
index d5b230f..b6af027 100644 (file)
@@ -35,23 +35,23 @@ static constexpr int32 kSTListFileVersion = 1;
 template <class T, class Writer>
 class STListWriter {
  public:
-  explicit STListWriter(const std::string &filename)
-      : stream_(filename.empty() ? &std::cout
-                                 : new std::ofstream(
-                                       filename, std::ios_base::out |
-                                                     std::ios_base::binary)),
+  explicit STListWriter(const std::string &source)
+      : stream_(source.empty()
+                    ? &std::cout
+                    : new std::ofstream(
+                          source, std::ios_base::out | std::ios_base::binary)),
         error_(false) {
     WriteType(*stream_, kSTListMagicNumber);
     WriteType(*stream_, kSTListFileVersion);
     if (!stream_) {
       FSTERROR() << "STListWriter::STListWriter: Error writing to file: "
-                 << filename;
+                 << source;
       error_ = true;
     }
   }
 
-  static STListWriter<T, Writer> *Create(const std::string &filename) {
-    return new STListWriter<T, Writer>(filename);
+  static STListWriter<T, Writer> *Create(const std::string &source) {
+    return new STListWriter<T, Writer>(source);
   }
 
   void Add(const std::string &key, const T &t) {
@@ -94,12 +94,12 @@ class STListWriter {
 template <class T, class Reader>
 class STListReader {
  public:
-  explicit STListReader(const std::vector<std::string> &filenames)
-      : sources_(filenames), error_(false) {
-    streams_.resize(filenames.size(), 0);
+  explicit STListReader(const std::vector<std::string> &sources)
+      : sources_(sources), error_(false) {
+    streams_.resize(sources.size(), nullptr);
     bool has_stdin = false;
-    for (size_t i = 0; i < filenames.size(); ++i) {
-      if (filenames[i].empty()) {
+    for (size_t i = 0; i < sources.size(); ++i) {
+      if (sources[i].empty()) {
         if (!has_stdin) {
           streams_[i] = &std::cin;
           sources_[i] = "stdin";
@@ -112,10 +112,10 @@ class STListReader {
         }
       } else {
         streams_[i] = new std::ifstream(
-            filenames[i], std::ios_base::in | std::ios_base::binary);
+            sources[i], std::ios_base::in | std::ios_base::binary);
         if (streams_[i]->fail()) {
           FSTERROR() << "STListReader::STListReader: Error reading file: "
-                     << filenames[i];
+                     << sources[i];
           error_ = true;
           return;
         }
@@ -126,13 +126,13 @@ class STListReader {
       ReadType(*streams_[i], &file_version);
       if (magic_number != kSTListMagicNumber) {
         FSTERROR() << "STListReader::STListReader: Wrong file type: "
-                   << filenames[i];
+                   << sources[i];
         error_ = true;
         return;
       }
       if (file_version != kSTListFileVersion) {
         FSTERROR() << "STListReader::STListReader: Wrong file version: "
-                   << filenames[i];
+                   << sources[i];
         error_ = true;
         return;
       }
@@ -161,15 +161,15 @@ class STListReader {
     }
   }
 
-  static STListReader<T, Reader> *Open(const std::string &filename) {
-    std::vector<std::string> filenames;
-    filenames.push_back(filename);
-    return new STListReader<T, Reader>(filenames);
+  static STListReader<T, Reader> *Open(const std::string &source) {
+    std::vector<std::string> sources;
+    sources.push_back(source);
+    return new STListReader<T, Reader>(sources);
   }
 
   static STListReader<T, Reader> *Open(
-      const std::vector<std::string> &filenames) {
-    return new STListReader<T, Reader>(filenames);
+      const std::vector<std::string> &sources) {
+    return new STListReader<T, Reader>(sources);
   }
 
   void Reset() {
@@ -217,7 +217,7 @@ class STListReader {
  private:
   Reader entry_reader_;                  // Read functor.
   std::vector<std::istream *> streams_;  // Input streams.
-  std::vector<std::string> sources_;     // Corresponding filenames.
+  std::vector<std::string> sources_;     // Corresponding sources.
   std::priority_queue<std::pair<std::string, size_t>,
                       std::vector<std::pair<std::string, size_t>>,
                       std::greater<std::pair<std::string, size_t>>>
@@ -233,17 +233,17 @@ class STListReader {
 // The Header type must provide at least the following interface:
 //
 //  struct Header {
-//    void Read(std::istream &strm, const string &filename);
+//    void Read(std::istream &strm, const string &source);
 //  };
 template <class Header>
-bool ReadSTListHeader(const std::string &filename, Header *header) {
-  if (filename.empty()) {
+bool ReadSTListHeader(const std::string &source, Header *header) {
+  if (source.empty()) {
     LOG(ERROR) << "ReadSTListHeader: Can't read header from standard input";
     return false;
   }
-  std::ifstream strm(filename, std::ios_base::in | std::ios_base::binary);
+  std::ifstream strm(source, std::ios_base::in | std::ios_base::binary);
   if (!strm) {
-    LOG(ERROR) << "ReadSTListHeader: Could not open file: " << filename;
+    LOG(ERROR) << "ReadSTListHeader: Could not open file: " << source;
     return false;
   }
   int32 magic_number = 0;
@@ -251,24 +251,24 @@ bool ReadSTListHeader(const std::string &filename, Header *header) {
   int32 file_version = 0;
   ReadType(strm, &file_version);
   if (magic_number != kSTListMagicNumber) {
-    LOG(ERROR) << "ReadSTListHeader: Wrong file type: " << filename;
+    LOG(ERROR) << "ReadSTListHeader: Wrong file type: " << source;
     return false;
   }
   if (file_version != kSTListFileVersion) {
-    LOG(ERROR) << "ReadSTListHeader: Wrong file version: " << filename;
+    LOG(ERROR) << "ReadSTListHeader: Wrong file version: " << source;
     return false;
   }
   std::string key;
   ReadType(strm, &key);
-  header->Read(strm, filename + ":" + key);
+  header->Read(strm, source + ":" + key);
   if (!strm) {
-    LOG(ERROR) << "ReadSTListHeader: Error reading file: " << filename;
+    LOG(ERROR) << "ReadSTListHeader: Error reading file: " << source;
     return false;
   }
   return true;
 }
 
-bool IsSTList(const std::string &filename);
+bool IsSTList(const std::string &source);
 
 }  // namespace fst
 
index 377c495..ef17f79 100644 (file)
@@ -31,24 +31,24 @@ static constexpr int32 kSTTableFileVersion = 1;
 template <class T, class Writer>
 class STTableWriter {
  public:
-  explicit STTableWriter(const std::string &filename)
-      : stream_(filename, std::ios_base::out | std::ios_base::binary),
+  explicit STTableWriter(const std::string &source)
+      : stream_(source, std::ios_base::out | std::ios_base::binary),
         error_(false) {
     WriteType(stream_, kSTTableMagicNumber);
     WriteType(stream_, kSTTableFileVersion);
     if (stream_.fail()) {
       FSTERROR() << "STTableWriter::STTableWriter: Error writing to file: "
-                 << filename;
+                 << source;
       error_ = true;
     }
   }
 
-  static STTableWriter<T, Writer> *Create(const std::string &filename) {
-    if (filename.empty()) {
+  static STTableWriter<T, Writer> *Create(const std::string &source) {
+    if (source.empty()) {
       LOG(ERROR) << "STTableWriter: Writing to standard out unsupported.";
       return nullptr;
     }
-    return new STTableWriter<T, Writer>(filename);
+    return new STTableWriter<T, Writer>(source);
   }
 
   void Add(const std::string &key, const T &t) {
@@ -94,18 +94,18 @@ class STTableWriter {
 template <class T, class Reader>
 class STTableReader {
  public:
-  explicit STTableReader(const std::vector<std::string> &filenames)
-      : sources_(filenames), error_(false) {
+  explicit STTableReader(const std::vector<std::string> &sources)
+      : sources_(sources), error_(false) {
     compare_.reset(new Compare(&keys_));
-    keys_.resize(filenames.size());
-    streams_.resize(filenames.size(), 0);
-    positions_.resize(filenames.size());
-    for (size_t i = 0; i < filenames.size(); ++i) {
+    keys_.resize(sources.size());
+    streams_.resize(sources.size(), nullptr);
+    positions_.resize(sources.size());
+    for (size_t i = 0; i < sources.size(); ++i) {
       streams_[i] = new std::ifstream(
-          filenames[i], std::ios_base::in | std::ios_base::binary);
+          sources[i], std::ios_base::in | std::ios_base::binary);
       if (streams_[i]->fail()) {
         FSTERROR() << "STTableReader::STTableReader: Error reading file: "
-                 << filenames[i];
+                   << sources[i];
         error_ = true;
         return;
       }
@@ -115,13 +115,13 @@ class STTableReader {
       ReadType(*streams_[i], &file_version);
       if (magic_number != kSTTableMagicNumber) {
         FSTERROR() << "STTableReader::STTableReader: Wrong file type: "
-                   << filenames[i];
+                   << sources[i];
         error_ = true;
         return;
       }
       if (file_version != kSTTableFileVersion) {
         FSTERROR() << "STTableReader::STTableReader: Wrong file version: "
-                   << filenames[i];
+                   << sources[i];
         error_ = true;
         return;
       }
@@ -138,7 +138,7 @@ class STTableReader {
         streams_[i]->seekg(positions_[i][0]);
         if (streams_[i]->fail()) {
           FSTERROR() << "STTableReader::STTableReader: Error reading file: "
-                     << filenames[i];
+                     << sources[i];
           error_ = true;
           return;
         }
@@ -151,19 +151,19 @@ class STTableReader {
     for (auto &stream : streams_) delete stream;
   }
 
-  static STTableReader<T, Reader> *Open(const std::string &filename) {
-    if (filename.empty()) {
+  static STTableReader<T, Reader> *Open(const std::string &source) {
+    if (source.empty()) {
       LOG(ERROR) << "STTableReader: Operation not supported on standard input";
       return nullptr;
     }
-    std::vector<std::string> filenames;
-    filenames.push_back(filename);
-    return new STTableReader<T, Reader>(filenames);
+    std::vector<std::string> sources;
+    sources.push_back(source);
+    return new STTableReader<T, Reader>(sources);
   }
 
   static STTableReader<T, Reader> *Open(
-      const std::vector<std::string> &filenames) {
-    return new STTableReader<T, Reader>(filenames);
+      const std::vector<std::string> &sources) {
+    return new STTableReader<T, Reader>(sources);
   }
 
   void Reset() {
@@ -301,17 +301,17 @@ class STTableReader {
 // The Header type must provide at least the following interface:
 //
 //   struct Header {
-//     void Read(std::istream &istrm, const string &filename);
+//     void Read(std::istream &istrm, const string &source);
 //   };
 template <class Header>
-bool ReadSTTableHeader(const std::string &filename, Header *header) {
-  if (filename.empty()) {
+bool ReadSTTableHeader(const std::string &source, Header *header) {
+  if (source.empty()) {
     LOG(ERROR) << "ReadSTTable: Can't read header from standard input";
     return false;
   }
-  std::ifstream strm(filename, std::ios_base::in | std::ios_base::binary);
+  std::ifstream strm(source, std::ios_base::in | std::ios_base::binary);
   if (!strm) {
-    LOG(ERROR) << "ReadSTTableHeader: Could not open file: " << filename;
+    LOG(ERROR) << "ReadSTTableHeader: Could not open file: " << source;
     return false;
   }
   int32 magic_number = 0;
@@ -319,18 +319,18 @@ bool ReadSTTableHeader(const std::string &filename, Header *header) {
   int32 file_version = 0;
   ReadType(strm, &file_version);
   if (magic_number != kSTTableMagicNumber) {
-    LOG(ERROR) << "ReadSTTableHeader: Wrong file type: " << filename;
+    LOG(ERROR) << "ReadSTTableHeader: Wrong file type: " << source;
     return false;
   }
   if (file_version != kSTTableFileVersion) {
-    LOG(ERROR) << "ReadSTTableHeader: Wrong file version: " << filename;
+    LOG(ERROR) << "ReadSTTableHeader: Wrong file version: " << source;
     return false;
   }
   int64 i = -1;
   strm.seekg(-static_cast<int>(sizeof(int64)), std::ios_base::end);
   ReadType(strm, &i);  // Reads number of entries
   if (strm.fail()) {
-    LOG(ERROR) << "ReadSTTableHeader: Error reading file: " << filename;
+    LOG(ERROR) << "ReadSTTableHeader: Error reading file: " << source;
     return false;
   }
   if (i == 0) return true;  // No entry header to read.
@@ -339,15 +339,15 @@ bool ReadSTTableHeader(const std::string &filename, Header *header) {
   strm.seekg(i);
   std::string key;
   ReadType(strm, &key);
-  header->Read(strm, filename + ":" + key);
+  header->Read(strm, source + ":" + key);
   if (strm.fail()) {
-    LOG(ERROR) << "ReadSTTableHeader: Error reading file: " << filename;
+    LOG(ERROR) << "ReadSTTableHeader: Error reading file: " << source;
     return false;
   }
   return true;
 }
 
-bool IsSTTable(const std::string &filename);
+bool IsSTTable(const std::string &source);
 
 }  // namespace fst
 
index 18d2097..b8ef763 100644 (file)
 
 #include <fst/compat.h>
 #include <fst/log.h>
+#include <fst/extensions/linear/linear-fst-data.h>
 #include <fst/fst.h>
 #include <fst/symbol-table.h>
 #include <fst/util.h>
 
-#include <fst/extensions/linear/linear-fst-data.h>
-
 namespace fst {
 
 // Forward declaration
index ae348eb..fdfd379 100644 (file)
@@ -13,9 +13,8 @@
 #include <vector>
 
 #include <fst/compat.h>
-#include <fst/fst.h>
-
 #include <fst/extensions/linear/trie.h>
+#include <fst/fst.h>
 
 namespace fst {
 
@@ -392,7 +391,7 @@ template <class A>
 struct FeatureGroup<A>::InputOutputLabel {
   Label input, output;
 
-  InputOutputLabel(Label i = kNoLabel, Label o = kNoLabel)
+  explicit InputOutputLabel(Label i = kNoLabel, Label o = kNoLabel)
       : input(i), output(o) {}
 
   bool operator==(InputOutputLabel that) const {
index 00f8329..22cc2e1 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <fst/compat.h>
 #include <fst/log.h>
+#include <fst/extensions/linear/linear-fst-data.h>
 #include <fst/extensions/pdt/collection.h>
 #include <fst/bi-table.h>
 #include <fst/cache.h>
@@ -21,8 +22,6 @@
 #include <fst/matcher.h>
 #include <fst/symbol-table.h>
 
-#include <fst/extensions/linear/linear-fst-data.h>
-
 namespace fst {
 
 // Forward declaration of the specialized matcher for both
@@ -493,15 +492,15 @@ class LinearTaggerFst : public ImplToFst<internal::LinearTaggerFstImpl<A>> {
     return new LinearFstMatcherTpl<LinearTaggerFst<A>>(this, match_type);
   }
 
-  static LinearTaggerFst<A> *Read(const std::string &filename) {
-    if (!filename.empty()) {
-      std::ifstream strm(filename,
+  static LinearTaggerFst<A> *Read(const std::string &source) {
+    if (!source.empty()) {
+      std::ifstream strm(source,
                               std::ios_base::in | std::ios_base::binary);
       if (!strm) {
-        LOG(ERROR) << "LinearTaggerFst::Read: Can't open file: " << filename;
+        LOG(ERROR) << "LinearTaggerFst::Read: Can't open file: " << source;
         return nullptr;
       }
-      return Read(strm, FstReadOptions(filename));
+      return Read(strm, FstReadOptions(source));
     } else {
       return Read(std::cin, FstReadOptions("standard input"));
     }
@@ -513,15 +512,15 @@ class LinearTaggerFst : public ImplToFst<internal::LinearTaggerFstImpl<A>> {
     return impl ? new LinearTaggerFst<A>(std::shared_ptr<Impl>(impl)) : nullptr;
   }
 
-  bool Write(const std::string &filename) const override {
-    if (!filename.empty()) {
-      std::ofstream strm(filename,
+  bool Write(const std::string &source) const override {
+    if (!source.empty()) {
+      std::ofstream strm(source,
                                std::ios_base::out | std::ios_base::binary);
       if (!strm) {
-        LOG(ERROR) << "LinearTaggerFst::Write: Can't open file: " << filename;
+        LOG(ERROR) << "LinearTaggerFst::Write: Can't open file: " << source;
         return false;
       }
-      return Write(strm, FstWriteOptions(filename));
+      return Write(strm, FstWriteOptions(source));
     } else {
       return Write(std::cout, FstWriteOptions("standard output"));
     }
@@ -950,16 +949,15 @@ class LinearClassifierFst
     return new LinearFstMatcherTpl<LinearClassifierFst<A>>(this, match_type);
   }
 
-  static LinearClassifierFst<A> *Read(const std::string &filename) {
-    if (!filename.empty()) {
-      std::ifstream strm(filename,
+  static LinearClassifierFst<A> *Read(const std::string &source) {
+    if (!source.empty()) {
+      std::ifstream strm(source,
                               std::ios_base::in | std::ios_base::binary);
       if (!strm) {
-        LOG(ERROR) << "LinearClassifierFst::Read: Can't open file: "
-                   << filename;
+        LOG(ERROR) << "LinearClassifierFst::Read: Can't open file: " << source;
         return nullptr;
       }
-      return Read(strm, FstReadOptions(filename));
+      return Read(strm, FstReadOptions(source));
     } else {
       return Read(std::cin, FstReadOptions("standard input"));
     }
@@ -972,15 +970,15 @@ class LinearClassifierFst
                 : nullptr;
   }
 
-  bool Write(const std::string &filename) const override {
-    if (!filename.empty()) {
-      std::ofstream strm(filename,
+  bool Write(const std::string &source) const override {
+    if (!source.empty()) {
+      std::ofstream strm(source,
                                std::ios_base::out | std::ios_base::binary);
       if (!strm) {
-        LOG(ERROR) << "ProdLmFst::Write: Can't open file: " << filename;
+        LOG(ERROR) << "ProdLmFst::Write: Can't open file: " << source;
         return false;
       }
-      return Write(strm, FstWriteOptions(filename));
+      return Write(strm, FstWriteOptions(source));
     } else {
       return Write(std::cout, FstWriteOptions("standard output"));
     }
index 0b306c1..94af369 100644 (file)
@@ -25,13 +25,14 @@ DECLARE_bool(classifier);
 
 namespace fst {
 namespace script {
-typedef std::tuple<const std::string &, const std::string &,
-                   const std::string &, char **, int, const std::string &,
-                   const std::string &, const std::string &,
-                   const std::string &>
-    LinearCompileArgs;
+
+using LinearCompileArgs =
+    std::tuple<const std::string &, const std::string &, const std::string &,
+               char **, int, const std::string &, const std::string &,
+               const std::string &, const std::string &>;
 
 bool ValidateDelimiter();
+
 bool ValidateEmptySymbol();
 
 // Returns the proper label given the symbol. For symbols other than
@@ -42,13 +43,14 @@ bool ValidateEmptySymbol();
 // right away.
 template <class Arc>
 inline typename Arc::Label LookUp(const std::string &str, SymbolTable *syms) {
-  if (str == FLAGS_start_symbol)
+  if (str == FLAGS_start_symbol) {
     return str == FLAGS_end_symbol ? kNoLabel
                                    : LinearFstData<Arc>::kStartOfSentence;
-  else if (str == FLAGS_end_symbol)
+  } else if (str == FLAGS_end_symbol) {
     return LinearFstData<Arc>::kEndOfSentence;
-  else
+  } else {
     return syms->AddSymbol(str);
+  }
 }
 
 // Splits `str` with `delim` as the delimiter and stores the labels in
@@ -59,8 +61,9 @@ void SplitAndPush(const std::string &str, const char delim, SymbolTable *syms,
   if (str == FLAGS_empty_symbol) return;
   std::istringstream strm(str);
   std::string buf;
-  while (std::getline(strm, buf, delim))
+  while (std::getline(strm, buf, delim)) {
     output->push_back(LookUp<Arc>(buf, syms));
+  }
 }
 
 // Like `std::replace_copy` but returns the number of modifications
@@ -118,10 +121,11 @@ void AddVocab(const std::string &vocab, SymbolTable *isyms, SymbolTable *fsyms,
       LOG(WARNING) << "Ignored: boundary word: " << fields[0];
       continue;
     }
-    if (possible_labels.empty())
+    if (possible_labels.empty()) {
       num_added += builder->AddWord(word, feature_labels);
-    else
+    } else {
       num_added += builder->AddWord(word, feature_labels, possible_labels);
+    }
   }
   VLOG(1) << "Read " << num_added << " words in " << num_line << " lines from "
           << vocab;
@@ -139,9 +143,10 @@ void AddVocab(const std::string &vocab, SymbolTable *isyms, SymbolTable *fsyms,
   typename Arc::Label word;
   while (GetVocabRecord<Arc>(vocab, in, isyms, fsyms, osyms, &word,
                              &feature_labels, &possible_labels, &num_line)) {
-    if (!possible_labels.empty())
+    if (!possible_labels.empty()) {
       LOG(FATAL)
           << "Classifier vocabulary should not have possible output constraint";
+    }
     if (word == kNoLabel) {
       LOG(WARNING) << "Ignored: boundary word: " << fields[0];
       continue;
@@ -187,9 +192,10 @@ void AddModel(const std::string &model, SymbolTable *fsyms, SymbolTable *osyms,
   typename Arc::Weight weight;
   while (GetModelRecord<Arc>(model, in, fsyms, osyms, &input_labels,
                              &output_labels, &weight, &num_line)) {
-    if (output_labels.empty())
+    if (output_labels.empty()) {
       LOG(FATAL) << "Empty output sequence in source " << model << ", line "
                  << num_line;
+    }
 
     const typename Arc::Label marks[] = {LinearFstData<Arc>::kStartOfSentence,
                                          LinearFstData<Arc>::kEndOfSentence};
@@ -205,9 +211,10 @@ void AddModel(const std::string &model, SymbolTable *fsyms, SymbolTable *osyms,
             ReplaceCopy(output_labels.begin(), output_labels.end(),
                         copy_output.begin(), kNoLabel, marks[j]);
         if ((num_input_changes > 0 || i == 0) &&
-            (num_output_changes > 0 || j == 0))
+            (num_output_changes > 0 || j == 0)) {
           num_added +=
               builder->AddWeight(group, copy_input, copy_output, weight);
+        }
       }
     }
   }
@@ -229,9 +236,10 @@ void AddModel(const std::string &model, SymbolTable *fsyms, SymbolTable *osyms,
     strm >> future_size;
     if (!strm) LOG(FATAL) << "Can't read future size: " << model;
   }
-  if (future_size != 0)
+  if (future_size != 0) {
     LOG(FATAL) << "Classifier model must have future size = 0; got "
                << future_size << " from " << model;
+  }
   size_t num_line = 1, num_added = 0;
   const int group = builder->AddGroup();
   VLOG(1) << "Group " << group << ": from " << model << "; future size is "
@@ -242,9 +250,10 @@ void AddModel(const std::string &model, SymbolTable *fsyms, SymbolTable *osyms,
   typename Arc::Weight weight;
   while (GetModelRecord<Arc>(model, in, fsyms, osyms, &input_labels,
                              &output_labels, &weight, &num_line)) {
-    if (output_labels.size() != 1)
+    if (output_labels.size() != 1) {
       LOG(FATAL) << "Output not a single label in source " << model << ", line "
                  << num_line;
+    }
 
     const typename Arc::Label marks[] = {LinearFstData<Arc>::kStartOfSentence,
                                          LinearFstData<Arc>::kEndOfSentence};
@@ -256,8 +265,9 @@ void AddModel(const std::string &model, SymbolTable *fsyms, SymbolTable *osyms,
       size_t num_input_changes =
           ReplaceCopy(input_labels.begin(), input_labels.end(),
                       copy_input.begin(), kNoLabel, marks[i]);
-      if (num_input_changes > 0 || i == 0)
+      if (num_input_changes > 0 || i == 0) {
         num_added += builder->AddWeight(group, copy_input, pred, weight);
+      }
     }
   }
   VLOG(1) << "Group " << group << ": read " << num_added << " weight(s) in "
@@ -297,18 +307,17 @@ void LinearCompileTpl(LinearCompileArgs *args) {
                                                 &osyms);
 
     AddVocab(vocab, &isyms, &fsyms, &osyms, &builder);
-    for (int i = 0; i < models_length; ++i)
+    for (int i = 0; i < models_length; ++i) {
       AddModel(models[i], &fsyms, &osyms, &builder);
-
+    }
     LinearClassifierFst<Arc> fst(builder.Dump(), num_classes, &isyms, &osyms);
     fst.Write(out);
   } else {
     LinearFstDataBuilder<Arc> builder(&isyms, &fsyms, &osyms);
-
     AddVocab(vocab, &isyms, &fsyms, &osyms, &builder);
-    for (int i = 0; i < models_length; ++i)
+    for (int i = 0; i < models_length; ++i) {
       AddModel(models[i], &fsyms, &osyms, &builder);
-
+    }
     LinearTaggerFst<Arc> fst(builder.Dump(), &isyms, &osyms);
     fst.Write(out);
   }
@@ -339,9 +348,10 @@ bool GetVocabRecord(const std::string &vocab, std::istream &strm,  // NOLINT
 
   std::vector<std::string> fields;
   SplitByWhitespace(line, &fields);
-  if (fields.size() != 3)
+  if (fields.size() != 3) {
     LOG(FATAL) << "Wrong number of fields in source " << vocab << ", line "
                << num_line;
+  }
 
   feature_labels->clear();
   possible_labels->clear();
@@ -367,9 +377,10 @@ bool GetModelRecord(const std::string &model, std::istream &strm,  // NOLINT
 
   std::vector<std::string> fields;
   SplitByWhitespace(line, &fields);
-  if (fields.size() != 3)
+  if (fields.size() != 3) {
     LOG(FATAL) << "Wrong number of fields in source " << model << ", line "
                << num_line;
+  }
 
   input_labels->clear();
   output_labels->clear();
@@ -385,10 +396,8 @@ bool GetModelRecord(const std::string &model, std::istream &strm,  // NOLINT
 
   return true;
 }
+
 }  // namespace script
 }  // namespace fst
 
-#define REGISTER_FST_LINEAR_OPERATIONS(Arc) \
-  REGISTER_FST_OPERATION(LinearCompileTpl, Arc, LinearCompileArgs);
-
 #endif  // FST_EXTENSIONS_LINEAR_LINEARSCRIPT_H_
index 1b5d2ea..ca40e4f 100644 (file)
@@ -5,8 +5,8 @@
 #define FST_EXTENSIONS_LINEAR_LOGLINEAR_APPLY_H_
 
 #include <fst/compat.h>
-#include <fst/arc.h>
 #include <fst/arc-map.h>
+#include <fst/arc.h>
 #include <fst/compose.h>
 #include <fst/determinize.h>
 #include <fst/float-weight.h>
index 0e06cdc..026c8f9 100644 (file)
@@ -24,7 +24,7 @@ struct MPdtExpandFstOptions : public CacheOptions {
   internal::MPdtStack<typename Arc::StateId, typename Arc::Label> *stack;
   PdtStateTable<typename Arc::StateId, typename Arc::StateId> *state_table;
 
-  MPdtExpandFstOptions(
+  explicit MPdtExpandFstOptions(
       const CacheOptions &opts = CacheOptions(), bool kp = false,
       internal::MPdtStack<typename Arc::StateId, typename Arc::Label> *s =
           nullptr,
index 6634099..fb4d757 100644 (file)
@@ -33,8 +33,9 @@ namespace script {
 
 using MPdtComposeArgs =
     std::tuple<const FstClass &, const FstClass &,
-               const std::vector<LabelPair> &, const std::vector<int64> &,
-               MutableFstClass *, const MPdtComposeOptions &, bool>;
+               const std::vector<std::pair<int64, int64>> &,
+               const std::vector<int64> &, MutableFstClass *,
+               const MPdtComposeOptions &, bool>;
 
 template <class Arc>
 void MPdtCompose(MPdtComposeArgs *args) {
@@ -59,12 +60,12 @@ void MPdtCompose(MPdtComposeArgs *args) {
 }
 
 void MPdtCompose(const FstClass &ifst1, const FstClass &ifst2,
-                 const std::vector<LabelPair> &parens,
+                 const std::vector<std::pair<int64, int64>> &parens,
                  const std::vector<int64> &assignments, MutableFstClass *ofst,
                  const MPdtComposeOptions &copts, bool left_pdt);
 
 using MPdtExpandArgs =
-    std::tuple<const FstClass &, const std::vector<LabelPair> &,
+    std::tuple<const FstClass &, const std::vector<std::pair<int64, int64>> &,
                const std::vector<int64> &, MutableFstClass *,
                const MPdtExpandOptions &>;
 
@@ -88,12 +89,13 @@ void MPdtExpand(MPdtExpandArgs *args) {
                            std::get<4>(*args).keep_parentheses));
 }
 
-void MPdtExpand(const FstClass &ifst, const std::vector<LabelPair> &parens,
+void MPdtExpand(const FstClass &ifst,
+                const std::vector<std::pair<int64, int64>> &parens,
                 const std::vector<int64> &assignments, MutableFstClass *ofst,
                 const MPdtExpandOptions &opts);
 
 using MPdtReverseArgs =
-    std::tuple<const FstClass &, const std::vector<LabelPair> &,
+    std::tuple<const FstClass &, const std::vector<std::pair<int64, int64>> &,
                std::vector<int64> *, MutableFstClass *>;
 
 template <class Arc>
@@ -117,11 +119,12 @@ void MPdtReverse(MPdtReverseArgs *args) {
             std::get<2>(*args)->begin());
 }
 
-void MPdtReverse(const FstClass &ifst, const std::vector<LabelPair> &parens,
+void MPdtReverse(const FstClass &ifst,
+                 const std::vector<std::pair<int64, int64>> &parens,
                  std::vector<int64> *assignments, MutableFstClass *ofst);
 
 using PrintMPdtInfoArgs =
-    std::tuple<const FstClass &, const std::vector<LabelPair> &,
+    std::tuple<const FstClass &, const std::vector<std::pair<int64, int64>> &,
                const std::vector<int64> &>;
 
 template <class Arc>
@@ -142,15 +145,11 @@ void PrintMPdtInfo(PrintMPdtInfoArgs *args) {
   mpdtinfo.Print();
 }
 
-void PrintMPdtInfo(const FstClass &ifst, const std::vector<LabelPair> &parens,
+void PrintMPdtInfo(const FstClass &ifst,
+                   const std::vector<std::pair<int64, int64>> &parens,
                    const std::vector<int64> &assignments);
 
 }  // namespace script
 }  // namespace fst
 
-#define REGISTER_FST_MPDT_OPERATIONS(ArcType)                    \
-  REGISTER_FST_OPERATION(MPdtCompose, ArcType, MPdtComposeArgs); \
-  REGISTER_FST_OPERATION(MPdtExpand, ArcType, MPdtExpandArgs);   \
-  REGISTER_FST_OPERATION(MPdtReverse, ArcType, MPdtReverseArgs); \
-  REGISTER_FST_OPERATION(PrintMPdtInfo, ArcType, PrintMPdtInfoArgs)
 #endif  // FST_EXTENSIONS_MPDT_MPDTSCRIPT_H_
index d7b98ac..535f592 100644 (file)
@@ -18,13 +18,13 @@ namespace fst {
 
 // Returns true on success.
 template <typename Label>
-bool ReadLabelTriples(const std::string &filename,
+bool ReadLabelTriples(const std::string &source,
                       std::vector<std::pair<Label, Label>> *pairs,
                       std::vector<Label> *assignments,
                       bool allow_negative = false) {
-  std::ifstream fstrm(filename);
+  std::ifstream fstrm(source);
   if (!fstrm) {
-    LOG(ERROR) << "ReadIntTriples: Can't open file: " << filename;
+    LOG(ERROR) << "ReadIntTriples: Can't open file: " << source;
     return false;
   }
   static constexpr auto kLineLen = 8096;
@@ -39,16 +39,16 @@ bool ReadLabelTriples(const std::string &filename,
     if (col.empty() || col[0][0] == '\0' || col[0][0] == '#') continue;
     if (col.size() != 3) {
       LOG(ERROR) << "ReadLabelTriples: Bad number of columns, "
-                 << "file = " << filename << ", line = " << nline;
+                 << "file = " << source << ", line = " << nline;
       return false;
     }
     bool err;
-    const Label i1 = StrToInt64(col[0], filename, nline, allow_negative, &err);
+    const Label i1 = StrToInt64(col[0], source, nline, allow_negative, &err);
     if (err) return false;
-    const Label i2 = StrToInt64(col[1], filename, nline, allow_negative, &err);
+    const Label i2 = StrToInt64(col[1], source, nline, allow_negative, &err);
     if (err) return false;
     using Level = Label;
-    const Level i3 = StrToInt64(col[2], filename, nline, allow_negative, &err);
+    const Level i3 = StrToInt64(col[2], source, nline, allow_negative, &err);
     if (err) return false;
     pairs->push_back(std::make_pair(i1, i2));
     assignments->push_back(i3);
@@ -58,16 +58,16 @@ bool ReadLabelTriples(const std::string &filename,
 
 // Returns true on success.
 template <typename Label>
-bool WriteLabelTriples(const std::string &filename,
+bool WriteLabelTriples(const std::string &source,
                        const std::vector<std::pair<Label, Label>> &pairs,
                        const std::vector<Label> &assignments) {
   if (pairs.size() != assignments.size()) {
     LOG(ERROR) << "WriteLabelTriples: Pairs and assignments of different sizes";
     return false;
   }
-  std::ofstream fstrm(filename);
+  std::ofstream fstrm(source);
   if (!fstrm) {
-    LOG(ERROR) << "WriteLabelTriples: Can't open file: " << filename;
+    LOG(ERROR) << "WriteLabelTriples: Can't open file: " << source;
     return false;
   }
   for (size_t n = 0; n < pairs.size(); ++n)
@@ -75,7 +75,7 @@ bool WriteLabelTriples(const std::string &filename,
           << "\n";
   if (!fstrm) {
     LOG(ERROR) << "WriteLabelTriples: Write failed: "
-               << (filename.empty() ? "standard output" : filename);
+               << (source.empty() ? "standard output" : source);
     return false;
   }
   return true;
index 09ad6d7..a6a8446 100644 (file)
 // occurs.
 //
 // To handle overflows, a "primary" index containing a running count of
-// bits set in each block is created using the type uint64.
+// bits set in each block is created using the type uint32.  Therefore,
+// only bitstrings with < 2**32 ones are supported.
+//
+// For each 64 bits of input there are 16 bits of secondary index and
+// 32/kSecondaryBlockSize == 32/1023 bits of primary index,
+// for a 25.05% space overhead.
 
 namespace fst {
 
 class BitmapIndex {
  public:
-  static size_t StorageSize(size_t size) {
-    return ((size + kStorageBlockMask) >> kStorageLogBitSize);
+  static size_t StorageSize(size_t num_bits) {
+    return ((num_bits + kStorageBlockMask) >> kStorageLogBitSize);
   }
 
-  BitmapIndex() : bits_(nullptr), size_(0) {}
+  BitmapIndex() = default;
+  BitmapIndex(BitmapIndex &&) = default;
+  BitmapIndex &operator=(BitmapIndex &&) = default;
 
   bool Get(size_t index) const {
     return (bits_[index >> kStorageLogBitSize] &
@@ -46,13 +53,25 @@ class BitmapIndex {
     bits[index >> kStorageLogBitSize] &= ~(kOne << (index & kStorageBlockMask));
   }
 
-  size_t Bits() const { return size_; }
+  size_t Bits() const { return num_bits_; }
+
+  size_t ArraySize() const { return StorageSize(num_bits_); }
 
-  size_t ArraySize() const { return StorageSize(size_); }
+  // Number of bytes used to store the bit vector.
+  size_t ArrayBytes() const {
+    return ArraySize() * sizeof(bits_[0]);
+  }
+
+  // Number of bytes used to store the primary and secondary indices.
+  size_t IndexBytes() const {
+    return (primary_index_.size() * sizeof(primary_index_[0]) +
+            secondary_index_.size() * sizeof(secondary_index_[0]));
+  }
 
   // Returns the number of one bits in the bitmap
   size_t GetOnesCount() const {
-    return primary_index_[primary_index_size() - 1];
+    // Empty bitmaps still have a non-empty primary index.
+    return primary_index_.back();
   }
 
   // Returns the number of one bits in positions 0 to limit - 1.
@@ -97,7 +116,7 @@ class BitmapIndex {
   // Rebuilds from index for the associated Bitmap, should be called
   // whenever changes have been made to the Bitmap or else behavior
   // of the indexed bitmap methods will be undefined.
-  void BuildIndex(const uint64* bits, size_t size);
+  void BuildIndex(const uint64* bits, size_t num_bits);
 
   // the secondary index accumulates counts until it can possibly overflow
   // this constant computes the number of uint64 units that can fit into
@@ -105,6 +124,7 @@ class BitmapIndex {
   static const uint64 kOne = 1;
   static const uint32 kStorageBitSize = 64;
   static const uint32 kStorageLogBitSize = 6;
+  // Number of secondary index entries per primary index entry.
   static const uint32 kSecondaryBlockSize =
       ((1 << 16) - 1) >> kStorageLogBitSize;
 
@@ -118,9 +138,11 @@ class BitmapIndex {
   // count of the population of one bits contained in [0,i), there is
   // no reason to have an element in the zeroth position as this value would
   // necessarily be zero.  (The bits are indexed in a zero based way.)  Thus
-  // we don't store the 0th element in either index.  Both of the following
-  // functions, if greater than 0, must be decremented by one before retreiving
-  // the value from the corresponding array.
+  // we don't store the 0th element in either index for non-empty bitmaps.
+  // For empty bitmaps, the 0 is stored for the primary index, but not the
+  // secondary index.  Both of the following functions, if greater than 0,
+  // must be decremented by one before retrieving the value from the
+  // corresponding array.
   // returns the 1 + the block that contains the bitindex in question
   // the inverted version works the same but looks for zeros using an inverted
   // view of the index
@@ -147,19 +169,23 @@ class BitmapIndex {
   // The primary index is the actual running
   // count of one bits set for all blocks (and, thus, all uint64s).
   size_t primary_index_size() const {
+    // Special-case empty bitmaps to still store the 0 in the primary index.
+    if (ArraySize() == 0) return 1;
     return (ArraySize() + kSecondaryBlockSize - 1) / kSecondaryBlockSize;
   }
 
-  const uint64* bits_;
-  size_t size_;
+  const uint64* bits_ = nullptr;
+  size_t num_bits_ = 0;
 
   // The primary index contains the running popcount of all blocks
-  // which means the nth value contains the popcounts of
-  // [0,n*kSecondaryBlockSize], however, the 0th element is omitted.
+  // which means the nth value contains the popcounts of uint64 elements
+  // [0,n*kSecondaryBlockSize], however, the 0th element is omitted for
+  // non-empty bitmaps.
   std::vector<uint32> primary_index_;
   // The secondary index contains the running popcount of the associated
   // bitmap.  It is the same length (in units of uint16) as the
-  // bitmap's map is in units of uint64s.
+  // bitmap's map is in units of uint64s, namely ArraySize() ==
+  // StorageSize(num_bits_).
   std::vector<uint16> secondary_index_;
 };
 
index 2c2fa76..15e7f11 100644 (file)
@@ -97,9 +97,9 @@ class NGramFstImpl : public FstImpl<A> {
 
   static NGramFstImpl<A> *Read(std::istream &strm,  // NOLINT
                                const FstReadOptions &opts) {
-    auto impl = std::make_unique<NGramFstImpl<A>>();
+    auto impl = fst::make_unique<NGramFstImpl<A>>();
     FstHeader hdr;
-    if (!impl->ReadHeader(strm, opts, kMinFileVersion, &hdr)) return 0;
+    if (!impl->ReadHeader(strm, opts, kMinFileVersion, &hdr)) return nullptr;
     uint64 num_states, num_futures, num_final;
     const size_t offset =
         sizeof(num_states) + sizeof(num_futures) + sizeof(num_final);
@@ -165,7 +165,7 @@ class NGramFstImpl : public FstImpl<A> {
   StateId NumStates() const { return num_states_; }
 
   void InitStateIterator(StateIteratorData<A> *data) const {
-    data->base = 0;
+    data->base = nullptr;
     data->nstates = num_states_;
   }
 
@@ -380,15 +380,15 @@ class NGramFst : public ImplToExpandedFst<internal::NGramFstImpl<A>> {
     return impl ? new NGramFst<A>(std::shared_ptr<Impl>(impl)) : nullptr;
   }
 
-  static NGramFst<A> *Read(const std::string &filename) {
-    if (!filename.empty()) {
-      std::ifstream strm(filename,
+  static NGramFst<A> *Read(const std::string &source) {
+    if (!source.empty()) {
+      std::ifstream strm(source,
                               std::ios_base::in | std::ios_base::binary);
       if (!strm.good()) {
-        LOG(ERROR) << "NGramFst::Read: Can't open file: " << filename;
+        LOG(ERROR) << "NGramFst::Read: Can't open file: " << source;
         return nullptr;
       }
-      return Read(strm, FstReadOptions(filename));
+      return Read(strm, FstReadOptions(source));
     } else {
       return Read(std::cin, FstReadOptions("standard input"));
     }
@@ -398,8 +398,8 @@ class NGramFst : public ImplToExpandedFst<internal::NGramFstImpl<A>> {
     return GetImpl()->Write(strm, opts);
   }
 
-  bool Write(const std::string &filename) const override {
-    return Fst<A>::WriteFile(filename);
+  bool Write(const std::string &source) const override {
+    return Fst<A>::WriteFile(source);
   }
 
   inline void InitStateIterator(StateIteratorData<A> *data) const override {
@@ -488,12 +488,12 @@ NGramFstImpl<A>::NGramFstImpl(const Fst<A> &fst,
   }
 
   int64 num_states = CountStates(fst);
-  Label *context = new Label[num_states];
+  std::vector<Label> context(num_states, 0);
 
   // Find the unigram state by starting from the start state, following
   // epsilons.
   StateId unigram = fst.Start();
-  while (1) {
+  while (true) {
     if (unigram == kNoStateId) {
       FSTERROR() << "Could not identify unigram state";
       SetProperties(kError, kError);
@@ -591,8 +591,6 @@ NGramFstImpl<A>::NGramFstImpl(const Fst<A> &fst,
     ArcSort(&context_fst, ILabelCompare<Arc>());
   }
 
-  delete[] context;
-
   uint64 b64;
   Weight weight;
   Label label = kNoLabel;
@@ -1004,21 +1002,21 @@ class ArcIterator<NGramFst<A>> : public ArcIteratorBase<A> {
     }
   }
 
-  uint32 Flags() const final { return flags_; }
+  uint8 Flags() const final { return flags_; }
 
-  void SetFlags(uint32 flags, uint32 mask) final {
+  void SetFlags(uint8 flags, uint8 mask) final {
     flags_ &= ~mask;
     flags_ |= (flags & kArcValueFlags);
   }
 
  private:
   mutable Arc arc_;
-  mutable uint32 lazy_;
+  mutable uint8 lazy_;
   const internal::NGramFstImpl<A> *impl_;  // Borrowed reference.
   mutable NGramFstInst<A> inst_;
 
   size_t i_;
-  uint32 flags_;
+  uint8 flags_;
 };
 
 }  // namespace fst
index abb55fb..e21f2d8 100644 (file)
@@ -74,8 +74,8 @@ class PdtExpandFstImpl : public CacheImpl<Arc> {
         stack_(opts.stack ? opts.stack : new PdtStack<StateId, Label>(parens)),
         state_table_(opts.state_table ? opts.state_table
                                       : new PdtStateTable<StateId, StackId>()),
-        own_stack_(opts.stack == 0),
-        own_state_table_(opts.state_table == 0),
+        own_stack_(opts.stack == nullptr),
+        own_state_table_(opts.state_table == nullptr),
         keep_parentheses_(opts.keep_parentheses) {
     SetType("expand");
     const auto props = fst.Properties(kFstProperties, false);
@@ -881,8 +881,8 @@ struct PdtExpandOptions {
   bool keep_parentheses;
   Weight weight_threshold;
 
-  PdtExpandOptions(bool connect = true, bool keep_parentheses = false,
-                   Weight weight_threshold = Weight::Zero())
+  explicit PdtExpandOptions(bool connect = true, bool keep_parentheses = false,
+                            Weight weight_threshold = Weight::Zero())
       : connect(connect),
         keep_parentheses(keep_parentheses),
         weight_threshold(std::move(weight_threshold)) {}
index d6c5946..f1ea637 100644 (file)
@@ -124,7 +124,7 @@ struct PdtStateTuple {
   StateId state_id;
   StackId stack_id;
 
-  PdtStateTuple(StateId state_id = kNoStateId, StackId stack_id = -1)
+  explicit PdtStateTuple(StateId state_id = kNoStateId, StackId stack_id = -1)
       : state_id(state_id), stack_id(stack_id) {}
 };
 
index a578a37..6dd8aa7 100644 (file)
@@ -29,7 +29,7 @@ namespace script {
 
 using PdtComposeArgs =
     std::tuple<const FstClass &, const FstClass &,
-               const std::vector<LabelPair> &, MutableFstClass *,
+               const std::vector<std::pair<int64, int64>> &, MutableFstClass *,
                const PdtComposeOptions &, bool>;
 
 template <class Arc>
@@ -52,7 +52,7 @@ void PdtCompose(PdtComposeArgs *args) {
 }
 
 void PdtCompose(const FstClass &ifst1, const FstClass &ifst2,
-                const std::vector<LabelPair> &parens,
+                const std::vector<std::pair<int64, int64>> &parens,
                 MutableFstClass *ofst, const PdtComposeOptions &opts,
                 bool left_pdt);
 
@@ -66,7 +66,7 @@ struct PdtExpandOptions {
 };
 
 using PdtExpandArgs =
-    std::tuple<const FstClass &, const std::vector<LabelPair> &,
+    std::tuple<const FstClass &, const std::vector<std::pair<int64, int64>> &,
                MutableFstClass *, const PdtExpandOptions &>;
 
 template <class Arc>
@@ -87,17 +87,19 @@ void PdtExpand(PdtExpandArgs *args) {
                    .weight_threshold.GetWeight<typename Arc::Weight>())));
 }
 
-void PdtExpand(const FstClass &ifst, const std::vector<LabelPair> &parens,
+void PdtExpand(const FstClass &ifst,
+               const std::vector<std::pair<int64, int64>> &parens,
                MutableFstClass *ofst, const PdtExpandOptions &opts);
 
-void PdtExpand(const FstClass &ifst, const std::vector<LabelPair> &parens,
+void PdtExpand(const FstClass &ifst,
+               const std::vector<std::pair<int64, int64>> &parens,
                MutableFstClass *ofst, bool connect, bool keep_parentheses,
                const WeightClass &weight_threshold);
 
 using PdtReplaceArgs =
-    std::tuple<const std::vector<LabelFstClassPair> &, MutableFstClass *,
-               std::vector<LabelPair> *, int64, PdtParserType, int64,
-               const std::string &, const std::string &>;
+    std::tuple<const std::vector<std::pair<int64, const FstClass *>> &,
+               MutableFstClass *, std::vector<std::pair<int64, int64>> *, int64,
+               PdtParserType, int64, const std::string &, const std::string &>;
 
 template <class Arc>
 void PdtReplace(PdtReplaceArgs *args) {
@@ -121,15 +123,16 @@ void PdtReplace(PdtReplaceArgs *args) {
             std::get<2>(*args)->begin());
 }
 
-void PdtReplace(const std::vector<LabelFstClassPair> &pairs,
-                MutableFstClass *ofst, std::vector<LabelPair> *parens,
-                int64 root, PdtParserType parser_type = PDT_LEFT_PARSER,
+void PdtReplace(const std::vector<std::pair<int64, const FstClass *>> &pairs,
+                MutableFstClass *ofst,
+                std::vector<std::pair<int64, int64>> *parens, int64 root,
+                PdtParserType parser_type = PDT_LEFT_PARSER,
                 int64 start_paren_labels = kNoLabel,
                 const std::string &left_paren_prefix = "(_",
                 const std::string &right_paren_prefix = "_)");
 
 using PdtReverseArgs =
-    std::tuple<const FstClass &, const std::vector<LabelPair> &,
+    std::tuple<const FstClass &, const std::vector<std::pair<int64, int64>> &,
                MutableFstClass *>;
 
 template <class Arc>
@@ -146,7 +149,8 @@ void PdtReverse(PdtReverseArgs *args) {
   Reverse(fst, typed_parens, ofst);
 }
 
-void PdtReverse(const FstClass &ifst, const std::vector<LabelPair> &,
+void PdtReverse(const FstClass &ifst,
+                const std::vector<std::pair<int64, int64>> &,
                 MutableFstClass *ofst);
 
 // PDT SHORTESTPATH
@@ -156,13 +160,13 @@ struct PdtShortestPathOptions {
   bool keep_parentheses;
   bool path_gc;
 
-  PdtShortestPathOptions(QueueType qt = FIFO_QUEUE, bool kp = false,
-                         bool gc = true)
+  explicit PdtShortestPathOptions(QueueType qt = FIFO_QUEUE, bool kp = false,
+                                  bool gc = true)
       : queue_type(qt), keep_parentheses(kp), path_gc(gc) {}
 };
 
 using PdtShortestPathArgs =
-    std::tuple<const FstClass &, const std::vector<LabelPair> &,
+    std::tuple<const FstClass &, const std::vector<std::pair<int64, int64>> &,
                MutableFstClass *, const PdtShortestPathOptions &>;
 
 template <class Arc>
@@ -204,14 +208,15 @@ void PdtShortestPath(PdtShortestPathArgs *args) {
   }
 }
 
-void PdtShortestPath(const FstClass &ifst,
-    const std::vector<LabelPair> &parens, MutableFstClass *ofst,
+void PdtShortestPath(
+    const FstClass &ifst, const std::vector<std::pair<int64, int64>> &parens,
+    MutableFstClass *ofst,
     const PdtShortestPathOptions &opts = PdtShortestPathOptions());
 
 // PRINT INFO
 
 using PrintPdtInfoArgs =
-    std::pair<const FstClass &, const std::vector<LabelPair> &>;
+    std::pair<const FstClass &, const std::vector<std::pair<int64, int64>> &>;
 
 template <class Arc>
 void PrintPdtInfo(PrintPdtInfoArgs *args) {
@@ -227,7 +232,8 @@ void PrintPdtInfo(PrintPdtInfoArgs *args) {
   PrintPdtInfo(pdtinfo);
 }
 
-void PrintPdtInfo(const FstClass &ifst, const std::vector<LabelPair> &parens);
+void PrintPdtInfo(const FstClass &ifst,
+                  const std::vector<std::pair<int64, int64>> &parens);
 
 }  // namespace script
 }  // namespace fst
index fd75e30..3ed8710 100644 (file)
@@ -114,7 +114,7 @@ class PdtParser {
       if (!CompatSymbols(fst_array[0].second->OutputSymbols(),
                          fst_array[i].second->OutputSymbols())) {
         FSTERROR() << "PdtParser: Output symbol table of input FST " << i
-                   << " does not match input symbol table of 0th input FST";
+                   << " does not match output symbol table of 0th input FST";
         error_ = true;
       }
       fst_array_.emplace_back(fst_array[i].first, fst_array[i].second->Copy());
index 2483c23..2ed7a30 100644 (file)
@@ -23,7 +23,8 @@ struct PdtShortestPathOptions {
   bool keep_parentheses;
   bool path_gc;
 
-  PdtShortestPathOptions(bool keep_parentheses = false, bool path_gc = true)
+  explicit PdtShortestPathOptions(bool keep_parentheses = false,
+                                  bool path_gc = true)
       : keep_parentheses(keep_parentheses), path_gc(path_gc) {}
 };
 
@@ -61,7 +62,7 @@ class PdtShortestPathData {
     StateId state;  // PDT state.
     StateId start;  // PDT paren "start" state.
 
-    SearchState(StateId s = kNoStateId, StateId t = kNoStateId)
+    explicit SearchState(StateId s = kNoStateId, StateId t = kNoStateId)
         : state(s), start(t) {}
 
     bool operator==(const SearchState &other) const {
@@ -73,8 +74,9 @@ class PdtShortestPathData {
   // Specifies paren ID, source and dest "start" states of a paren. These are
   // the "start" states of the respective sub-graphs.
   struct ParenSpec {
-    ParenSpec(Label paren_id = kNoLabel, StateId src_start = kNoStateId,
-              StateId dest_start = kNoStateId)
+    explicit ParenSpec(Label paren_id = kNoLabel,
+                       StateId src_start = kNoStateId,
+                       StateId dest_start = kNoStateId)
         : paren_id(paren_id), src_start(src_start), dest_start(dest_start) {}
 
     Label paren_id;
@@ -102,7 +104,7 @@ class PdtShortestPathData {
     uint8 flags;         // First byte reserved for PdtShortestPathData use.
   };
 
-  PdtShortestPathData(bool gc)
+  explicit PdtShortestPathData(bool gc)
       : gc_(gc), nstates_(0), ngc_(0), finished_(false) {}
 
   ~PdtShortestPathData() {
index acc51c9..e2b1475 100644 (file)
@@ -136,47 +136,28 @@ extern const char phi_fst_type[];
 extern const char input_phi_fst_type[];
 extern const char output_phi_fst_type[];
 
-using StdPhiFst =
-    MatcherFst<ConstFst<StdArc>, PhiFstMatcher<SortedMatcher<ConstFst<StdArc>>>,
+template <class Arc>
+using PhiFst =
+    MatcherFst<ConstFst<Arc>, PhiFstMatcher<SortedMatcher<ConstFst<Arc>>>,
                phi_fst_type>;
 
-using LogPhiFst =
-    MatcherFst<ConstFst<LogArc>, PhiFstMatcher<SortedMatcher<ConstFst<LogArc>>>,
-               phi_fst_type>;
-
-using Log64PhiFst = MatcherFst<ConstFst<Log64Arc>,
-                               PhiFstMatcher<SortedMatcher<ConstFst<Log64Arc>>>,
-                               input_phi_fst_type>;
-
-using StdInputPhiFst =
-    MatcherFst<ConstFst<StdArc>, PhiFstMatcher<SortedMatcher<ConstFst<StdArc>>,
-                                               kPhiFstMatchInput>,
-               input_phi_fst_type>;
+using StdPhiFst = PhiFst<StdArc>;
 
-using LogInputPhiFst =
-    MatcherFst<ConstFst<LogArc>, PhiFstMatcher<SortedMatcher<ConstFst<LogArc>>,
-                                               kPhiFstMatchInput>,
+template <class Arc>
+using InputPhiFst =
+    MatcherFst<ConstFst<Arc>,
+               PhiFstMatcher<SortedMatcher<ConstFst<Arc>>, kPhiFstMatchInput>,
                input_phi_fst_type>;
 
-using Log64InputPhiFst = MatcherFst<
-    ConstFst<Log64Arc>,
-    PhiFstMatcher<SortedMatcher<ConstFst<Log64Arc>>, kPhiFstMatchInput>,
-    input_phi_fst_type>;
-
-using StdOutputPhiFst =
-    MatcherFst<ConstFst<StdArc>, PhiFstMatcher<SortedMatcher<ConstFst<StdArc>>,
-                                               kPhiFstMatchOutput>,
-               output_phi_fst_type>;
+using StdInputPhiFst = InputPhiFst<StdArc>;
 
-using LogOutputPhiFst =
-    MatcherFst<ConstFst<LogArc>, PhiFstMatcher<SortedMatcher<ConstFst<LogArc>>,
-                                               kPhiFstMatchOutput>,
+template <class Arc>
+using OutputPhiFst =
+    MatcherFst<ConstFst<Arc>,
+               PhiFstMatcher<SortedMatcher<ConstFst<Arc>>, kPhiFstMatchOutput>,
                output_phi_fst_type>;
 
-using Log64OutputPhiFst = MatcherFst<
-    ConstFst<Log64Arc>,
-    PhiFstMatcher<SortedMatcher<ConstFst<Log64Arc>>, kPhiFstMatchOutput>,
-    output_phi_fst_type>;
+using StdOutputPhiFst = OutputPhiFst<StdArc>;
 
 }  // namespace fst
 
index f51677d..94c8676 100644 (file)
@@ -125,47 +125,28 @@ extern const char rho_fst_type[];
 extern const char input_rho_fst_type[];
 extern const char output_rho_fst_type[];
 
-using StdRhoFst =
-    MatcherFst<ConstFst<StdArc>, RhoFstMatcher<SortedMatcher<ConstFst<StdArc>>>,
+template <class Arc>
+using RhoFst =
+    MatcherFst<ConstFst<Arc>, RhoFstMatcher<SortedMatcher<ConstFst<Arc>>>,
                rho_fst_type>;
 
-using LogRhoFst =
-    MatcherFst<ConstFst<LogArc>, RhoFstMatcher<SortedMatcher<ConstFst<LogArc>>>,
-               rho_fst_type>;
-
-using Log64RhoFst = MatcherFst<ConstFst<Log64Arc>,
-                               RhoFstMatcher<SortedMatcher<ConstFst<Log64Arc>>>,
-                               input_rho_fst_type>;
-
-using StdInputRhoFst =
-    MatcherFst<ConstFst<StdArc>, RhoFstMatcher<SortedMatcher<ConstFst<StdArc>>,
-                                               kRhoFstMatchInput>,
-               input_rho_fst_type>;
+using StdRhoFst = RhoFst<StdArc>;
 
-using LogInputRhoFst =
-    MatcherFst<ConstFst<LogArc>, RhoFstMatcher<SortedMatcher<ConstFst<LogArc>>,
-                                               kRhoFstMatchInput>,
+template <class Arc>
+using InputRhoFst =
+    MatcherFst<ConstFst<Arc>,
+               RhoFstMatcher<SortedMatcher<ConstFst<Arc>>, kRhoFstMatchInput>,
                input_rho_fst_type>;
 
-using Log64InputRhoFst = MatcherFst<
-    ConstFst<Log64Arc>,
-    RhoFstMatcher<SortedMatcher<ConstFst<Log64Arc>>, kRhoFstMatchInput>,
-    input_rho_fst_type>;
-
-using StdOutputRhoFst =
-    MatcherFst<ConstFst<StdArc>, RhoFstMatcher<SortedMatcher<ConstFst<StdArc>>,
-                                               kRhoFstMatchOutput>,
-               output_rho_fst_type>;
+using StdInputRhoFst = InputRhoFst<StdArc>;
 
-using LogOutputRhoFst =
-    MatcherFst<ConstFst<LogArc>, RhoFstMatcher<SortedMatcher<ConstFst<LogArc>>,
-                                               kRhoFstMatchOutput>,
+template <class Arc>
+using OutputRhoFst =
+    MatcherFst<ConstFst<Arc>,
+               RhoFstMatcher<SortedMatcher<ConstFst<Arc>>, kRhoFstMatchOutput>,
                output_rho_fst_type>;
 
-using Log64OutputRhoFst = MatcherFst<
-    ConstFst<Log64Arc>,
-    RhoFstMatcher<SortedMatcher<ConstFst<Log64Arc>>, kRhoFstMatchOutput>,
-    output_rho_fst_type>;
+using StdOutputRhoFst = OutputRhoFst<StdArc>;
 
 }  // namespace fst
 
index 9e870ef..7ca51dd 100644 (file)
@@ -128,48 +128,28 @@ extern const char sigma_fst_type[];
 extern const char input_sigma_fst_type[];
 extern const char output_sigma_fst_type[];
 
-using StdSigmaFst = MatcherFst<ConstFst<StdArc>,
-                               SigmaFstMatcher<SortedMatcher<ConstFst<StdArc>>>,
-                               sigma_fst_type>;
-
-using LogSigmaFst = MatcherFst<ConstFst<LogArc>,
-                               SigmaFstMatcher<SortedMatcher<ConstFst<LogArc>>>,
-                               sigma_fst_type>;
-
-using Log64SigmaFst =
-    MatcherFst<ConstFst<Log64Arc>,
-               SigmaFstMatcher<SortedMatcher<ConstFst<Log64Arc>>>,
-               input_sigma_fst_type>;
-
-using StdInputSigmaFst = MatcherFst<
-    ConstFst<StdArc>,
-    SigmaFstMatcher<SortedMatcher<ConstFst<StdArc>>, kSigmaFstMatchInput>,
-    input_sigma_fst_type>;
+template <class Arc>
+using SigmaFst =
+    MatcherFst<ConstFst<Arc>, SigmaFstMatcher<SortedMatcher<ConstFst<Arc>>>,
+               sigma_fst_type>;
 
-using LogInputSigmaFst = MatcherFst<
-    ConstFst<LogArc>,
-    SigmaFstMatcher<SortedMatcher<ConstFst<LogArc>>, kSigmaFstMatchInput>,
-    input_sigma_fst_type>;
+using StdSigmaFst = SigmaFst<StdArc>;
 
-using Log64InputSigmaFst = MatcherFst<
-    ConstFst<Log64Arc>,
-    SigmaFstMatcher<SortedMatcher<ConstFst<Log64Arc>>, kSigmaFstMatchInput>,
+template <class Arc>
+using InputSigmaFst = MatcherFst<
+    ConstFst<Arc>,
+    SigmaFstMatcher<SortedMatcher<ConstFst<Arc>>, kSigmaFstMatchInput>,
     input_sigma_fst_type>;
 
-using StdOutputSigmaFst = MatcherFst<
-    ConstFst<StdArc>,
-    SigmaFstMatcher<SortedMatcher<ConstFst<StdArc>>, kSigmaFstMatchOutput>,
-    output_sigma_fst_type>;
+using StdInputSigmaFst = InputSigmaFst<StdArc>;
 
-using LogOutputSigmaFst = MatcherFst<
-    ConstFst<LogArc>,
-    SigmaFstMatcher<SortedMatcher<ConstFst<LogArc>>, kSigmaFstMatchOutput>,
+template <class Arc>
+using OutputSigmaFst = MatcherFst<
+    ConstFst<Arc>,
+    SigmaFstMatcher<SortedMatcher<ConstFst<Arc>>, kSigmaFstMatchOutput>,
     output_sigma_fst_type>;
 
-using Log64OutputSigmaFst = MatcherFst<
-    ConstFst<Log64Arc>,
-    SigmaFstMatcher<SortedMatcher<ConstFst<Log64Arc>>, kSigmaFstMatchOutput>,
-    output_sigma_fst_type>;
+using StdOutputSigmaFst = OutputSigmaFst<StdArc>;
 
 }  // namespace fst
 
index 0a854d3..655194a 100644 (file)
 
 namespace fst {
 
-constexpr uint32 kFactorFinalWeights = 0x00000001;
-constexpr uint32 kFactorArcWeights = 0x00000002;
+constexpr uint8 kFactorFinalWeights = 0x01;
+constexpr uint8 kFactorArcWeights = 0x02;
 
 template <class Arc>
 struct FactorWeightOptions : CacheOptions {
   using Label = typename Arc::Label;
 
   float delta;
-  uint32 mode;         // Factor arc weights and/or final weights.
+  uint8 mode;          // Factor arc weights and/or final weights.
   Label final_ilabel;  // Input label of arc when factoring final weights.
   Label final_olabel;  // Output label of arc when factoring final weights.
   bool increment_final_ilabel;  // When factoring final w' results in > 1 arcs
   bool increment_final_olabel;  // at state, increment labels to make distinct?
 
   explicit FactorWeightOptions(const CacheOptions &opts, float delta = kDelta,
-                               uint32 mode = kFactorArcWeights |
-                                             kFactorFinalWeights,
+                               uint8 mode = kFactorArcWeights |
+                                            kFactorFinalWeights,
                                Label final_ilabel = 0, Label final_olabel = 0,
                                bool increment_final_ilabel = false,
                                bool increment_final_olabel = false)
@@ -49,8 +49,8 @@ struct FactorWeightOptions : CacheOptions {
         increment_final_olabel(increment_final_olabel) {}
 
   explicit FactorWeightOptions(float delta = kDelta,
-                               uint32 mode = kFactorArcWeights |
-                                             kFactorFinalWeights,
+                               uint8 mode = kFactorArcWeights |
+                                            kFactorFinalWeights,
                                Label final_ilabel = 0, Label final_olabel = 0,
                                bool increment_final_ilabel = false,
                                bool increment_final_olabel = false)
@@ -414,13 +414,13 @@ class FactorWeightFstImpl : public CacheImpl<Arc> {
 
   std::unique_ptr<const Fst<Arc>> fst_;
   float delta_;
-  uint32 mode_;         // Factoring arc and/or final weights.
+  uint8 mode_;          // Factoring arc and/or final weights.
   Label final_ilabel_;  // ilabel of arc created when factoring final weights.
   Label final_olabel_;  // olabel of arc created when factoring final weights.
   bool increment_final_ilabel_;    // When factoring final weights results in
   bool increment_final_olabel_;    // mutiple arcs, increment labels?
-  std::vector<Element> elements_;  // mapping from FST state to Element.
-  ElementMap element_map_;         // mapping from Element to FST state.
+  std::vector<Element> elements_;  // Mapping from FST state to Element.
+  ElementMap element_map_;         // Mapping from Element to FST state.
   // Mapping between old/new StateId for states that do not need to be factored
   // when mode_ is 0 or kFactorFinalWeights.
   std::vector<StateId> unfactored_;
index 2f2acd5..0400626 100644 (file)
@@ -59,13 +59,26 @@ class DefaultCompactStore;
 template <class Arc>
 class DefaultCacheStore;
 
+// Compactors.
+
+template <class AC, class U,
+          class S = DefaultCompactStore<typename AC::Element, U>>
+class DefaultCompactor;
+
 // FST templates.
 
-template <class Arc, class Compactor, class U = uint32,
-    class CompactStore = DefaultCompactStore<typename Compactor::Element, U>,
-    class CacheStore = DefaultCacheStore<Arc>>
+template <class Arc, class Compactor, class CacheStore = DefaultCacheStore<Arc>>
 class CompactFst;
 
+// The Unsigned type is used to represent indices into the compact arc array.
+template <class Arc, class ArcCompactor, class Unsigned = uint32,
+          class CompactStore =
+              DefaultCompactStore<typename ArcCompactor::Element, Unsigned>,
+          class CacheStore = DefaultCacheStore<Arc>>
+using CompactArcFst =
+    CompactFst<Arc, DefaultCompactor<ArcCompactor, Unsigned, CompactStore>,
+               CacheStore>;
+
 template <class Arc, class U = uint32>
 class ConstFst;
 
@@ -143,7 +156,7 @@ class UnionFst;
 template <class T, class Compare>
 class Heap;
 
-// Compactors.
+// ArcCompactors.
 
 template <class Arc>
 class AcceptorCompactor;
@@ -160,24 +173,24 @@ class UnweightedCompactor;
 template <class Arc>
 class WeightedStringCompactor;
 
-// Compact FSTs.
+// Compact Arc FSTs.
 
 template <class Arc, class U = uint32>
-using CompactStringFst = CompactFst<Arc, StringCompactor<Arc>, U>;
+using CompactStringFst = CompactArcFst<Arc, StringCompactor<Arc>, U>;
 
 template <class Arc, class U = uint32>
 using CompactWeightedStringFst =
-    CompactFst<Arc, WeightedStringCompactor<Arc>, U>;
+    CompactArcFst<Arc, WeightedStringCompactor<Arc>, U>;
 
 template <class Arc, class U = uint32>
-using CompactAcceptorFst = CompactFst<Arc, AcceptorCompactor<Arc>, U>;
+using CompactAcceptorFst = CompactArcFst<Arc, AcceptorCompactor<Arc>, U>;
 
 template <class Arc, class U = uint32>
-using CompactUnweightedFst = CompactFst<Arc, UnweightedCompactor<Arc>, U>;
+using CompactUnweightedFst = CompactArcFst<Arc, UnweightedCompactor<Arc>, U>;
 
 template <class Arc, class U = uint32>
 using CompactUnweightedAcceptorFst =
-    CompactFst<Arc, UnweightedAcceptorCompactor<Arc>, U>;
+    CompactArcFst<Arc, UnweightedAcceptorCompactor<Arc>, U>;
 
 // StdArc aliases for FSTs.
 
index d9fb408..029be58 100644 (file)
@@ -249,17 +249,17 @@ class Fst {
     return reader(strm, ropts);
   }
 
-  // Reads an FST from a file; returns nullptr on error. An empty filename
+  // Reads an FST from a file; returns nullptr on error. An empty source
   // results in reading from standard input.
-  static Fst<Arc> *Read(const std::string &filename) {
-    if (!filename.empty()) {
-      std::ifstream strm(filename,
+  static Fst<Arc> *Read(const std::string &source) {
+    if (!source.empty()) {
+      std::ifstream strm(source,
                               std::ios_base::in | std::ios_base::binary);
       if (!strm) {
-        LOG(ERROR) << "Fst::Read: Can't open file: " << filename;
+        LOG(ERROR) << "Fst::Read: Can't open file: " << source;
         return nullptr;
       }
-      return Read(strm, FstReadOptions(filename));
+      return Read(strm, FstReadOptions(source));
     } else {
       return Read(std::cin, FstReadOptions("standard input"));
     }
@@ -272,14 +272,20 @@ class Fst {
     return false;
   }
 
-  // Writes an FST to a file; returns false on error; an empty filename
+  // Writes an FST to a file; returns false on error; an empty source
   // results in writing to standard output.
-  virtual bool Write(const std::string &filename) const {
-    LOG(ERROR) << "Fst::Write: No write filename method for " << Type()
+  virtual bool Write(const std::string &source) const {
+    LOG(ERROR) << "Fst::Write: No write source method for " << Type()
                << " FST type";
     return false;
   }
 
+  // Some Fst implementations support
+  //   template <class Fst2>
+  //   static bool Fst1::WriteFst(const Fst2 &fst2, ...);
+  // which is equivalent to Fst1(fst2).Write(...), but uses less memory.
+  // WriteFst is not part of the general Fst interface.
+
   // Returns input label symbol table; return nullptr if not specified.
   virtual const SymbolTable *InputSymbols() const = 0;
 
@@ -299,16 +305,16 @@ class Fst {
   virtual MatcherBase<Arc> *InitMatcher(MatchType match_type) const;
 
  protected:
-  bool WriteFile(const std::string &filename) const {
-    if (!filename.empty()) {
-      std::ofstream strm(filename,
+  bool WriteFile(const std::string &source) const {
+    if (!source.empty()) {
+      std::ofstream strm(source,
                                std::ios_base::out | std::ios_base::binary);
       if (!strm) {
-        LOG(ERROR) << "Fst::WriteFile: Can't open file: " << filename;
+        LOG(ERROR) << "Fst::WriteFile: Can't open file: " << source;
         return false;
       }
-      if (!Write(strm, FstWriteOptions(filename))) {
-        LOG(ERROR) << "Fst::WriteFile: Write failed: " << filename;
+      if (!Write(strm, FstWriteOptions(source))) {
+        LOG(ERROR) << "Fst::WriteFile: Write failed: " << source;
         return false;
       }
       return true;
@@ -409,18 +415,19 @@ class StateIterator {
 };
 
 // Flags to control the behavior on an arc iterator.
-static constexpr uint32 kArcILabelValue =
-    0x0001;  // Value() gives valid ilabel.
-static constexpr uint32 kArcOLabelValue = 0x0002;  //  "       "     " olabel.
-static constexpr uint32 kArcWeightValue = 0x0004;  //  "       "     " weight.
-static constexpr uint32 kArcNextStateValue =
-    0x0008;                                    //  "       "     " nextstate.
-static constexpr uint32 kArcNoCache = 0x0010;  // No need to cache arcs.
-
-static constexpr uint32 kArcValueFlags =
+// Value() gives valid ilabel.
+static constexpr uint8 kArcILabelValue = 0x01;
+// Value() call gives valid olabel.
+static constexpr uint8 kArcOLabelValue = 0x02;
+// Value() call gives valid weight.
+static constexpr uint8 kArcWeightValue = 0x04;
+// Value() call gives valid nextstate.
+static constexpr uint8 kArcNextStateValue = 0x08;
+// Arcs need not be cached.
+static constexpr uint8 kArcNoCache = 0x10;
+static constexpr uint8 kArcValueFlags =
     kArcILabelValue | kArcOLabelValue | kArcWeightValue | kArcNextStateValue;
-
-static constexpr uint32 kArcFlags = kArcValueFlags | kArcNoCache;
+static constexpr uint8 kArcFlags = kArcValueFlags | kArcNoCache;
 
 // Arc iterator interface, templated on the arc definition; used for arc
 // iterator specializations that are returned by the InitArcIterator FST method.
@@ -443,10 +450,10 @@ class ArcIteratorBase {
   virtual void Reset() = 0;
   // Advances to arbitrary arc by position.
   virtual void Seek(size_t) = 0;
-  // Returns current behavorial flags
-  virtual uint32 Flags() const = 0;
+  // Returns current behavorial flags.
+  virtual uint8 Flags() const = 0;
   // Sets behavorial flags.
-  virtual void SetFlags(uint32, uint32) = 0;
+  virtual void SetFlags(uint8, uint8) = 0;
 };
 
 // ArcIterator initialization data.
@@ -531,15 +538,11 @@ class ArcIterator {
 
   size_t Position() const { return data_.base ? data_.base->Position() : i_; }
 
-  uint32 Flags() const {
-    if (data_.base) {
-      return data_.base->Flags();
-    } else {
-      return kArcValueFlags;
-    }
+  uint8 Flags() const {
+    return data_.base ? data_.base->Flags() : kArcValueFlags;
   }
 
-  void SetFlags(uint32 flags, uint32 mask) {
+  void SetFlags(uint8 flags, uint8 mask) {
     if (data_.base) data_.base->SetFlags(flags, mask);
   }
 
@@ -824,17 +827,21 @@ bool FstImpl<Arc>::ReadHeader(std::istream &strm, const FstReadOptions &opts,
           << ", flags: " << hdr->GetFlags();
   if (hdr->FstType() != type_) {
     LOG(ERROR) << "FstImpl::ReadHeader: FST not of type " << type_
+               << ", found " << hdr->FstType()
                << ": " << opts.source;
     return false;
   }
   if (hdr->ArcType() != Arc::Type()) {
     LOG(ERROR) << "FstImpl::ReadHeader: Arc not of type " << Arc::Type()
+               << ", found " << hdr->ArcType()
                << ": " << opts.source;
     return false;
   }
   if (hdr->Version() < min_version) {
     LOG(ERROR) << "FstImpl::ReadHeader: Obsolete " << type_
-               << " FST version: " << opts.source;
+               << " FST version " << hdr->Version()
+               << ", min_version=" << min_version
+               << ": " << opts.source;
     return false;
   }
   properties_ = hdr->Properties();
@@ -864,6 +871,7 @@ uint64 TestProperties(const Fst<Arc> &fst, uint64 mask, uint64 *known);
 
 // This is a helper class template useful for attaching an FST interface to
 // its implementation, handling reference counting.
+// Impl's copy constructor must produce a thread-safe copy.
 template <class Impl, class FST = Fst<typename Impl::Arc>>
 class ImplToFst : public FST {
  public:
@@ -909,7 +917,7 @@ class ImplToFst : public FST {
   explicit ImplToFst(std::shared_ptr<Impl> impl) : impl_(std::move(impl)) {}
 
   // This constructor presumes there is a copy constructor for the
-  // implementation.
+  // implementation that produces a thread-safe copy.
   ImplToFst(const ImplToFst<Impl, FST> &fst, bool safe) {
     if (safe) {
       impl_ = std::make_shared<Impl>(*(fst.impl_));
index 0942ea0..3677c85 100644 (file)
@@ -7,6 +7,7 @@
 #define FST_INTERVAL_SET_H_
 
 #include <algorithm>
+#include <initializer_list>
 #include <iostream>
 #include <vector>
 
@@ -65,6 +66,8 @@ class VectorIntervalStore {
   using Iterator = typename std::vector<Interval>::const_iterator;
 
   VectorIntervalStore() : count_(-1) {}
+  VectorIntervalStore(std::initializer_list<Interval> intervals_init)
+      : intervals_(intervals_init), count_(-1) {}
 
   std::vector<Interval> *MutableIntervals() { return &intervals_; }
 
@@ -107,6 +110,9 @@ class IntervalSet {
  public:
   using Interval = IntInterval<T>;
 
+  IntervalSet(std::initializer_list<Interval> intervals_init)
+      : intervals_(intervals_init) {}
+
   template <class... A>
   explicit IntervalSet(A... args) : intervals_(args...) {}
 
index b52e7b8..d409074 100644 (file)
@@ -93,12 +93,45 @@ class LabelReachableData {
   std::vector<LabelIntervalSet> interval_sets_;   // Interval sets per state.
 };
 
+// Apply a new state order to a vector of LabelIntervalSets. order[i] gives
+// the StateId after sorting that corresponds to the StateId i before
+// sorting; it must therefore be a permutation of the input FST's StateId
+// sequence.
+template <typename Label, typename StateId>
+bool StateSort(std::vector<IntervalSet<Label>> *interval_sets,
+               const std::vector<StateId> &order) {
+  if (order.size() != interval_sets->size()) {
+    FSTERROR() << "StateSort: Bad order vector size: " << order.size()
+               << ", expected: " << interval_sets->size();
+    return false;
+  }
+  std::vector<IntervalSet<Label>> reordered_interval_sets(
+      interval_sets->size());
+  // TODO(jrosenstock): Use storage-efficient cycle-following algorithm
+  // from StateSort(MutableFst *, order).
+  for (StateId s = 0; s < order.size(); ++s) {
+    reordered_interval_sets[order[s]] = std::move((*interval_sets)[s]);
+  }
+  *interval_sets = std::move(reordered_interval_sets);
+  return true;
+}
+
+// Apply a new state order to LabelReachableData.
+template <typename Label, typename StateId>
+bool StateSort(LabelReachableData<Label> *data,
+               const std::vector<StateId> &order) {
+  return StateSort(data->MutableIntervalSets(), order);
+}
+
 // Tests reachability of labels from a given state. If reach_input is true, then
 // input labels are considered, o.w. output labels are considered. To test for
 // reachability from a state s, first do SetState(s), then a label l can be
 // reached from state s of FST f iff Reach(r) is true where r = Relabel(l). The
-// relabeling is required to ensure a compact representation of the reachable
-// labels.
+// relabeling is required to ensure the consecutive ones property (C1P); this
+// allows a compact representation of the reachable labels. See Section 2.3.3 of
+// "A Generalized Composition Algorithm for Weighted Finite-State Transducers",
+// Cyril Allauzen, Michael Riley, Johan Schalkwyk, Interspeech 2009.
+// https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/35539.pdf
 
 // The whole FST can be relabeled instead with Relabel(&f, reach_input) so that
 // the test Reach(r) applies directly to the labels of the transformed FST f.
@@ -178,9 +211,14 @@ class LabelReachable {
   // Relabels w.r.t labels that give compact label sets.
   Label Relabel(Label label) {
     if (label == 0 || error_) return label;
-    auto &label2index = *data_->Label2Index();
-    auto &relabel = label2index[label];
-    if (!relabel) relabel = label2index.size() + 1;  // Adds new label.
+    const auto &label2index = *data_->Label2Index();
+    auto iter = label2index.find(label);
+    if (iter != label2index.end()) return iter->second;
+    auto &relabel = oov_label2index_[label];
+    if (!relabel) {
+      // Adds new label.
+      relabel = label2index.size() + oov_label2index_.size() + 1;
+    }
     return relabel;
   }
 
@@ -216,17 +254,22 @@ class LabelReachable {
     pairs->clear();
     const auto &label2index = *data_->Label2Index();
     // Maps labels to their new values in [1, label2index().size()].
-    for (auto it = label2index.begin(); it != label2index.end(); ++it) {
-      if (it->second != data_->FinalLabel()) {
-        pairs->emplace_back(it->first, it->second);
+    for (const auto &kv : label2index) {
+      if (kv.second != data_->FinalLabel()) {
+        pairs->emplace_back(kv);
       }
     }
+    // Maps oov labels to their values > label2index().size().
+    pairs->insert(pairs->end(), oov_label2index_.begin(),
+                  oov_label2index_.end());
     if (avoid_collisions) {
       // Ensures any label in [1, label2index().size()] is mapped either
-      // by the above step or to label2index() + 1 (to avoid collisions).
+      // by the above steps or to label2index() + 1 (to avoid collisions).
       for (size_t i = 1; i <= label2index.size(); ++i) {
         const auto it = label2index.find(i);
-        if (it == label2index.end() || it->second == data_->FinalLabel()) {
+        bool unmapped = it == label2index.end();
+        if (unmapped) unmapped = oov_label2index_.count(i) == 0;
+        if (unmapped || it->second == data_->FinalLabel()) {
           pairs->emplace_back(i, label2index.size() + 1);
         }
       }
@@ -498,6 +541,8 @@ class LabelReachable {
   std::shared_ptr<Data> data_;
   // Sums arc weights.
   std::unique_ptr<Accumulator> accumulator_;
+  // Relabeling map for OOV labels.
+  std::unordered_map<Label, Label> oov_label2index_;
   double ncalls_;
   double nintervals_;
   bool reach_fst_input_;
index df3fc6c..657fe9a 100644 (file)
@@ -308,7 +308,7 @@ class PushWeightsComposeFilter {
     if (!(LookAheadFlags() & kLookAheadWeight)) {
       return FilterState(fs1, FilterState2(Weight::One()));
     }
-    const auto &lweight = filter_.LookAheadArc()
+    const auto &lweight = LookAheadArc()
                               ? Selector().GetMatcher()->LookAheadWeight()
                               : Weight::One();
     const auto &fs2 = fs_.GetState2();
@@ -438,7 +438,7 @@ class PushLabelsComposeFilter {
     }
     const auto &fs1 = filter_.FilterArc(arc1, arc2);
     if (fs1 == FilterState1::NoState()) return FilterState::NoState();
-    if (!filter_.LookAheadArc())
+    if (!LookAheadArc())
       return FilterState(fs1, FilterState2(kNoLabel));
     return LookAheadOutput() ? PushLabelFilterArc(arc1, arc2, fs1)
                              : PushLabelFilterArc(arc2, arc1, fs1);
index c529fef..34c8429 100644 (file)
@@ -530,7 +530,7 @@ class LabelLookAheadMatcher
 
   const MatcherData *GetData() const {
     return label_reachable_ ? label_reachable_->GetData() : nullptr;
-  };
+  }
 
   std::shared_ptr<MatcherData> GetSharedData() const {
     return label_reachable_ ? label_reachable_->GetSharedData()
index a8b63c1..e7281ed 100644 (file)
@@ -112,10 +112,10 @@ class MatcherFst : public ImplToExpandedFst<internal::AddOnImpl<F, Data>> {
   }
 
   // Read a MatcherFst from a file; return nullptr on error
-  // Empty filename reads from standard input
+  // Empty source reads from standard input
   static MatcherFst<FST, FstMatcher, Name, Init, Data> *Read(
-      const std::string &filename) {
-    auto *impl = ImplToExpandedFst<Impl>::Read(filename);
+      const std::string &source) {
+    auto *impl = ImplToExpandedFst<Impl>::Read(source);
     return impl ? new MatcherFst<FST, FstMatcher, Name, Init, Data>(
                       std::shared_ptr<Impl>(impl))
                 : nullptr;
@@ -125,8 +125,8 @@ class MatcherFst : public ImplToExpandedFst<internal::AddOnImpl<F, Data>> {
     return GetImpl()->Write(strm, opts);
   }
 
-  bool Write(const std::string &filename) const override {
-    return Fst<Arc>::WriteFile(filename);
+  bool Write(const std::string &source) const override {
+    return Fst<Arc>::WriteFile(source);
   }
 
   void InitStateIterator(StateIteratorData<Arc> *data) const override {
index d9528d6..465de19 100644 (file)
@@ -51,14 +51,15 @@ namespace fst {
 //
 //   // If safe = true, the copy is thread-safe. See Fst<>::Copy() for
 //   // further doc.
-//   Matcher<FST> *Copy(bool safe = false) const override;
+//   Matcher *Copy(bool safe = false) const override;
 //
 //   // Returns the match type that can be provided (depending on compatibility
-//   of the input FST). It is either the requested match type, MATCH_NONE, or
-//   MATCH_UNKNOWN. If test is false, a costly testing is avoided, but
-//   MATCH_UNKNOWN may be returned. If test is true, a definite answer is
-//   returned, but may involve more costly computation (e.g., visiting the FST).
-//   MatchType Type(bool test) const override;
+//   // of the input FST). It is either the requested match type, MATCH_NONE,
+//   // or MATCH_UNKNOWN. If test is false, a costly testing is avoided, but
+//   // MATCH_UNKNOWN may be returned. If test is true, a definite answer is
+//   // returned, but may involve more costly computation (e.g., visiting
+//   // the FST).
+//   // MatchType Type(bool test) const override;
 //
 //   // Specifies the current state.
 //   void SetState(StateId s) final;
@@ -69,7 +70,7 @@ namespace fst {
 //   bool Find(Label label) final;
 //
 //   // Iterator methods. Note that initially and after SetState() these have
-//   undefined behavior until Find() is called.
+//   // undefined behavior until Find() is called.
 //
 //   bool Done() const final;
 //
@@ -123,7 +124,7 @@ class MatcherBase {
 
   // Virtual interface.
 
-  virtual MatcherBase<Arc> *Copy(bool safe = false) const = 0;
+  virtual MatcherBase *Copy(bool safe = false) const = 0;
   virtual MatchType Type(bool) const = 0;
   virtual void SetState(StateId) = 0;
   virtual bool Find(Label) = 0;
@@ -196,7 +197,7 @@ class SortedMatcher : public MatcherBase<typename F::Arc> {
   }
 
   // This makes a copy of the FST.
-  SortedMatcher(const SortedMatcher<FST> &matcher, bool safe = false)
+  SortedMatcher(const SortedMatcher &matcher, bool safe = false)
       : owned_fst_(matcher.fst_.Copy(safe)),
         fst_(*owned_fst_),
         state_(kNoStateId),
@@ -211,8 +212,8 @@ class SortedMatcher : public MatcherBase<typename F::Arc> {
 
   ~SortedMatcher() override { Destroy(aiter_, &aiter_pool_); }
 
-  SortedMatcher<FST> *Copy(bool safe = false) const override {
-    return new SortedMatcher<FST>(*this, safe);
+  SortedMatcher *Copy(bool safe = false) const override {
+    return new SortedMatcher(*this, safe);
   }
 
   MatchType Type(bool test) const override {
@@ -444,7 +445,7 @@ class HashMatcher : public MatcherBase<typename F::Arc> {
   }
 
   // This makes a copy of the FST.
-  HashMatcher(const HashMatcher<FST> &matcher, bool safe = false)
+  HashMatcher(const HashMatcher &matcher, bool safe = false)
       : owned_fst_(matcher.fst_.Copy(safe)),
         fst_(*owned_fst_),
         state_(kNoStateId),
@@ -454,8 +455,8 @@ class HashMatcher : public MatcherBase<typename F::Arc> {
         state_table_(
             safe ? std::make_shared<StateTable>() : matcher.state_table_) {}
 
-  HashMatcher<FST> *Copy(bool safe = false) const override {
-    return new HashMatcher<FST>(*this, safe);
+  HashMatcher *Copy(bool safe = false) const override {
+    return new HashMatcher(*this, safe);
   }
 
   // The argument is ignored as there are no relevant properties to test.
@@ -1530,15 +1531,15 @@ class Matcher {
   }
 
   // This makes a copy of the FST.
-  Matcher(const Matcher<FST> &matcher, bool safe = false)
+  Matcher(const Matcher &matcher, bool safe = false)
       : base_(matcher.base_->Copy(safe)) { }
 
   // Takes ownership of the provided matcher.
   explicit Matcher(MatcherBase<Arc> *base_matcher)
       : base_(base_matcher) { }
 
-  Matcher<FST> *Copy(bool safe = false) const {
-    return new Matcher<FST>(*this, safe);
+  Matcher *Copy(bool safe = false) const {
+    return new Matcher(*this, safe);
   }
 
   MatchType Type(bool test) const { return base_->Type(test); }
index 3ec7817..5af7cff 100644 (file)
@@ -129,26 +129,25 @@ class MutableFst : public ExpandedFst<A> {
   }
 
   // Reads a MutableFst from a file; returns nullptr on error. An empty
-  // filename results in reading from standard input. If convert is true,
+  // source results in reading from standard input. If convert is true,
   // convert to a mutable FST subclass (given by convert_type) in the case
   // that the input FST is non-mutable.
-  static MutableFst<Arc> *Read(const std::string &filename,
-                               bool convert = false,
+  static MutableFst<Arc> *Read(const std::string &source, bool convert = false,
                                const std::string &convert_type = "vector") {
     if (convert == false) {
-      if (!filename.empty()) {
-        std::ifstream strm(filename,
+      if (!source.empty()) {
+        std::ifstream strm(source,
                                 std::ios_base::in | std::ios_base::binary);
         if (!strm) {
-          LOG(ERROR) << "MutableFst::Read: Can't open file: " << filename;
+          LOG(ERROR) << "MutableFst::Read: Can't open file: " << source;
           return nullptr;
         }
-        return Read(strm, FstReadOptions(filename));
+        return Read(strm, FstReadOptions(source));
       } else {
         return Read(std::cin, FstReadOptions("standard input"));
       }
     } else {  // Converts to 'convert_type' if not mutable.
-      std::unique_ptr<Fst<Arc>> ifst(Fst<Arc>::Read(filename));
+      std::unique_ptr<Fst<Arc>> ifst(Fst<Arc>::Read(source));
       if (!ifst) return nullptr;
       if (ifst->Properties(kMutable, false)) {
         return static_cast<MutableFst<Arc> *>(ifst.release());
@@ -226,9 +225,9 @@ class MutableArcIterator {
 
   void SetValue(const Arc &arc) { data_.base->SetValue(arc); }
 
-  uint32 Flags() const { return data_.base->Flags(); }
+  uint8 Flags() const { return data_.base->Flags(); }
 
-  void SetFlags(uint32 flags, uint32 mask) {
+  void SetFlags(uint8 flags, uint8 mask) {
     return data_.base->SetFlags(flags, mask);
   }
 
index 1f77273..f9d6253 100644 (file)
@@ -64,17 +64,16 @@ void RemoveWeight(MutableFst<Arc> *fst, const typename Arc::Weight &weight,
   }
 }
 
-// Pushes the weights in FST in the direction defined by TYPE. If
-// pushing towards the initial state, the sum of the weight of the
-// outgoing transitions and final weight at a non-initial state is
-// equal to One() in the resulting machine. If pushing towards the
-// final state, the same property holds on the reverse machine.
+// Pushes the weights in FST in the direction defined by TYPE. If pushing
+// towards the initial state, the sum of the weight of the outgoing transitions
+// and final weight at a non-initial state is equal to One() in the resulting
+// machine. If pushing towards the final state, the same property holds on the
+// reverse machine.
 //
-// Weight needs to be left distributive when pushing towards the
-// initial state and right distributive when pushing towards the final
-// states.
+// Weight needs to be left distributive when pushing towards the initial state
+// and right distributive when pushing towards the final states.
 template <class Arc>
-void Push(MutableFst<Arc> *fst, ReweightType type, float delta = kDelta,
+void Push(MutableFst<Arc> *fst, ReweightType type, float delta = kShortestDelta,
           bool remove_total_weight = false) {
   using Weight = typename Arc::Weight;
   std::vector<Weight> distance;
@@ -90,20 +89,20 @@ void Push(MutableFst<Arc> *fst, ReweightType type, float delta = kDelta,
   }
 }
 
-constexpr uint32 kPushWeights = 0x0001;
-constexpr uint32 kPushLabels = 0x0002;
-constexpr uint32 kPushRemoveTotalWeight = 0x0004;
-constexpr uint32 kPushRemoveCommonAffix = 0x0008;
+constexpr uint8 kPushWeights = 0x01;
+constexpr uint8 kPushLabels = 0x02;
+constexpr uint8 kPushRemoveTotalWeight = 0x04;
+constexpr uint8 kPushRemoveCommonAffix = 0x08;
 
-// Pushes the weights and/or labels of the input FST into the output
-// mutable FST by pushing weights and/or labels (as determined by the
-// ptype argument) towards the initial state or final states (as
-// determined by the rtype template parameter). The weight type must
-// be left distributive when pushing weights towards the initial state, and
-// right distribution when pushing weights towards the final states.
+// Pushes the weights and/or labels of the input FST into the output mutable FST
+// by pushing weights and/or labels (as determined by the ptype argument)
+// towards the initial state or final states (as determined by the rtype
+// template parameter). The weight type must be left distributive when pushing
+// weights towards the initial state, and right distribution when pushing
+// weights towards the final states.
 template <class Arc, ReweightType rtype>
-void Push(const Fst<Arc> &ifst, MutableFst<Arc> *ofst, uint32 ptype,
-          float delta = kDelta) {
+void Push(const Fst<Arc> &ifst, MutableFst<Arc> *ofst, uint8 ptype,
+          float delta = kShortestDelta) {
   using Label = typename Arc::Label;
   using Weight = typename Arc::Weight;
   if ((ptype & (kPushWeights | kPushLabels)) == kPushWeights) {
index bbe1a44..449586a 100644 (file)
@@ -6,8 +6,9 @@
 #ifndef FST_QUEUE_H_
 #define FST_QUEUE_H_
 
-#include <deque>
 #include <memory>
+#include <queue>
+#include <stack>
 #include <type_traits>
 #include <utility>
 #include <vector>
@@ -138,20 +139,20 @@ class FifoQueue : public QueueBase<S> {
 
   virtual ~FifoQueue() = default;
 
-  StateId Head() const override { return queue_.back(); }
+  StateId Head() const override { return queue_.front(); }
 
-  void Enqueue(StateId s) override { queue_.push_front(s); }
+  void Enqueue(StateId s) override { queue_.push(s); }
 
-  void Dequeue() override { queue_.pop_back(); }
+  void Dequeue() override { queue_.pop(); }
 
   void Update(StateId) override {}
 
   bool Empty() const override { return queue_.empty(); }
 
-  void Clear() override { queue_.clear(); }
+  void Clear() override { queue_ = std::queue<StateId>(); }
 
  private:
-  std::deque<StateId> queue_;
+  std::queue<StateId> queue_;
 };
 
 // Last-in, first-out queue discipline.
@@ -164,20 +165,20 @@ class LifoQueue : public QueueBase<S> {
 
   virtual ~LifoQueue() = default;
 
-  StateId Head() const final { return queue_.front(); }
+  StateId Head() const final { return stack_.top(); }
 
-  void Enqueue(StateId s) final { queue_.push_front(s); }
+  void Enqueue(StateId s) final { stack_.push(s); }
 
-  void Dequeue() final { queue_.pop_front(); }
+  void Dequeue() final { stack_.pop(); }
 
   void Update(StateId) final {}
 
-  bool Empty() const final { return queue_.empty(); }
+  bool Empty() const final { return stack_.empty(); }
 
-  void Clear() final { queue_.clear(); }
+  void Clear() final { stack_ = std::stack<StateId>(); }
 
  private:
-  std::deque<StateId> queue_;
+  std::stack<StateId> stack_;
 };
 
 // Shortest-first queue discipline, templated on the StateId and as well as a
index 30c0e0d..87093df 100644 (file)
@@ -6,11 +6,13 @@
 #ifndef FST_RANDGEN_H_
 #define FST_RANDGEN_H_
 
+#include <algorithm>
 #include <cmath>
 #include <cstddef>
 #include <limits>
 #include <map>
 #include <memory>
+#include <numeric>
 #include <random>
 #include <utility>
 #include <vector>
@@ -28,6 +30,8 @@
 #include <fst/util.h>
 #include <fst/weight.h>
 
+#include <vector>
+
 namespace fst {
 
 // The RandGenFst class is roughly similar to ArcMapFst in that it takes two
@@ -256,19 +260,21 @@ class ArcSampler {
 template <class Result, class RNG>
 void OneMultinomialSample(const std::vector<double> &probs,
                           size_t num_to_sample, Result *result, RNG *rng) {
-  // Left-over probability mass.
-  double norm = 0;
-  for (double p : probs) norm += p;
+  using distribution = std::binomial_distribution<size_t>;
+  // Left-over probability mass.  Keep an array of the partial sums because
+  // keeping a scalar and modifying norm -= probs[i] in the loop will result
+  // in round-off error and can have probs[i] > norm.
+  std::vector<double> norm(probs.size());
+  std::partial_sum(probs.rbegin(), probs.rend(), norm.rbegin());
   // Left-over number of samples needed.
   for (size_t i = 0; i < probs.size(); ++i) {
-    size_t num_sampled = 0;
+    distribution::result_type num_sampled = 0;
     if (probs[i] > 0) {
-      std::binomial_distribution<> d(num_to_sample, probs[i] / norm);
+      distribution d(num_to_sample, probs[i] / norm[i]);
       num_sampled = d(*rng);
     }
     if (num_sampled != 0) (*result)[i] = num_sampled;
-    norm -= probs[i];
-    num_to_sample -= num_sampled;
+    num_to_sample -= std::min(num_sampled, num_to_sample);
   }
 }
 
index 8b6b18c..daf5322 100644 (file)
@@ -764,7 +764,7 @@ class ReplaceFstImpl
   // If acpp is null, only returns true if a final arcp is required, but does
   // not actually compute it.
   bool ComputeFinalArc(const StateTuple &tuple, Arc *arcp,
-                       uint32 flags = kArcValueFlags) {
+                       uint8 flags = kArcValueFlags) {
     const auto fst_state = tuple.fst_state;
     if (fst_state == kNoStateId) return false;
     // If state is final, pops the stack.
@@ -795,7 +795,7 @@ class ReplaceFstImpl
   // Returns false if the underlying arc corresponds to no arc in the resulting
   // FST.
   bool ComputeArc(const StateTuple &tuple, const Arc &arc, Arc *arcp,
-                  uint32 flags = kArcValueFlags) {
+                  uint8 flags = kArcValueFlags) {
     if (!EpsilonOnInput(call_label_type_) &&
         (flags == (flags & (kArcILabelValue | kArcWeightValue)))) {
       *arcp = arc;
@@ -849,8 +849,8 @@ class ReplaceFstImpl
   }
 
   // Returns the arc iterator flags supported by this FST.
-  uint32 ArcIteratorFlags() const {
-    uint32 flags = kArcValueFlags;
+  uint8 ArcIteratorFlags() const {
+    uint8 flags = kArcValueFlags;
     if (!always_cache_) flags |= kArcNoCache;
     return flags;
   }
@@ -1194,9 +1194,9 @@ class ArcIterator<ReplaceFst<Arc, StateTable, CacheStore>> {
 
   void Seek(size_t pos) { pos_ = pos; }
 
-  uint32 Flags() const { return flags_; }
+  uint8 Flags() const { return flags_; }
 
-  void SetFlags(uint32 flags, uint32 mask) {
+  void SetFlags(uint8 flags, uint8 mask) {
     // Updates the flags taking into account what flags are supported
     // by the FST.
     flags_ &= ~mask;
@@ -1220,16 +1220,16 @@ class ArcIterator<ReplaceFst<Arc, StateTable, CacheStore>> {
   ssize_t pos_;             // Current position.
   mutable ssize_t offset_;  // Offset between position in iterator and in arcs_.
   ssize_t num_arcs_;        // Number of arcs at state_.
-  uint32 flags_;            // Behavorial flags for the arc iterator
+  uint8 flags_;             // Behavorial flags for the arc iterator
   mutable Arc arc_;         // Memory to temporarily store computed arcs.
 
   mutable ArcIteratorData<Arc> cache_data_;  // Arc iterator data in cache.
   mutable ArcIteratorData<Arc> local_data_;  // Arc iterator data in local FST.
 
-  mutable const Arc *arcs_;     // Array of arcs.
-  mutable uint32 data_flags_;   // Arc value flags valid for data in arcs_.
-  mutable Arc final_arc_;       // Final arc (when required).
-  mutable uint32 final_flags_;  // Arc value flags valid for final_arc_.
+  mutable const Arc *arcs_;    // Array of arcs.
+  mutable uint8 data_flags_;   // Arc value flags valid for data in arcs_.
+  mutable Arc final_arc_;      // Final arc (when required).
+  mutable uint8 final_flags_;  // Arc value flags valid for final_arc_.
 
   ArcIterator(const ArcIterator &) = delete;
   ArcIterator &operator=(const ArcIterator &) = delete;
index e509eb2..4336d7a 100644 (file)
@@ -24,12 +24,12 @@ namespace script {
 class ArcIteratorImplBase {
  public:
   virtual bool Done() const = 0;
-  virtual uint32 Flags() const = 0;
+  virtual uint8 Flags() const = 0;
   virtual void Next() = 0;
   virtual size_t Position() const = 0;
   virtual void Reset() = 0;
   virtual void Seek(size_t a) = 0;
-  virtual void SetFlags(uint32 flags, uint32 mask) = 0;
+  virtual void SetFlags(uint8 flags, uint8 mask) = 0;
   virtual ArcClass Value() const = 0;
   virtual ~ArcIteratorImplBase() {}
 };
@@ -43,7 +43,7 @@ class ArcIteratorClassImpl : public ArcIteratorImplBase {
 
   bool Done() const final { return aiter_.Done(); }
 
-  uint32 Flags() const final { return aiter_.Flags(); }
+  uint8 Flags() const final { return aiter_.Flags(); }
 
   void Next() final { aiter_.Next(); }
 
@@ -53,9 +53,7 @@ class ArcIteratorClassImpl : public ArcIteratorImplBase {
 
   void Seek(size_t a) final { aiter_.Seek(a); }
 
-  void SetFlags(uint32 flags, uint32 mask) final {
-    aiter_.SetFlags(flags, mask);
-  }
+  void SetFlags(uint8 flags, uint8 mask) final { aiter_.SetFlags(flags, mask); }
 
   // This is returned by value because it has not yet been constructed, and
   // is likely to participate in return-value optimization.
@@ -83,7 +81,7 @@ class ArcIteratorClass {
 
   bool Done() const { return impl_->Done(); }
 
-  uint32 Flags() const { return impl_->Flags(); }
+  uint8 Flags() const { return impl_->Flags(); }
 
   void Next() { impl_->Next(); }
 
@@ -93,7 +91,7 @@ class ArcIteratorClass {
 
   void Seek(size_t a) { impl_->Seek(a); }
 
-  void SetFlags(uint32 flags, uint32 mask) { impl_->SetFlags(flags, mask); }
+  void SetFlags(uint8 flags, uint8 mask) { impl_->SetFlags(flags, mask); }
 
   ArcClass Value() const { return impl_->Value(); }
 
@@ -131,7 +129,7 @@ class MutableArcIteratorClassImpl
 
   bool Done() const final { return aiter_.Done(); }
 
-  uint32 Flags() const final { return aiter_.Flags(); }
+  uint8 Flags() const final { return aiter_.Flags(); }
 
   void Next() final { aiter_.Next(); }
 
@@ -141,9 +139,7 @@ class MutableArcIteratorClassImpl
 
   void Seek(size_t a) final { aiter_.Seek(a); }
 
-  void SetFlags(uint32 flags, uint32 mask) final {
-    aiter_.SetFlags(flags, mask);
-  }
+  void SetFlags(uint8 flags, uint8 mask) final { aiter_.SetFlags(flags, mask); }
 
   void SetValue(const Arc &arc) { aiter_.SetValue(arc); }
 
@@ -175,7 +171,7 @@ class MutableArcIteratorClass {
 
   bool Done() const { return impl_->Done(); }
 
-  uint32 Flags() const { return impl_->Flags(); }
+  uint8 Flags() const { return impl_->Flags(); }
 
   void Next() { impl_->Next(); }
 
@@ -185,7 +181,7 @@ class MutableArcIteratorClass {
 
   void Seek(size_t a) { impl_->Seek(a); }
 
-  void SetFlags(uint32 flags, uint32 mask) { impl_->SetFlags(flags, mask); }
+  void SetFlags(uint8 flags, uint8 mask) { impl_->SetFlags(flags, mask); }
 
   void SetValue(const ArcClass &ac) { impl_->SetValue(ac); }
 
index 05be3f7..f9dd0fe 100644 (file)
@@ -16,23 +16,40 @@ using ConcatArgs1 = std::pair<MutableFstClass *, const FstClass &>;
 
 template <class Arc>
 void Concat(ConcatArgs1 *args) {
-  MutableFst<Arc> *ofst = std::get<0>(*args)->GetMutableFst<Arc>();
-  const Fst<Arc> &ifst = *std::get<1>(*args).GetFst<Arc>();
-  Concat(ofst, ifst);
+  MutableFst<Arc> *fst1 = std::get<0>(*args)->GetMutableFst<Arc>();
+  const Fst<Arc> &fst2 = *std::get<1>(*args).GetFst<Arc>();
+  Concat(fst1, fst2);
 }
 
 using ConcatArgs2 = std::pair<const FstClass &, MutableFstClass *>;
 
 template <class Arc>
 void Concat(ConcatArgs2 *args) {
-  const Fst<Arc> &ifst = *std::get<0>(*args).GetFst<Arc>();
-  MutableFst<Arc> *ofst = std::get<1>(*args)->GetMutableFst<Arc>();
-  Concat(ifst, ofst);
+  const Fst<Arc> &fst1 = *std::get<0>(*args).GetFst<Arc>();
+  MutableFst<Arc> *fst2 = std::get<1>(*args)->GetMutableFst<Arc>();
+  Concat(fst1, fst2);
 }
 
-void Concat(MutableFstClass *ofst, const FstClass &ifst);
+using ConcatArgs3 =
+    std::pair<const std::vector<FstClass *> &, MutableFstClass *>;
 
-void Concat(const FstClass &ifst, MutableFstClass *ofst);
+template <class Arc>
+void Concat(ConcatArgs3 *args) {
+  const auto &untyped_fsts1 = std::get<0>(*args);
+  std::vector<const Fst<Arc> *> typed_fsts1;
+  typed_fsts1.reserve(untyped_fsts1.size());
+  for (const auto &untyped_fst1 : untyped_fsts1) {
+    typed_fsts1.emplace_back(untyped_fst1->GetFst<Arc>());
+  }
+  MutableFst<Arc> *fst2 = std::get<1>(*args)->GetMutableFst<Arc>();
+  Concat(typed_fsts1, fst2);
+}
+
+void Concat(MutableFstClass *fst1, const FstClass &fst2);
+
+void Concat(const FstClass &fst1, MutableFstClass *fst2);
+
+void Concat(const std::vector<FstClass *> &fsts1, MutableFstClass *fst2);
 
 }  // namespace script
 }  // namespace fst
index cde2904..81b9554 100644 (file)
@@ -4,8 +4,7 @@
 #ifndef FST_SCRIPT_DECODE_H_
 #define FST_SCRIPT_DECODE_H_
 
-#include <memory>
-#include <string>
+#include <tuple>
 #include <utility>
 
 #include <fst/encode.h>
 namespace fst {
 namespace script {
 
-using DecodeArgs1 = std::pair<MutableFstClass *, const std::string &>;
+using DecodeArgs = std::pair<MutableFstClass *, const EncodeMapperClass &>;
 
 template <class Arc>
-void Decode(DecodeArgs1 *args) {
+void Decode(DecodeArgs *args) {
   MutableFst<Arc> *fst = std::get<0>(*args)->GetMutableFst<Arc>();
-  std::unique_ptr<EncodeMapper<Arc>> decoder(
-      EncodeMapper<Arc>::Read(std::get<1>(*args), DECODE));
-  if (!decoder) {
-    fst->SetProperties(kError, kError);
-    return;
-  }
-  Decode(fst, *decoder);
+  const EncodeMapper<Arc> &mapper = *std::get<1>(*args).GetEncodeMapper<Arc>();
+  Decode(fst, mapper);
 }
 
-using DecodeArgs2 = std::pair<MutableFstClass *, const EncodeMapperClass &>;
-
-template <class Arc>
-void Decode(DecodeArgs2 *args) {
-  MutableFst<Arc> *fst = std::get<0>(*args)->GetMutableFst<Arc>();
-  const EncodeMapper<Arc> &encoder =
-      *(std::get<1>(*args).GetEncodeMapper<Arc>());
-  Decode(fst, encoder);
-}
-
-void Decode(MutableFstClass *fst, const std::string &coder_fname);
-
 void Decode(MutableFstClass *fst, const EncodeMapperClass &encoder);
 
 }  // namespace script
index ea9a752..7c039f9 100644 (file)
@@ -51,11 +51,11 @@ class FstDrawer {
         show_weight_one_(show_weight_one) {}
 
   // Draws FST to an output buffer.
-  void Draw(std::ostream *strm, const std::string &dest) {
-    ostrm_ = strm;
+  void Draw(std::ostream &strm, const std::string &dest) {
+    ostrm_ = &strm;
     SetStreamState(ostrm_);
     dest_ = dest;
-    StateId start = fst_.Start();
+    const auto start = fst_.Start();
     if (start == kNoStateId) return;
     PrintString("digraph FST {\n");
     if (vertical_) {
index 997c933..66f111a 100644 (file)
 namespace fst {
 namespace script {
 
-// Note: it is safe to pass these strings as references because
-// this struct is only used to pass them deeper in the call graph.
-// Be sure you understand why this is so before using this struct
-// for anything else!
-struct FstDrawerArgs {
+// Note: it is safe to pass these strings as references because this struct is
+// only used to pass them deeper in the call graph. Be sure you understand why
+// this is so before using this struct for anything else!
+struct DrawArgs {
   const FstClass &fst;
   const SymbolTable *isyms;
   const SymbolTable *osyms;
@@ -33,16 +32,15 @@ struct FstDrawerArgs {
   const int precision;
   const std::string &float_format;  // NOLINT
   const bool show_weight_one;
-  std::ostream *ostrm;
+  std::ostream &ostrm;
   const std::string &dest;
 
-  FstDrawerArgs(const FstClass &fst, const SymbolTable *isyms,
-                const SymbolTable *osyms, const SymbolTable *ssyms, bool accep,
-                const std::string &title, float width, float height,
-                bool portrait, bool vertical, float ranksep, float nodesep,
-                int fontsize, int precision, const std::string &float_format,
-                bool show_weight_one, std::ostream *ostrm,
-                const std::string &dest)
+  DrawArgs(const FstClass &fst, const SymbolTable *isyms,
+           const SymbolTable *osyms, const SymbolTable *ssyms, bool accep,
+           const std::string &title, float width, float height, bool portrait,
+           bool vertical, float ranksep, float nodesep, int fontsize,
+           int precision, const std::string &float_format, bool show_weight_one,
+           std::ostream &ostrm, const std::string &dest)
       : fst(fst),
         isyms(isyms),
         osyms(osyms),
@@ -64,7 +62,7 @@ struct FstDrawerArgs {
 };
 
 template <class Arc>
-void DrawFst(FstDrawerArgs *args) {
+void Draw(DrawArgs *args) {
   const Fst<Arc> &fst = *args->fst.GetFst<Arc>();
   FstDrawer<Arc> fstdrawer(fst, args->isyms, args->osyms, args->ssyms,
       args->accep, args->title, args->width, args->height, args->portrait,
@@ -73,13 +71,12 @@ void DrawFst(FstDrawerArgs *args) {
   fstdrawer.Draw(args->ostrm, args->dest);
 }
 
-void DrawFst(const FstClass &fst, const SymbolTable *isyms,
-             const SymbolTable *osyms, const SymbolTable *ssyms, bool accep,
-             const std::string &title, float width, float height, bool portrait,
-             bool vertical, float ranksep, float nodesep, int fontsize,
-             int precision, const std::string &float_format,
-             bool show_weight_one, std::ostream *ostrm,
-             const std::string &dest);
+void Draw(const FstClass &fst, const SymbolTable *isyms,
+          const SymbolTable *osyms, const SymbolTable *ssyms, bool accep,
+          const std::string &title, float width, float height, bool portrait,
+          bool vertical, float ranksep, float nodesep, int fontsize,
+          int precision, const std::string &float_format, bool show_weight_one,
+          std::ostream &ostrm, const std::string &dest);
 
 }  // namespace script
 }  // namespace fst
index 2c26e3b..0d79161 100644 (file)
@@ -4,8 +4,6 @@
 #ifndef FST_SCRIPT_ENCODE_H_
 #define FST_SCRIPT_ENCODE_H_
 
-#include <memory>
-#include <string>
 #include <tuple>
 #include <utility>
 
 namespace fst {
 namespace script {
 
-using EncodeArgs1 =
-    std::tuple<MutableFstClass *, uint32, bool, const std::string &>;
+using EncodeArgs = std::tuple<MutableFstClass *, EncodeMapperClass *>;
 
 template <class Arc>
-void Encode(EncodeArgs1 *args) {
+void Encode(EncodeArgs *args) {
   MutableFst<Arc> *fst = std::get<0>(*args)->GetMutableFst<Arc>();
-  const std::string &coder_fname = std::get<3>(*args);
-  // If true, reuse encode from disk. If false, make a new encoder and just use
-  // the filename argument as the destination state.
-  std::unique_ptr<EncodeMapper<Arc>> encoder(
-      std::get<2>(*args) ? EncodeMapper<Arc>::Read(coder_fname, ENCODE)
-                         : new EncodeMapper<Arc>(std::get<1>(*args), ENCODE));
-  Encode(fst, encoder.get());
-  if (!std::get<2>(*args)) encoder->Write(coder_fname);
+  EncodeMapper<Arc> *mapper = std::get<1>(*args)->GetEncodeMapper<Arc>();
+  Encode(fst, mapper);
 }
 
-using EncodeArgs2 = std::pair<MutableFstClass *, EncodeMapperClass *>;
-
-template <class Arc>
-void Encode(EncodeArgs2 *args) {
-  MutableFst<Arc> *fst = std::get<0>(*args)->GetMutableFst<Arc>();
-  EncodeMapper<Arc> *encoder = std::get<1>(*args)->GetEncodeMapper<Arc>();
-  Encode(fst, encoder);
-}
-
-void Encode(MutableFstClass *fst, uint32 flags, bool reuse_encoder,
-            const std::string &coder_fname);
-
-void Encode(MutableFstClass *fst, EncodeMapperClass *encoder);
+void Encode(MutableFstClass *fst, EncodeMapperClass *mapper);
 
 }  // namespace script
 }  // namespace fst
index 2ad39b0..5796a71 100644 (file)
@@ -8,7 +8,8 @@
 #include <memory>
 #include <string>
 
-#include <fst/fstlib.h>
+#include <fst/encode.h>
+#include <fst/generic-register.h>
 #include <fst/script/arc-class.h>
 #include <fst/script/fst-class.h>
 
 namespace fst {
 namespace script {
 
-// Virtual interface implemented by each concrete EncodeMapperClassImpl<A>.
+// Virtual interface implemented by each concrete EncodeMapperClassImpl<Arc>.
 class EncodeMapperImplBase {
  public:
   // Returns an encoded ArcClass.
-  virtual ArcClass operator()(const ArcClass &a) = 0;
+  virtual ArcClass operator()(const ArcClass &) = 0;
   virtual const std::string &ArcType() const = 0;
-  virtual uint32 Flags() const = 0;
-  virtual uint64 Properties(uint64 inprops) = 0;
+  virtual const std::string &WeightType() const = 0;
+  virtual EncodeMapperImplBase *Copy() const = 0;
+  virtual uint8 Flags() const = 0;
+  virtual uint64 Properties(uint64) = 0;
   virtual EncodeType Type() const = 0;
+  virtual bool Write(const std::string &) const = 0;
+  virtual bool Write(std::ostream &, const std::string &) const = 0;
   virtual const SymbolTable *InputSymbols() const = 0;
   virtual const SymbolTable *OutputSymbols() const = 0;
-  virtual void SetInputSymbols(const SymbolTable *syms) = 0;
-  virtual void SetOutputSymbols(const SymbolTable *syms) = 0;
-  virtual const std::string &WeightType() const = 0;
+  virtual void SetInputSymbols(const SymbolTable *) = 0;
+  virtual void SetOutputSymbols(const SymbolTable *) = 0;
   virtual ~EncodeMapperImplBase() {}
 };
 
@@ -38,81 +42,109 @@ class EncodeMapperImplBase {
 template <class Arc>
 class EncodeMapperClassImpl : public EncodeMapperImplBase {
  public:
-  EncodeMapperClassImpl(uint32 flags, EncodeType type)
-      : encoder_(flags, type) {}
+  explicit EncodeMapperClassImpl(const EncodeMapper<Arc> &mapper)
+      : mapper_(mapper) {}
 
   ArcClass operator()(const ArcClass &a) final;
 
   const std::string &ArcType() const final { return Arc::Type(); }
 
-  uint32 Flags() const final { return encoder_.Flags(); }
+  const std::string &WeightType() const final { return Arc::Weight::Type(); }
+
+  EncodeMapperClassImpl<Arc> *Copy() const final {
+    return new EncodeMapperClassImpl<Arc>(mapper_);
+  }
+
+  uint8 Flags() const final { return mapper_.Flags(); }
 
   uint64 Properties(uint64 inprops) final {
-    return encoder_.Properties(inprops);
+    return mapper_.Properties(inprops);
+  }
+
+  EncodeType Type() const final { return mapper_.Type(); }
+
+  bool Write(const std::string &source) const final {
+    return mapper_.Write(source);
   }
 
-  EncodeType Type() const final { return encoder_.Type(); }
+  bool Write(std::ostream &strm, const std::string &source) const final {
+    return mapper_.Write(strm, source);
+  }
 
   const SymbolTable *InputSymbols() const final {
-    return encoder_.InputSymbols();
+    return mapper_.InputSymbols();
   }
 
   const SymbolTable *OutputSymbols() const final {
-    return encoder_.OutputSymbols();
+    return mapper_.OutputSymbols();
   }
 
   void SetInputSymbols(const SymbolTable *syms) final {
-    encoder_.SetInputSymbols(syms);
+    mapper_.SetInputSymbols(syms);
   }
 
   void SetOutputSymbols(const SymbolTable *syms) final {
-    encoder_.SetOutputSymbols(syms);
+    mapper_.SetOutputSymbols(syms);
   }
 
-  const std::string &WeightType() const final { return Arc::Weight::Type(); }
-
   ~EncodeMapperClassImpl() override {}
 
-  EncodeMapper<Arc> *GetImpl() const { return &encoder_; }
+  EncodeMapper<Arc> *GetImpl() const { return &mapper_; }
 
-  EncodeMapper<Arc> *GetImpl() { return &encoder_; }
+  EncodeMapper<Arc> *GetImpl() { return &mapper_; }
 
  private:
-  EncodeMapper<Arc> encoder_;
+  EncodeMapper<Arc> mapper_;
 };
 
-// This is returned by value because it is very likely to undergo return-value
-// optimization.
 template <class Arc>
 inline ArcClass EncodeMapperClassImpl<Arc>::operator()(const ArcClass &a) {
-  Arc arc(a.ilabel, a.olabel, *(a.weight.GetWeight<typename Arc::Weight>()),
-          a.nextstate);
-  return ArcClass(encoder_(arc));
+  const Arc arc(a.ilabel, a.olabel,
+                *(a.weight.GetWeight<typename Arc::Weight>()), a.nextstate);
+  return ArcClass(mapper_(arc));
 }
 
-class EncodeMapperClass;
-
-using InitEncodeMapperClassArgs =
-    std::tuple<uint32, EncodeType, EncodeMapperClass *>;
-
 class EncodeMapperClass {
  public:
-  EncodeMapperClass(const std::string &arc_type, uint32 flags, EncodeType type);
+  EncodeMapperClass() : impl_(nullptr) {}
+
+  EncodeMapperClass(const std::string &arc_type, uint8 flags,
+                    EncodeType type = ENCODE);
 
   template <class Arc>
-  EncodeMapperClass(uint32 flags, EncodeType type)
-      : impl_(new EncodeMapperClassImpl<Arc>(flags, type)) {}
+  explicit EncodeMapperClass(const EncodeMapper<Arc> &mapper)
+      : impl_(new EncodeMapperClassImpl<Arc>(mapper)) {}
+
+  EncodeMapperClass(const EncodeMapperClass &other)
+      : impl_(other.impl_ == nullptr ? nullptr : other.impl_->Copy()) {}
+
+  EncodeMapperClass &operator=(const EncodeMapperClass &other) {
+    impl_.reset(other.impl_ == nullptr ? nullptr : other.impl_->Copy());
+    return *this;
+  }
 
   ArcClass operator()(const ArcClass &arc) { return (*impl_)(arc); }
 
   const std::string &ArcType() const { return impl_->ArcType(); }
 
-  uint32 Flags() const { return impl_->Flags(); }
+  const std::string &WeightType() const { return impl_->WeightType(); }
+
+  uint8 Flags() const { return impl_->Flags(); }
 
   uint64 Properties(uint64 inprops) { return impl_->Properties(inprops); }
 
   EncodeType Type() const { return impl_->Type(); }
 
+  static EncodeMapperClass *Read(const std::string &source);
+
+  static EncodeMapperClass *Read(std::istream &strm, const std::string &source);
+
+  bool Write(const std::string &source) const { return impl_->Write(source); }
+
+  bool Write(std::ostream &strm, const std::string &source) const {
+    return impl_->Write(strm, source);
+  }
+
   const SymbolTable *InputSymbols() const { return impl_->InputSymbols(); }
 
   const SymbolTable *OutputSymbols() const { return impl_->OutputSymbols(); }
@@ -125,13 +157,7 @@ class EncodeMapperClass {
     impl_->SetOutputSymbols(syms);
   }
 
-  const std::string &WeightType() const { return impl_->WeightType(); }
-
-  template <class Arc>
-  friend void InitEncodeMapperClass(InitEncodeMapperClassArgs *args);
-
-  // Naturally, this exists in non-const and const forms. Encoding arcs or FSTs
-  // mutates the underlying encoder; decoding them does not.
+  // Implementation stuff.
 
   template <class Arc>
   EncodeMapper<Arc> *GetEncodeMapper() {
@@ -153,15 +179,92 @@ class EncodeMapperClass {
     }
   }
 
+  // Required for registration.
+
+  template <class Arc>
+  static EncodeMapperClass *Read(std::istream &strm,
+                                 const std::string &source) {
+    std::unique_ptr<EncodeMapper<Arc>> mapper(
+        EncodeMapper<Arc>::Read(strm, source));
+    return mapper ? new EncodeMapperClass(*mapper) : nullptr;
+  }
+
+  template <class Arc>
+  static EncodeMapperImplBase *Create(uint8 flags, EncodeType type = ENCODE) {
+    return new EncodeMapperClassImpl<Arc>(EncodeMapper<Arc>(flags, type));
+  }
+
  private:
+  explicit EncodeMapperClass(EncodeMapperImplBase *impl) : impl_(impl) {}
+
+  const EncodeMapperImplBase *GetImpl() const { return impl_.get(); }
+
+  EncodeMapperImplBase *GetImpl() { return impl_.get(); }
+
   std::unique_ptr<EncodeMapperImplBase> impl_;
 };
 
-template <class Arc>
-void InitEncodeMapperClass(InitEncodeMapperClassArgs *args) {
-  std::get<2>(*args)->impl_.reset(
-      new EncodeMapperClassImpl<Arc>(std::get<0>(*args), std::get<1>(*args)));
-}
+// Registration for EncodeMapper types.
+
+// This class definition is to avoid a nested class definition inside the
+// EncodeMapperIORegistration struct.
+
+template <class Reader, class Creator>
+struct EncodeMapperClassRegEntry {
+  Reader reader;
+  Creator creator;
+
+  EncodeMapperClassRegEntry(Reader reader, Creator creator)
+      : reader(reader), creator(creator) {}
+
+  EncodeMapperClassRegEntry() : reader(nullptr), creator(nullptr) {}
+};
+
+template <class Reader, class Creator>
+class EncodeMapperClassIORegister
+    : public GenericRegister<std::string,
+                             EncodeMapperClassRegEntry<Reader, Creator>,
+                             EncodeMapperClassIORegister<Reader, Creator>> {
+ public:
+  Reader GetReader(const std::string &arc_type) const {
+    return this->GetEntry(arc_type).reader;
+  }
+
+  Creator GetCreator(const std::string &arc_type) const {
+    return this->GetEntry(arc_type).creator;
+  }
+
+ protected:
+  std::string ConvertKeyToSoFilename(const std::string &key) const final {
+    std::string legal_type(key);
+    ConvertToLegalCSymbol(&legal_type);
+    return legal_type + "-arc.so";
+  }
+};
+
+// Struct containing everything needed to register a particular type
+struct EncodeMapperClassIORegistration {
+  using Reader = EncodeMapperClass *(*)(std::istream &stream,
+                                        const std::string &source);
+
+  using Creator = EncodeMapperImplBase *(*)(uint8 flags, EncodeType type);
+
+  using Entry = EncodeMapperClassRegEntry<Reader, Creator>;
+
+  // EncodeMapper register.
+  using Register = EncodeMapperClassIORegister<Reader, Creator>;
+
+  // EncodeMapper register-er.
+  using Registerer =
+      GenericRegisterer<EncodeMapperClassIORegister<Reader, Creator>>;
+};
+
+#define REGISTER_ENCODEMAPPER_CLASS(Arc)             \
+  static EncodeMapperClassIORegistration::Registerer \
+      Class##_##Arc##_registerer(                    \
+          Arc::Type(),                               \
+          EncodeMapperClassIORegistration::Entry(    \
+              EncodeMapperClass::Read<Arc>, EncodeMapperClass::Create<Arc>));
 
 }  // namespace script
 }  // namespace fst
index 1d9629e..18646b4 100644 (file)
@@ -5,12 +5,14 @@
 #define FST_SCRIPT_FST_CLASS_H_
 
 #include <algorithm>
+#include <istream>
 #include <limits>
 #include <string>
 #include <type_traits>
 
 #include <fst/expanded-fst.h>
 #include <fst/fst.h>
+#include <fst/generic-register.h>
 #include <fst/mutable-fst.h>
 #include <fst/vector-fst.h>
 #include <fst/script/arc-class.h>
@@ -257,12 +259,12 @@ class FstClassImpl : public FstClassImplBase {
 
   const std::string &WeightType() const final { return Arc::Weight::Type(); }
 
-  bool Write(const std::string &fname) const final {
-    return impl_->Write(fname);
+  bool Write(const std::string &source) const final {
+    return impl_->Write(source);
   }
 
-  bool Write(std::ostream &ostr, const std::string &fname) const final {
-    const FstWriteOptions opts(fname);
+  bool Write(std::ostream &ostr, const std::string &source) const final {
+    const FstWriteOptions opts(source);
     return impl_->Write(ostr, opts);
   }
 
@@ -323,7 +325,7 @@ class FstClass : public FstClassBase {
     return impl_->Properties(mask, test);
   }
 
-  static FstClass *Read(const std::string &fname);
+  static FstClass *Read(const std::string &source);
 
   static FstClass *Read(std::istream &istrm, const std::string &source);
 
@@ -339,12 +341,12 @@ class FstClass : public FstClassBase {
   bool WeightTypesMatch(const WeightClass &weight,
                         const std::string &op_name) const;
 
-  bool Write(const std::string &fname) const final {
-    return impl_->Write(fname);
+  bool Write(const std::string &source) const final {
+    return impl_->Write(source);
   }
 
-  bool Write(std::ostream &ostr, const std::string &fname) const final {
-    return impl_->Write(ostr, fname);
+  bool Write(std::ostream &ostr, const std::string &source) const final {
+    return impl_->Write(ostr, source);
   }
 
   ~FstClass() override {}
@@ -447,7 +449,7 @@ class MutableFstClass : public FstClass {
 
   void ReserveStates(int64 n) { GetImpl()->ReserveStates(n); }
 
-  static MutableFstClass *Read(const std::string &fname, bool convert = false);
+  static MutableFstClass *Read(const std::string &source, bool convert = false);
 
   void SetInputSymbols(SymbolTable *isyms) {
     GetImpl()->SetInputSymbols(isyms);
@@ -513,7 +515,7 @@ class VectorFstClass : public MutableFstClass {
 
   explicit VectorFstClass(const std::string &arc_type);
 
-  static VectorFstClass *Read(const std::string &fname);
+  static VectorFstClass *Read(const std::string &source);
 
   template <class Arc>
   static VectorFstClass *Read(std::istream &stream,
@@ -537,6 +539,83 @@ class VectorFstClass : public MutableFstClass {
   }
 };
 
+// Registration stuff.
+
+// This class definition is to avoid a nested class definition inside the
+// FstClassIORegistration struct.
+template <class Reader, class Creator, class Converter>
+struct FstClassRegEntry {
+  Reader reader;
+  Creator creator;
+  Converter converter;
+
+  FstClassRegEntry(Reader r, Creator cr, Converter co)
+      : reader(r), creator(cr), converter(co) {}
+
+  FstClassRegEntry() : reader(nullptr), creator(nullptr), converter(nullptr) {}
+};
+
+// Actual FST IO method register.
+template <class Reader, class Creator, class Converter>
+class FstClassIORegister
+    : public GenericRegister<std::string,
+                             FstClassRegEntry<Reader, Creator, Converter>,
+                             FstClassIORegister<Reader, Creator, Converter>> {
+ public:
+  Reader GetReader(const std::string &arc_type) const {
+    return this->GetEntry(arc_type).reader;
+  }
+
+  Creator GetCreator(const std::string &arc_type) const {
+    return this->GetEntry(arc_type).creator;
+  }
+
+  Converter GetConverter(const std::string &arc_type) const {
+    return this->GetEntry(arc_type).converter;
+  }
+
+ protected:
+  std::string ConvertKeyToSoFilename(const std::string &key) const final {
+    std::string legal_type(key);
+    ConvertToLegalCSymbol(&legal_type);
+    return legal_type + "-arc.so";
+  }
+};
+
+// Struct containing everything needed to register a particular type
+// of FST class (e.g., a plain FstClass, or a MutableFstClass, etc.).
+template <class FstClassType>
+struct FstClassIORegistration {
+  using Reader = FstClassType *(*)(std::istream &stream,
+                                   const FstReadOptions &opts);
+
+  using Creator = FstClassImplBase *(*)();
+
+  using Converter = FstClassImplBase *(*)(const FstClass &other);
+
+  using Entry = FstClassRegEntry<Reader, Creator, Converter>;
+
+  // FST class Register.
+  using Register = FstClassIORegister<Reader, Creator, Converter>;
+
+  // FST class Register-er.
+  using Registerer =
+      GenericRegisterer<FstClassIORegister<Reader, Creator, Converter>>;
+};
+
+// Macros for registering other arc types.
+
+#define REGISTER_FST_CLASS(Class, Arc)                                         \
+  static FstClassIORegistration<Class>::Registerer Class##_##Arc##_registerer( \
+      Arc::Type(),                                                             \
+      FstClassIORegistration<Class>::Entry(                                    \
+          Class::Read<Arc>, Class::Create<Arc>, Class::Convert<Arc>))
+
+#define REGISTER_FST_CLASSES(Arc)           \
+  REGISTER_FST_CLASS(FstClass, Arc);        \
+  REGISTER_FST_CLASS(MutableFstClass, Arc); \
+  REGISTER_FST_CLASS(VectorFstClass, Arc);
+
 }  // namespace script
 }  // namespace fst
 
index 45f1617..791d292 100644 (file)
@@ -92,37 +92,33 @@ class AllFstOperationsRegisterer {
     REGISTER_FST_OPERATION(Compose, Arc, ComposeArgs);
     REGISTER_FST_OPERATION(Concat, Arc, ConcatArgs1);
     REGISTER_FST_OPERATION(Concat, Arc, ConcatArgs2);
+    REGISTER_FST_OPERATION(Concat, Arc, ConcatArgs3);
     REGISTER_FST_OPERATION(Connect, Arc, MutableFstClass);
     REGISTER_FST_OPERATION(Convert, Arc, ConvertArgs);
-    REGISTER_FST_OPERATION(Decode, Arc, DecodeArgs1);
-    REGISTER_FST_OPERATION(Decode, Arc, DecodeArgs2);
+    REGISTER_FST_OPERATION(Decode, Arc, DecodeArgs);
     REGISTER_FST_OPERATION(Determinize, Arc, DeterminizeArgs);
     REGISTER_FST_OPERATION(Difference, Arc, DifferenceArgs);
     REGISTER_FST_OPERATION(Disambiguate, Arc, DisambiguateArgs);
-    REGISTER_FST_OPERATION(DrawFst, Arc, FstDrawerArgs);
-    REGISTER_FST_OPERATION(Encode, Arc, EncodeArgs1);
-    REGISTER_FST_OPERATION(Encode, Arc, EncodeArgs2);
+    REGISTER_FST_OPERATION(Draw, Arc, DrawArgs);
+    REGISTER_FST_OPERATION(Encode, Arc, EncodeArgs);
     REGISTER_FST_OPERATION(EpsNormalize, Arc, EpsNormalizeArgs);
     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,
-                           InitEncodeMapperClassArgs);
     REGISTER_FST_OPERATION(InitMutableArcIteratorClass, Arc,
                            InitMutableArcIteratorClassArgs);
     REGISTER_FST_OPERATION(InitStateIteratorClass, Arc,
                            InitStateIteratorClassArgs);
+    REGISTER_FST_OPERATION(Info, Arc, InfoArgs);
+    REGISTER_FST_OPERATION(Intersect, Arc, IntersectArgs);
+    REGISTER_FST_OPERATION(Invert, Arc, MutableFstClass);
   }
 
   void RegisterBatch2() {
-    REGISTER_FST_OPERATION(Intersect, Arc, IntersectArgs);
-    REGISTER_FST_OPERATION(Invert, Arc, MutableFstClass);
     REGISTER_FST_OPERATION(Map, Arc, MapArgs);
     REGISTER_FST_OPERATION(Minimize, Arc, MinimizeArgs);
-    REGISTER_FST_OPERATION(PrintFst, Arc, FstPrinterArgs);
+    REGISTER_FST_OPERATION(Print, Arc, PrintArgs);
     REGISTER_FST_OPERATION(Project, Arc, ProjectArgs);
     REGISTER_FST_OPERATION(Prune, Arc, PruneArgs1);
     REGISTER_FST_OPERATION(Prune, Arc, PruneArgs2);
@@ -141,7 +137,8 @@ class AllFstOperationsRegisterer {
     REGISTER_FST_OPERATION(ShortestPath, Arc, ShortestPathArgs);
     REGISTER_FST_OPERATION(Synchronize, Arc, SynchronizeArgs);
     REGISTER_FST_OPERATION(TopSort, Arc, TopSortArgs);
-    REGISTER_FST_OPERATION(Union, Arc, UnionArgs);
+    REGISTER_FST_OPERATION(Union, Arc, UnionArgs1);
+    REGISTER_FST_OPERATION(Union, Arc, UnionArgs2);
     REGISTER_FST_OPERATION(Verify, Arc, VerifyArgs);
   }
 };
index b09dc62..7b3eb67 100644 (file)
@@ -35,7 +35,7 @@ bool GetComposeFilter(const std::string &str, ComposeFilter *compose_filter);
 
 bool GetDeterminizeType(const std::string &str, DeterminizeType *det_type);
 
-inline uint32 GetEncodeFlags(bool encode_labels, bool encode_weights) {
+inline uint8 GetEncodeFlags(bool encode_labels, bool encode_weights) {
   return (encode_labels ? kEncodeLabels : 0) |
          (encode_weights ? kEncodeWeights : 0);
 }
@@ -50,8 +50,8 @@ inline ProjectType GetProjectType(bool project_output) {
   return project_output ? PROJECT_OUTPUT : PROJECT_INPUT;
 }
 
-inline uint32 GetPushFlags(bool push_weights, bool push_labels,
-                           bool remove_total_weight, bool remove_common_affix) {
+inline uint8 GetPushFlags(bool push_weights, bool push_labels,
+                          bool remove_total_weight, bool remove_common_affix) {
   return ((push_weights ? kPushWeights : 0) |
           (push_labels ? kPushLabels : 0) |
           (remove_total_weight ? kPushRemoveTotalWeight : 0) |
index 9ba73ad..f0721cb 100644 (file)
@@ -29,8 +29,6 @@ namespace fst {
 // Fst<Arc>::NumArcs, TestProperties, etc.
 class FstInfo {
  public:
-  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>
@@ -274,6 +272,8 @@ class FstInfo {
     return properties_;
   }
 
+  void Info() const;
+
  private:
   void CheckLong() const {
     if (!long_info_)
@@ -307,7 +307,7 @@ class FstInfo {
   std::string arc_type_;
 };
 
-void PrintFstInfoImpl(const FstInfo &fstinfo, bool pipe = false);
+void InfoImpl(const FstInfo &fstinfo);
 
 }  // namespace fst
 
index dc6bdc1..df26d10 100644 (file)
@@ -15,34 +15,19 @@ namespace fst {
 namespace script {
 
 using InfoArgs = std::tuple<const FstClass &, bool, const std::string &,
-                            const std::string &, bool, bool>;
+                            const std::string &, bool>;
 
 template <class Arc>
-void PrintFstInfo(InfoArgs *args) {
+void Info(InfoArgs *args) {
   const Fst<Arc> &fst = *std::get<0>(*args).GetFst<Arc>();
-  const FstInfo fstinfo(fst, std::get<1>(*args), std::get<2>(*args),
-                        std::get<3>(*args), std::get<4>(*args));
-  PrintFstInfoImpl(fstinfo, std::get<5>(*args));
-  if (std::get<5>(*args)) fst.Write("");
+  const FstInfo info(fst, std::get<1>(*args), std::get<2>(*args),
+                     std::get<3>(*args), std::get<4>(*args));
+  info.Info();
 }
 
-void PrintFstInfo(const FstClass &f, bool test_properties,
-                  const std::string &arc_filter, const std::string &info_type,
-                  bool pipe, bool verify);
-
-using GetInfoArgs = std::tuple<const FstClass &, bool, const std::string &,
-                               const std::string &, bool, FstInfo *>;
-
-template <class Arc>
-void GetFstInfo(GetInfoArgs *args) {
-  const Fst<Arc> &fst = *std::get<0>(*args).GetFst<Arc>();
-  *(std::get<5>(*args)) = FstInfo(fst, std::get<1>(*args), std::get<2>(*args),
-                                  std::get<3>(*args), std::get<4>(*args));
-}
-
-void GetFstInfo(const FstClass &fst, bool test_properties,
-                const std::string &arc_filter, const std::string &info_type,
-                bool verify, FstInfo *info);
+void Info(const FstClass &fst, bool test_properties,
+          const std::string &arc_filter, const std::string &info_type,
+          bool verify);
 
 }  // namespace script
 }  // namespace fst
index 91ffdce..59cb7d7 100644 (file)
@@ -14,8 +14,6 @@
 #include <fst/fstlib.h>
 #include <fst/util.h>
 
-DECLARE_string(fst_field_separator);
-
 namespace fst {
 
 // Print a binary FST in textual format (helper class for fstprint.cc).
@@ -28,23 +26,25 @@ class FstPrinter {
   using Label = typename Arc::Label;
   using Weight = typename Arc::Weight;
 
-  FstPrinter(const Fst<Arc> &fst, const SymbolTable *isyms,
-             const SymbolTable *osyms, const SymbolTable *ssyms, bool accep,
-             bool show_weight_one, const std::string &field_separator,
-             const std::string &missing_symbol = "")
+  explicit FstPrinter(const Fst<Arc> &fst, const SymbolTable *isyms,
+                      const SymbolTable *osyms,
+                      const SymbolTable *ssyms, bool accept,
+                      bool show_weight_one,
+                      const std::string &field_separator,
+                      const std::string &missing_symbol = "")
       : fst_(fst),
         isyms_(isyms),
         osyms_(osyms),
         ssyms_(ssyms),
-        accep_(accep && fst.Properties(kAcceptor, true)),
+        accept_(accept && (fst.Properties(kAcceptor, true) == kAcceptor)),
         ostrm_(nullptr),
         show_weight_one_(show_weight_one),
         sep_(field_separator),
         missing_symbol_(missing_symbol) {}
 
   // Prints FST to an output stream.
-  void Print(std::ostream *ostrm, const std::string &dest) {
-    ostrm_ = ostrm;
+  void Print(std::ostream &ostrm, const std::string &dest) {
+    ostrm_ = &ostrm;
     dest_ = dest;
     const auto start = fst_.Start();
     if (start == kNoStateId) return;
@@ -92,7 +92,7 @@ class FstPrinter {
       PrintStateId(arc.nextstate);
       *ostrm_ << sep_;
       PrintILabel(arc.ilabel);
-      if (!accep_) {
+      if (!accept_) {
         *ostrm_ << sep_;
         PrintOLabel(arc.olabel);
       }
@@ -115,7 +115,7 @@ class FstPrinter {
   const SymbolTable *isyms_;    // ilabel symbol table.
   const SymbolTable *osyms_;    // olabel symbol table.
   const SymbolTable *ssyms_;    // slabel symbol table.
-  bool accep_;                  // Print as acceptor when possible?
+  bool accept_;                 // Print as acceptor when possible?
   std::ostream *ostrm_;         // Text FST destination.
   std::string dest_;            // Text FST destination name.
   bool show_weight_one_;        // Print weights equal to Weight::One()?
index 05c57cc..bb043dc 100644 (file)
@@ -15,27 +15,25 @@ DECLARE_string(fst_field_separator);
 namespace fst {
 namespace script {
 
-// Note: it is safe to pass these strings as references because
-// this struct is only used to pass them deeper in the call graph.
-// Be sure you understand why this is so before using this struct
-// for anything else!
-struct FstPrinterArgs {
+// Note: it is safe to pass these strings as references because this struct is
+// only used to pass them deeper in the call graph. Be sure you understand why
+// this is so before using this struct for anything else!
+struct PrintArgs {
   const FstClass &fst;
   const SymbolTable *isyms;
   const SymbolTable *osyms;
   const SymbolTable *ssyms;
   const bool accept;
   const bool show_weight_one;
-  std::ostream *ostrm;
+  std::ostream &ostrm;
   const std::string &dest;
-  const std::string &sep;  // NOLINT
+  const std::string &sep;
   const std::string &missing_symbol;
 
-  FstPrinterArgs(const FstClass &fst, const SymbolTable *isyms,
-                 const SymbolTable *osyms, const SymbolTable *ssyms,
-                 bool accept, bool show_weight_one, std::ostream *ostrm,
-                 const std::string &dest, const std::string &sep,
-                 const std::string &missing_sym = "")
+  PrintArgs(const FstClass &fst, const SymbolTable *isyms,
+            const SymbolTable *osyms, const SymbolTable *ssyms, bool accept,
+            bool show_weight_one, std::ostream &ostrm, const std::string &dest,
+            const std::string &sep, const std::string &missing_sym = "")
       : fst(fst),
         isyms(isyms),
         osyms(osyms),
@@ -49,7 +47,7 @@ struct FstPrinterArgs {
 };
 
 template <class Arc>
-void PrintFst(FstPrinterArgs *args) {
+void Print(PrintArgs *args) {
   const Fst<Arc> &fst = *args->fst.GetFst<Arc>();
   FstPrinter<Arc> fstprinter(fst, args->isyms, args->osyms, args->ssyms,
                              args->accept, args->show_weight_one, args->sep,
@@ -57,12 +55,20 @@ void PrintFst(FstPrinterArgs *args) {
   fstprinter.Print(args->ostrm, args->dest);
 }
 
+void Print(const FstClass &fst, std::ostream &ostrm, const std::string &dest,
+           const SymbolTable *isyms = nullptr,
+           const SymbolTable *osyms = nullptr,
+           const SymbolTable *ssyms = nullptr, bool accept = true,
+           bool show_weight_one = true, const std::string &missing_sym = "");
+
+// TODO(kbg,2019-09-01): Deprecated.
 void PrintFst(const FstClass &fst, std::ostream &ostrm, const std::string &dest,
               const SymbolTable *isyms, const SymbolTable *osyms,
               const SymbolTable *ssyms, bool accept, bool show_weight_one,
               const std::string &missing_sym = "");
 
-// The same, but with more sensible defaults.
+// The same, but with more sensible defaults, and for arc-templated FSTs only.
+// TODO(kbg,2019-09-01): Deprecated.
 template <class Arc>
 void PrintFst(const Fst<Arc> &fst, std::ostream &ostrm,
               const std::string &dest = "", const SymbolTable *isyms = nullptr,
@@ -70,7 +76,7 @@ void PrintFst(const Fst<Arc> &fst, std::ostream &ostrm,
               const SymbolTable *ssyms = nullptr) {
   const std::string sep = FLAGS_fst_field_separator.substr(0, 1);
   FstPrinter<Arc> fstprinter(fst, isyms, osyms, ssyms, true, true, sep);
-  fstprinter.Print(&ostrm, dest);
+  fstprinter.Print(ostrm, dest);
 }
 
 }  // namespace script
index a8709b8..900f537 100644 (file)
@@ -20,7 +20,7 @@ void Push(PushArgs1 *args) {
   Push(fst, std::get<1>(*args), std::get<2>(*args), std::get<3>(*args));
 }
 
-using PushArgs2 = std::tuple<const FstClass &, MutableFstClass *, uint32,
+using PushArgs2 = std::tuple<const FstClass &, MutableFstClass *, uint8,
                              ReweightType, float>;
 
 template <class Arc>
@@ -41,11 +41,11 @@ void Push(PushArgs2 *args) {
   }
 }
 
-void Push(MutableFstClass *fst, ReweightType rew_type, float delta = kDelta,
-          bool remove_total_weight = false);
+void Push(MutableFstClass *fst, ReweightType rew_type,
+          float delta = kShortestDelta, bool remove_total_weight = false);
 
-void Push(const FstClass &ifst, MutableFstClass *ofst, uint32 flags,
-          ReweightType rew_type, float delta = kDelta);
+void Push(const FstClass &ifst, MutableFstClass *ofst, uint8 flags,
+          ReweightType rew_type, float delta = kShortestDelta);
 
 }  // namespace script
 }  // namespace fst
diff --git a/src/include/fst/script/register.h b/src/include/fst/script/register.h
deleted file mode 100644 (file)
index ec53d60..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-// See www.openfst.org for extensive documentation on this weighted
-// finite-state transducer library.
-
-#ifndef FST_SCRIPT_REGISTER_H_
-#define FST_SCRIPT_REGISTER_H_
-
-#include <istream>
-#include <string>
-
-#include <fst/generic-register.h>
-#include <fst/script/fst-class.h>
-#include <fst/script/weight-class.h>
-
-// Holds methods and classes responsible for maintaining
-// the register for FstClass arc types.
-
-namespace fst {
-namespace script {
-
-// Registers for reading and converting various kinds of FST classes.
-
-// This class definition is to avoid a nested class definition inside the
-// IORegistration struct.
-
-template <class Reader, class Creator, class Converter>
-struct FstClassRegEntry {
-  Reader reader;
-  Creator creator;
-  Converter converter;
-
-  FstClassRegEntry(Reader r, Creator cr, Converter co)
-      : reader(r), creator(cr), converter(co) {}
-
-  FstClassRegEntry()
-      : reader(nullptr), creator(nullptr), converter(nullptr) {}
-};
-
-template <class Reader, class Creator, class Converter>
-class FstClassIORegister
-    : public GenericRegister<std::string,
-                             FstClassRegEntry<Reader, Creator, Converter>,
-                             FstClassIORegister<Reader, Creator, Converter>> {
- public:
-  Reader GetReader(const std::string &arc_type) const {
-    return this->GetEntry(arc_type).reader;
-  }
-
-  Creator GetCreator(const std::string &arc_type) const {
-    return this->GetEntry(arc_type).creator;
-  }
-
-  Converter GetConverter(const std::string &arc_type) const {
-    return this->GetEntry(arc_type).converter;
-  }
-
- protected:
-  std::string ConvertKeyToSoFilename(const std::string &key) const final {
-    std::string legal_type(key);
-    ConvertToLegalCSymbol(&legal_type);
-    return legal_type + "-arc.so";
-  }
-};
-
-// Struct containing everything needed to register a particular type
-// of FST class (e.g., a plain FstClass, or a MutableFstClass, etc.).
-template <class FstClassType>
-struct IORegistration {
-  using Reader = FstClassType *(*)(std::istream &stream,
-                                   const FstReadOptions &opts);
-
-  using Creator = FstClassImplBase *(*)();
-
-  using Converter = FstClassImplBase *(*)(const FstClass &other);
-
-  using Entry = FstClassRegEntry<Reader, Creator, Converter>;
-
-  // FST class Register.
-  using Register = FstClassIORegister<Reader, Creator, Converter>;
-
-  // FST class Register-er.
-  using Registerer =
-      GenericRegisterer<FstClassIORegister<Reader, Creator, Converter>>;
-};
-
-#define REGISTER_FST_CLASS(Class, Arc)                                   \
-  static IORegistration<Class>::Registerer Class##_##Arc##_registerer(   \
-      Arc::Type(),                                                       \
-      IORegistration<Class>::Entry(Class::Read<Arc>, Class::Create<Arc>, \
-                                   Class::Convert<Arc>))
-
-#define REGISTER_FST_CLASSES(Arc)           \
-  REGISTER_FST_CLASS(FstClass, Arc);        \
-  REGISTER_FST_CLASS(MutableFstClass, Arc); \
-  REGISTER_FST_CLASS(VectorFstClass, Arc);
-
-}  // namespace script
-}  // namespace fst
-
-#endif  // FST_SCRIPT_REGISTER_H_
index 1671076..e4d0453 100644 (file)
@@ -28,11 +28,9 @@ void Relabel(RelabelArgs1 *args) {
           std::get<7>(*args), std::get<8>(*args));
 }
 
-using LabelPair = std::pair<int64, int64>;
-
-using RelabelArgs2 = std::tuple<MutableFstClass *,
-                                const std::vector<LabelPair> &,
-                                const std::vector<LabelPair> &>;
+using RelabelArgs2 =
+    std::tuple<MutableFstClass *, const std::vector<std::pair<int64, int64>> &,
+               const std::vector<std::pair<int64, int64>> &>;
 
 template <class Arc>
 void Relabel(RelabelArgs2 *args) {
@@ -55,8 +53,9 @@ void Relabel(MutableFstClass *ofst, const SymbolTable *old_isymbols,
              const SymbolTable *old_osymbols, const SymbolTable *new_osymbols,
              const std::string &unknown_osymbol, bool attach_new_osymbols);
 
-void Relabel(MutableFstClass *ofst, const std::vector<LabelPair> &ipairs,
-             const std::vector<LabelPair> &opairs);
+void Relabel(MutableFstClass *ofst,
+             const std::vector<std::pair<int64, int64>> &ipairs,
+             const std::vector<std::pair<int64, int64>> &opairs);
 
 }  // namespace script
 }  // namespace fst
index 926ece2..d447d9d 100644 (file)
@@ -30,18 +30,16 @@ struct ReplaceOptions {
         return_label(return_label) {}
 };
 
-using LabelFstClassPair = std::pair<int64, const FstClass *>;
-
-using ReplaceArgs = std::tuple<const std::vector<LabelFstClassPair> &,
-                               MutableFstClass *, const ReplaceOptions &>;
+using ReplaceArgs =
+    std::tuple<const std::vector<std::pair<int64, const FstClass *>> &,
+               MutableFstClass *, const ReplaceOptions &>;
 
 template <class Arc>
 void Replace(ReplaceArgs *args) {
-  using LabelFstPair = std::pair<typename Arc::Label, const Fst<Arc> *>;
   // Now that we know the arc type, we construct a vector of
   // std::pair<real label, real fst> that the real Replace will use.
   const auto &untyped_pairs = std::get<0>(*args);
-  std::vector<LabelFstPair> typed_pairs;
+  std::vector<std::pair<typename Arc::Label, const Fst<Arc> *>> typed_pairs;
   typed_pairs.reserve(untyped_pairs.size());
   for (const auto &untyped_pair : untyped_pairs) {
     typed_pairs.emplace_back(untyped_pair.first,  // Converts label.
@@ -63,7 +61,7 @@ void Replace(ReplaceArgs *args) {
   *ofst = rfst;
 }
 
-void Replace(const std::vector<LabelFstClassPair> &pairs,
+void Replace(const std::vector<std::pair<int64, const FstClass *>> &pairs,
              MutableFstClass *ofst, const ReplaceOptions &opts);
 
 }  // namespace script
index 07bbbf9..c09f888 100644 (file)
 //  provided you also have:
 //
 //  4) A registration for your new operation, on the arc types you care about.
-//     This can be provided easily by the REGISTER_FST_OPERATION macro in
-//     operations.h:
+//     This can be provided easily by the REGISTER_FST_OPERATION macro:
 //
 //       REGISTER_FST_OPERATION(Foo, StdArc, FooArgs);
 //       REGISTER_FST_OPERATION(Foo, MyArc, FooArgs);
 //       // .. etc
 //
+//     You can also use REGISTER_FST_OPERATION_3ARCS macro to register an
+//     operation for StdArc, LogArc, and Log64Arc:
+//
+//       REGISTER_FST_OPERATION_3ARCS(Foo, FooArcs);
 //
 //  That's it! Now when you call Foo(const FstClass &, MutableFstClass *),
 //  it dispatches (in #3) via the Apply<> function to the correct
@@ -99,7 +102,6 @@ enum RandArcSelection {
 // The std::pair<std::string, std::string> is understood to be the operation
 // name and arc type; subclasses (or typedefs) need only provide the operation
 // signature.
-
 template <class OperationSignature>
 class GenericOperationRegister
     : public GenericRegister<std::pair<std::string, std::string>,
@@ -142,19 +144,23 @@ struct Operation {
   // The register (hash) type.
   using Register = GenericOperationRegister<OpType>;
 
-  // The register-er type
+  // The register-er type.
   using Registerer = GenericRegisterer<Register>;
 };
 
 // Macro for registering new types of operations.
-
 #define REGISTER_FST_OPERATION(Op, Arc, ArgPack)               \
   static fst::script::Operation<ArgPack>::Registerer       \
       arc_dispatched_operation_##ArgPack##Op##Arc##_registerer \
-      (std::make_pair(#Op, Arc::Type()), Op<Arc>)
+      ({#Op, Arc::Type()}, Op<Arc>)
 
-// Template function to apply an operation by name.
+// A macro that calls REGISTER_FST_OPERATION for widely-used arc types.
+#define REGISTER_FST_OPERATION_3ARCS(Op, ArgPack) \
+  REGISTER_FST_OPERATION(Op, StdArc, ArgPack);    \
+  REGISTER_FST_OPERATION(Op, LogArc, ArgPack);    \
+  REGISTER_FST_OPERATION(Op, Log64Arc, ArgPack)
 
+// Template function to apply an operation by name.
 template <class OpReg>
 void Apply(const std::string &op_name, const std::string &arc_type,
            typename OpReg::ArgPack *args) {
@@ -190,7 +196,7 @@ void CopyWeights(const std::vector<WeightClass> &weights,
   typed_weights->clear();
   typed_weights->reserve(weights.size());
   for (const auto &weight : weights) {
-    typed_weights->push_back(*weight.GetWeight<Weight>());
+    typed_weights->emplace_back(*weight.GetWeight<Weight>());
   }
 }
 
index c964072..99b6dd3 100644 (file)
 namespace fst {
 namespace script {
 
-bool ReadPotentials(const std::string &weight_type, const std::string &filename,
+bool ReadPotentials(const std::string &weight_type, const std::string &source,
                     std::vector<WeightClass> *potentials);
 
-bool WritePotentials(const std::string &filename,
+bool WritePotentials(const std::string &source,
                      const std::vector<WeightClass> &potentials);
 
 }  // namespace script
index d779250..0337da7 100644 (file)
@@ -5,6 +5,7 @@
 #define FST_SCRIPT_UNION_H_
 
 #include <utility>
+#include <vector>
 
 #include <fst/union.h>
 #include <fst/script/fst-class.h>
 namespace fst {
 namespace script {
 
-using UnionArgs = std::pair<MutableFstClass *, const FstClass &>;
+using UnionArgs1 = std::pair<MutableFstClass *, const FstClass &>;
 
 template <class Arc>
-void Union(UnionArgs *args) {
+void Union(UnionArgs1 *args) {
   MutableFst<Arc> *fst1 = std::get<0>(*args)->GetMutableFst<Arc>();
   const Fst<Arc> &fst2 = *std::get<1>(*args).GetFst<Arc>();
   Union(fst1, fst2);
 }
 
+using UnionArgs2 =
+    std::tuple<MutableFstClass *, const std::vector<const FstClass *> &>;
+
+template <class Arc>
+void Union(UnionArgs2 *args) {
+  MutableFst<Arc> *fst1 = std::get<0>(*args)->GetMutableFst<Arc>();
+  const auto &untyped_fsts2 = std::get<1>(*args);
+  std::vector<const Fst<Arc> *> typed_fsts2;
+  typed_fsts2.reserve(untyped_fsts2.size());
+  for (const auto &untyped_fst2 : untyped_fsts2) {
+    typed_fsts2.emplace_back(untyped_fst2->GetFst<Arc>());
+  }
+  Union(fst1, typed_fsts2);
+}
+
 void Union(MutableFstClass *fst1, const FstClass &fst2);
 
+void Union(MutableFstClass *fst1, const std::vector<const FstClass *> &fsts2);
+
 }  // namespace script
 }  // namespace fst
 
index 947cbe8..7f98fae 100644 (file)
@@ -117,16 +117,14 @@ class WeightClass {
     return *this;
   }
 
-  static constexpr const char *__ZERO__ = "__ZERO__";  // NOLINT
+  static constexpr char __ZERO__[] = "__ZERO__";  // NOLINT
+  static constexpr char __ONE__[] = "__ONE__";    // NOLINT
+  static constexpr char __NOWEIGHT__[] = "__NOWEIGHT__";  // NOLINT
 
   static WeightClass Zero(const std::string &weight_type);
 
-  static constexpr const char *__ONE__ = "__ONE__";  // NOLINT
-
   static WeightClass One(const std::string &weight_type);
 
-  static constexpr const char *__NOWEIGHT__ = "__NOWEIGHT__";  // NOLINT
-
   static WeightClass NoWeight(const std::string &weight_type);
 
   template <class W>
@@ -149,8 +147,8 @@ class WeightClass {
 
   bool Member() const { return impl_ && impl_->Member(); }
 
-  bool WeightTypesMatch(const WeightClass &other,
-                        const std::string &op_name) const;
+  static bool WeightTypesMatch(const WeightClass &lhs, const WeightClass &rhs,
+                               const std::string &op_name);
 
   friend bool operator==(const WeightClass &lhs, const WeightClass &rhs);
 
index af76dfb..6487524 100644 (file)
@@ -57,7 +57,7 @@ class SetWeight {
 
   // Input should be positive, sorted and unique.
   template <typename Iterator>
-  SetWeight(const Iterator &begin, const Iterator &end) {
+  SetWeight(const Iterator begin, const Iterator end) {
     for (auto iter = begin; iter != end; ++iter) PushBack(*iter);
   }
 
index 5311dae..6a7e449 100644 (file)
@@ -345,7 +345,7 @@ void NShortestPath(const Fst<RevArc> &ifst, MutableFst<Arc> *ofst,
   // (s, w). The vector pairs maps each state in ofst to the corresponding
   // pair maps states in ofst to the corresponding pair (s, w).
   std::vector<Pair> pairs;
-  // The supefinal state is denoted by kNoStateId. The distance from the
+  // The superfinal state is denoted by kNoStateId. The distance from the
   // superfinal state to the final state is semiring One, so
   // `distance[kNoStateId]` is not needed.
   const ShortestPathCompare<StateId, Weight> compare(pairs, distance,
@@ -496,8 +496,8 @@ void ShortestPath(const Fst<Arc> &ifst, MutableFst<Arc> *ofst,
                             opts.weight_threshold, opts.state_threshold);
   } else {
     std::vector<Weight> ddistance;
-    DeterminizeFstOptions<RevArc> dopts(opts.delta);
-    DeterminizeFst<RevArc> dfst(rfst, distance, &ddistance, dopts);
+    const DeterminizeFstOptions<RevArc> dopts(opts.delta);
+    const DeterminizeFst<RevArc> dfst(rfst, distance, &ddistance, dopts);
     internal::NShortestPath(dfst, ofst, ddistance, opts.nshortest, opts.delta,
                             opts.weight_threshold, opts.state_threshold);
   }
index 065f1c0..db99c01 100644 (file)
@@ -26,31 +26,31 @@ namespace fst {
 //
 // class StateMapper {
 //  public:
-//   using FromArc = A;
-//   using ToArc = B;
+//   using FromArc = ...;
+//   using ToArc = ...;
 //
 //   // Typical constructor.
-//   StateMapper(const Fst<A> &fst);
+//   StateMapper(const Fst<FromArc> &fst);
 //
 //   // Required copy constructor that allows updating FST argument;
 //   // pass only if relevant and changed.
-//   StateMapper(const StateMapper &mapper, const Fst<A> *fst = 0);
+//   StateMapper(const StateMapper &mapper, const Fst<FromArc> *fst = 0);
 //
 //   // Specifies initial state of result.
-//   B::StateId Start() const;
+//   ToArc::StateId Start() const;
 //   // Specifies state's final weight in result.
-//   B::Weight Final(B::StateId state) const;
+//   ToArc::Weight Final(ToArc::StateId state) const;
 //
 //   // These methods iterate through a state's arcs in result.
 //
 //   // Specifies state to iterate over.
-//   void SetState(B::StateId state);
+//   void SetState(ToArc::StateId state);
 //
 //   // End of arcs?
 //   bool Done() const;
 //
 //   // Current arc.
-//   const B &Value() const;
+//   const ToArc &Value() const;
 //
 //   // Advances to next arc (when !Done)
 //   void Next();
index a506759..d238e06 100644 (file)
@@ -195,7 +195,7 @@ class ErasableStateTable : public ErasableBiTable<typename T::StateId, T, H> {
 //   // Looks up a tuple by state ID.
 //   const ComposeStateTuple<StateId> &Tuple(StateId s) const;
 //
-//   // The number of of stored tuples.
+//   // The number of stored tuples.
 //   StateId Size() const;
 //
 //   // Return true if error was encountered.
@@ -262,7 +262,7 @@ class DefaultComposeStateTuple {
   FilterState fs_;  // State of composition filter.
 };
 
-// Specialization for TrivialFilterState that does not explicitely store the
+// Specialization for TrivialFilterState that does not explicitly store the
 // filter state since it is always the unique non-blocking state.
 template <typename S>
 class DefaultComposeStateTuple<S, TrivialFilterState> {
@@ -270,8 +270,7 @@ class DefaultComposeStateTuple<S, TrivialFilterState> {
   using StateId = S;
   using FilterState = TrivialFilterState;
 
-  DefaultComposeStateTuple()
-      : state_pair_(kNoStateId, kNoStateId) {}
+  DefaultComposeStateTuple() : state_pair_(kNoStateId, kNoStateId) {}
 
   DefaultComposeStateTuple(StateId s1, StateId s2, const FilterState &)
       : state_pair_(s1, s2) {}
@@ -289,7 +288,7 @@ class DefaultComposeStateTuple<S, TrivialFilterState> {
     return (&x == &y) || (x.state_pair_ == y.state_pair_);
   }
 
-  size_t Hash() const { return StateId1() + StateId2() * 7853; }
+  size_t Hash() const { return StateId1() + StateId2() * size_t{7853}; }
 
  private:
   std::pair<StateId, StateId> state_pair_;
index 662e7d5..6dd38d0 100644 (file)
@@ -54,7 +54,7 @@ class StringWeight {
   StringWeight() {}
 
   template <typename Iterator>
-  StringWeight(const Iterator &begin, const Iterator &end) {
+  StringWeight(const Iterator begin, const Iterator end) {
     for (auto iter = begin; iter != end; ++iter) PushBack(*iter);
   }
 
index c07eb69..490deda 100644 (file)
@@ -60,7 +60,8 @@ bool ConvertSymbolToLabel(const char *str, const SymbolTable *syms,
 template <class Label>
 bool ConvertStringToLabels(const std::string &str, StringTokenType token_type,
                            const SymbolTable *syms, Label unknown_label,
-                           bool allow_negative, std::vector<Label> *labels) {
+                           bool allow_negative, std::vector<Label> *labels,
+                           const std::string &sep = FLAGS_fst_field_separator) {
   labels->clear();
   if (token_type == StringTokenType::BYTE) {
     labels->reserve(str.size());
@@ -72,7 +73,7 @@ bool ConvertStringToLabels(const std::string &str, StringTokenType token_type,
     str.copy(c_str.get(), str.size());
     c_str[str.size()] = 0;
     std::vector<char *> vec;
-    const std::string separator = "\n" + FLAGS_fst_field_separator;
+    const std::string separator = "\n" + sep;
     SplitString(c_str.get(), separator.c_str(), &vec, true);
     for (const char *c : vec) {
       Label label;
@@ -86,12 +87,11 @@ bool ConvertStringToLabels(const std::string &str, StringTokenType token_type,
   return true;
 }
 
-// The sep string is used as a separator between symbols, unless it is nullptr,
-// in which case the last character of FLAGS_fst_field_separator is used.
+// The last character of 'sep' is used as a separator between symbols.
 template <class Label>
 bool LabelsToSymbolString(const std::vector<Label> &labels, std::string *str,
                           const SymbolTable &syms,
-                          const std::string *sep = nullptr) {
+                          const std::string &sep = FLAGS_fst_field_separator) {
   std::stringstream ostrm;
   std::string delim = "";
   for (auto label : labels) {
@@ -104,25 +104,22 @@ bool LabelsToSymbolString(const std::vector<Label> &labels, std::string *str,
       return false;
     }
     ostrm << symbol;
-    delim = sep != nullptr ? *sep
-                           : std::string(1, FLAGS_fst_field_separator.back());
+    delim = std::string(1, sep.back());
   }
   *str = ostrm.str();
   return !!ostrm;
 }
 
-// The sep string is used as a separator between symbols, unless it is nullptr,
-// in which case the last character of FLAGS_fst_field_separator is used.
+// The last character of 'sep' is used as a separator between symbols.
 template <class Label>
 bool LabelsToNumericString(const std::vector<Label> &labels, std::string *str,
-                           const std::string *sep = nullptr) {
+                           const std::string &sep = FLAGS_fst_field_separator) {
   std::stringstream ostrm;
   std::string delim = "";
   for (auto label : labels) {
     ostrm << delim;
     ostrm << label;
-    delim = sep != nullptr ? *sep
-                           : std::string(1, FLAGS_fst_field_separator.back());
+    delim = std::string(1, sep.back());
   }
   *str = ostrm.str();
   return !!ostrm;
@@ -147,25 +144,31 @@ class StringCompiler {
         unknown_label_(unknown_label),
         allow_negative_(allow_negative) {}
 
-  // Compiles string into an FST.
+  // Compiles string into an FST. With SYMBOL token type, sep is used to
+  // specify the set of char separators between symbols, in addition
+  // of '\n' which is always treated as a separator.
+  // Returns true on success.
   template <class FST>
-  bool operator()(const std::string &str, FST *fst) const {
+  bool operator()(const std::string &str, FST *fst,
+                  const std::string &sep = FLAGS_fst_field_separator) const {
     std::vector<Label> labels;
     if (!internal::ConvertStringToLabels(str, token_type_, syms_,
                                          unknown_label_, allow_negative_,
-                                         &labels)) {
+                                         &labels, sep)) {
       return false;
     }
     Compile(labels, fst);
     return true;
   }
 
+  // Same as above but allows to specify a weight for the string.
   template <class FST>
-  bool operator()(const std::string &str, FST *fst, Weight weight) const {
+  bool operator()(const std::string &str, FST *fst, Weight weight,
+                  const std::string &sep = FLAGS_fst_field_separator) const {
     std::vector<Label> labels;
     if (!internal::ConvertStringToLabels(str, token_type_, syms_,
                                          unknown_label_, allow_negative_,
-                                         &labels)) {
+                                         &labels, sep)) {
       return false;
     }
     Compile(labels, fst, std::move(weight));
@@ -190,7 +193,9 @@ class StringCompiler {
   template <class Unsigned>
   void Compile(const std::vector<Label> &labels,
                CompactStringFst<Arc, Unsigned> *fst) const {
-    fst->SetCompactElements(labels.begin(), labels.end());
+    using Compactor = typename CompactStringFst<Arc, Unsigned>::Compactor;
+    fst->SetCompactor(
+        std::make_shared<Compactor>(labels.begin(), labels.end()));
   }
 
   template <class Unsigned>
@@ -203,7 +208,10 @@ class StringCompiler {
       compacts.emplace_back(labels[i], Weight::One());
     }
     compacts.emplace_back(!labels.empty() ? labels.back() : kNoLabel, weight);
-    fst->SetCompactElements(compacts.begin(), compacts.end());
+    using Compactor =
+        typename CompactWeightedStringFst<Arc, Unsigned>::Compactor;
+    fst->SetCompactor(
+        std::make_shared<Compactor>(compacts.begin(), compacts.end()));
   }
 
   const StringTokenType token_type_;
@@ -251,15 +259,14 @@ bool StringFstToOutputLabels(const Fst<Arc> &fst,
   return true;
 }
 
-// Converts a list of symbols to a string. Returns true on success. If the token
-// type is SYMBOL and sep is provided, it is used to separate textual symbols.
-// If the token type is SYMBOL and it is not provided, the last character of
-// FLAGS_fst_field_separator is used.
+// Converts a list of symbols to a string. If the token type is SYMBOL, the last
+// character of sep is used to separate textual symbols.
+// Returns true on success.
 template <class Label>
 bool LabelsToString(const std::vector<Label> &labels, std::string *str,
                     StringTokenType ttype = BYTE,
                     const SymbolTable *syms = nullptr,
-                    const std::string *sep = nullptr) {
+                    const std::string &sep = FLAGS_fst_field_separator) {
   switch (ttype) {
     case StringTokenType::BYTE: {
       return LabelsToByteString(labels, str);
@@ -286,11 +293,10 @@ class StringPrinter {
                          const SymbolTable *syms = nullptr)
       : token_type_(token_type), syms_(syms) {}
 
-  // Converts the FST into a string. With SYMBOL token type, sep is used as a
-  // separator between symbols, unless it is nullptr, in which case the last
-  // character of FLAGS_fst_field_separator is used. Returns true on success.
+  // Converts the FST into a string. With SYMBOL token type, the last character
+  // of sep is used as a separator between symbols. Returns true on success.
   bool operator()(const Fst<Arc> &fst, std::string *str,
-                  const std::string *sep = nullptr) const {
+                  const std::string &sep = FLAGS_fst_field_separator) const {
     std::vector<Label> labels;
     return (StringFstToOutputLabels(fst, &labels) &&
             LabelsToString(labels, str, token_type_, syms_, sep));
index 740cd75..5c965a3 100644 (file)
@@ -64,7 +64,7 @@ SymbolTable *MergeSymbolTable(const SymbolTable &left, const SymbolTable &right,
 // Read the symbol table from any Fst::Read()able file, without loading the
 // corresponding FST. Returns nullptr if the FST does not contain a symbol
 // table or the symbol table cannot be read.
-SymbolTable *FstReadSymbols(const std::string &filename, bool input);
+SymbolTable *FstReadSymbols(const std::string &source, bool input);
 
 // Adds a contiguous range of symbols to a symbol table using a simple prefix
 // for the string, returning false if the inserted symbol string clashes with
index f766813..16f8c64 100644 (file)
@@ -43,6 +43,8 @@ namespace fst {
 
 constexpr int64 kNoSymbol = -1;
 
+class SymbolTable;
+
 // WARNING: Reading via symbol table read options should
 //          not be used. This is a temporary work around for
 //          reading symbol ranges of previously stored symbol sets.
@@ -83,8 +85,6 @@ class DenseSymbolMap {
 
   DenseSymbolMap();
 
-  DenseSymbolMap(const DenseSymbolMap &x);
-
   std::pair<int64, bool> InsertOrFind(KeyType key);
 
   int64 Find(KeyType key) const;
@@ -95,20 +95,94 @@ class DenseSymbolMap {
 
   void RemoveSymbol(size_t idx);
 
+  void ShrinkToFit();
+
  private:
+  static constexpr int64 kEmptyBucket = -1;
+
   // num_buckets must be power of 2.
   void Rehash(size_t num_buckets);
 
-  std::hash<typename std::remove_const<
+  size_t GetHash(KeyType key) const { return str_hash_(key) & hash_mask_; }
+
+  const std::hash<typename std::remove_const<
       typename std::remove_reference<KeyType>::type>::type>
       str_hash_;
-  int64 empty_;
   std::vector<std::string> symbols_;
   std::vector<int64> buckets_;
   uint64 hash_mask_;
 };
 
-class SymbolTableImpl {
+// Base class for SymbolTable implementations.
+// Use either MutableSymbolTableImpl or ConstSymbolTableImpl to derive
+// implementation classes.
+class SymbolTableImplBase {
+ public:
+  using SymbolType = DenseSymbolMap::KeyType;
+
+  SymbolTableImplBase() = default;
+  virtual ~SymbolTableImplBase() = default;
+
+  // Enforce copying through Copy().
+  SymbolTableImplBase(const SymbolTableImplBase &) = delete;
+  SymbolTableImplBase &operator=(const SymbolTableImplBase &) = delete;
+
+  virtual std::unique_ptr<SymbolTableImplBase> Copy() const = 0;
+
+  virtual bool Write(std::ostream &strm) const = 0;
+
+  virtual int64 AddSymbol(SymbolType symbol, int64 key) = 0;
+  virtual int64 AddSymbol(SymbolType symbol) = 0;
+
+  virtual void RemoveSymbol(int64 key) = 0;
+
+  virtual std::string Find(int64 key) const = 0;
+  virtual int64 Find(SymbolType symbol) const = 0;
+
+  virtual bool Member(int64 key) const { return !Find(key).empty(); }
+  virtual bool Member(SymbolType symbol) const {
+    return Find(symbol) != kNoSymbol;
+  }
+
+  virtual void AddTable(const SymbolTable &table) = 0;
+
+  virtual int64 GetNthKey(ssize_t pos) const = 0;
+
+  virtual const std::string &Name() const = 0;
+  virtual void SetName(const std::string &new_name) = 0;
+
+  virtual const std::string &CheckSum() const = 0;
+  virtual const std::string &LabeledCheckSum() const = 0;
+
+  virtual int64 AvailableKey() const = 0;
+  virtual size_t NumSymbols() const = 0;
+
+  virtual bool IsMutable() const = 0;
+};
+
+// Base class for SymbolTable implementations supporting Add/Remove.
+class MutableSymbolTableImpl : public SymbolTableImplBase {
+ public:
+  void AddTable(const SymbolTable &table) override;
+  bool IsMutable() const final { return true; }
+};
+
+// Base class for immutable SymbolTable implementations.
+class ConstSymbolTableImpl : public SymbolTableImplBase {
+ public:
+  std::unique_ptr<SymbolTableImplBase> Copy() const final;
+
+  int64 AddSymbol(SymbolType symbol, int64 key) final;
+  int64 AddSymbol(SymbolType symbol) final;
+  void RemoveSymbol(int64 key) final;
+  void SetName(const std::string &new_name) final;
+  void AddTable(const SymbolTable &table) final;
+  bool IsMutable() const final { return false; }
+};
+
+// Default SymbolTable implementation using DenseSymbolMap and std::map.
+// Provides the common text and binary format serialization.
+class SymbolTableImpl final : public MutableSymbolTableImpl {
  public:
   using SymbolType = DenseSymbolMap::KeyType;
 
@@ -127,16 +201,20 @@ class SymbolTableImpl {
         key_map_(impl.key_map_),
         check_sum_finalized_(false) {}
 
-  int64 AddSymbol(SymbolType symbol, int64 key);
+  std::unique_ptr<SymbolTableImplBase> Copy() const override {
+    return std::unique_ptr<SymbolTableImplBase>(new SymbolTableImpl(*this));
+  }
 
-  int64 AddSymbol(SymbolType symbol) {
+  int64 AddSymbol(SymbolType symbol, int64 key) override;
+
+  int64 AddSymbol(SymbolType symbol) override {
     return AddSymbol(symbol, available_key_);
   }
 
   // Removes the symbol with the given key. The removal is costly
   // (O(NumSymbols)) and may reduce the efficiency of Find() because of a
   // potentially reduced size of the dense key interval.
-  void RemoveSymbol(int64 key);
+  void RemoveSymbol(int64 key) override;
 
   static SymbolTableImpl *ReadText(
       std::istream &strm, const std::string &name,
@@ -145,56 +223,45 @@ class SymbolTableImpl {
   static SymbolTableImpl* Read(std::istream &strm,
                                const SymbolTableReadOptions &opts);
 
-  bool Write(std::ostream &strm) const;
+  bool Write(std::ostream &strm) const override;
 
-  // Return the string associated with the key. If the key is out of
+  // Returns the string associated with the key. If the key is out of
   // range (<0, >max), return an empty string.
-  std::string Find(int64 key) const {
-    int64 idx = key;
-    if (key < 0 || key >= dense_key_limit_) {
-      const auto it = key_map_.find(key);
-      if (it == key_map_.end()) return "";
-      idx = it->second;
-    }
-    if (idx < 0 || idx >= symbols_.Size()) return "";
-    return symbols_.GetSymbol(idx);
-  }
+  std::string Find(int64 key) const override;
 
   // Returns the key associated with the symbol; if the symbol
   // does not exists, returns kNoSymbol.
-  int64 Find(SymbolType symbol) const {
+  int64 Find(SymbolType symbol) const override {
     int64 idx = symbols_.Find(symbol);
     if (idx == kNoSymbol || idx < dense_key_limit_) return idx;
     return idx_key_[idx - dense_key_limit_];
   }
 
-  bool Member(int64 key) const { return !Find(key).empty(); }
-
-  bool Member(SymbolType symbol) const { return Find(symbol) != kNoSymbol; }
-
-  int64 GetNthKey(ssize_t pos) const {
+  int64 GetNthKey(ssize_t pos) const override {
     if (pos < 0 || pos >= symbols_.Size()) return kNoSymbol;
     if (pos < dense_key_limit_) return pos;
     return Find(symbols_.GetSymbol(pos));
   }
 
-  const std::string &Name() const { return name_; }
+  const std::string &Name() const override { return name_; }
 
-  void SetName(const std::string &new_name) { name_ = new_name; }
+  void SetName(const std::string &new_name) override { name_ = new_name; }
 
-  const std::string &CheckSum() const {
+  const std::string &CheckSum() const override {
     MaybeRecomputeCheckSum();
     return check_sum_string_;
   }
 
-  const std::string &LabeledCheckSum() const {
+  const std::string &LabeledCheckSum() const override {
     MaybeRecomputeCheckSum();
     return labeled_check_sum_string_;
   }
 
-  int64 AvailableKey() const { return available_key_; }
+  int64 AvailableKey() const override { return available_key_; }
 
-  size_t NumSymbols() const { return symbols_.Size(); }
+  size_t NumSymbols() const override { return symbols_.Size(); }
+
+  void ShrinkToFit();
 
  private:
   // Recomputes the checksums (both of them) if we've had changes since the last
@@ -248,28 +315,23 @@ class SymbolTable {
   static SymbolTable *ReadText(
       std::istream &strm, const std::string &name,
       const SymbolTableTextOptions &opts = SymbolTableTextOptions()) {
-    auto *impl = internal::SymbolTableImpl::ReadText(strm, name, opts);
+    std::shared_ptr<internal::SymbolTableImpl> impl(
+        internal::SymbolTableImpl::ReadText(strm, name, opts));
     return impl ? new SymbolTable(impl) : nullptr;
   }
 
   // Reads a text representation of the symbol table.
   static SymbolTable *ReadText(
-      const std::string &filename,
-      const SymbolTableTextOptions &opts = SymbolTableTextOptions()) {
-    std::ifstream strm(filename, std::ios_base::in);
-    if (!strm.good()) {
-      LOG(ERROR) << "SymbolTable::ReadText: Can't open file: " << filename;
-      return nullptr;
-    }
-    return ReadText(strm, filename, opts);
-  }
+      const std::string &source,
+      const SymbolTableTextOptions &opts = SymbolTableTextOptions());
 
   // WARNING: Reading via symbol table read options should not be used. This is
   // a temporary work-around.
   static SymbolTable* Read(std::istream &strm,
                            const SymbolTableReadOptions &opts) {
-    auto *impl = internal::SymbolTableImpl::Read(strm, opts);
-    return (impl) ? new SymbolTable(impl) : nullptr;
+    std::shared_ptr<internal::SymbolTableImpl> impl(
+        internal::SymbolTableImpl::Read(strm, opts));
+    return impl ? new SymbolTable(impl) : nullptr;
   }
 
   // Reads a binary dump of the symbol table from a stream.
@@ -280,140 +342,122 @@ class SymbolTable {
   }
 
   // Reads a binary dump of the symbol table.
-  static SymbolTable *Read(const std::string &filename) {
-    std::ifstream strm(filename,
-                            std::ios_base::in | std::ios_base::binary);
+  static SymbolTable *Read(const std::string &source) {
+    std::ifstream strm(source, std::ios_base::in | std::ios_base::binary);
     if (!strm.good()) {
-      LOG(ERROR) << "SymbolTable::Read: Can't open file: " << filename;
+      LOG(ERROR) << "SymbolTable::Read: Can't open file: " << source;
       return nullptr;
     }
-    return Read(strm, filename);
+    return Read(strm, source);
   }
 
-  // DERIVABLE INTERFACE
-
   // Creates a reference counted copy.
   virtual SymbolTable *Copy() const { return new SymbolTable(*this); }
 
+  // Adds another symbol table to this table. All keys will be offset by the
+  // current available key (highest key in the symbol table). Note string
+  // symbols with the same key will still have the same key after the symbol
+  // table has been merged, but a different value. Adding symbol tables do not
+  // result in changes in the base table.
+  void AddTable(const SymbolTable &table) {
+    MutateCheck();
+    impl_->AddTable(table);
+  }
+
   // Adds a symbol with given key to table. A symbol table also keeps track of
   // the last available key (highest key value in the symbol table).
-  virtual int64 AddSymbol(SymbolType symbol, int64 key) {
+  int64 AddSymbol(SymbolType symbol, int64 key) {
     MutateCheck();
     return impl_->AddSymbol(symbol, key);
   }
 
   // Adds a symbol to the table. The associated value key is automatically
   // assigned by the symbol table.
-  virtual int64 AddSymbol(SymbolType symbol) {
+  int64 AddSymbol(SymbolType symbol) {
     MutateCheck();
     return impl_->AddSymbol(symbol);
   }
 
-  // Adds another symbol table to this table. All key values will be offset
-  // by the current available key (highest key value in the symbol table).
-  // Note string symbols with the same key value will still have the same
-  // key value after the symbol table has been merged, but a different
-  // value. Adding symbol tables do not result in changes in the base table.
-  virtual void AddTable(const SymbolTable &table);
-
   // Returns the current available key (i.e., highest key + 1) in the symbol
   // table.
-  virtual int64 AvailableKey() const { return impl_->AvailableKey(); }
+  int64 AvailableKey() const { return impl_->AvailableKey(); }
 
   // Return the label-agnostic MD5 check-sum for this table. All new symbols
   // added to the table will result in an updated checksum. Deprecated.
-  virtual const std::string &CheckSum() const { return impl_->CheckSum(); }
+  const std::string &CheckSum() const { return impl_->CheckSum(); }
 
-  virtual int64 GetNthKey(ssize_t pos) const { return impl_->GetNthKey(pos); }
+  int64 GetNthKey(ssize_t pos) const { return impl_->GetNthKey(pos); }
 
   // Returns the string associated with the key; if the key is out of
   // range (<0, >max), returns an empty string.
-  virtual std::string Find(int64 key) const { return impl_->Find(key); }
+  std::string Find(int64 key) const { return impl_->Find(key); }
 
   // Returns the key associated with the symbol; if the symbol does not exist,
   // kNoSymbol is returned.
-  virtual int64 Find(SymbolType symbol) const { return impl_->Find(symbol); }
+  int64 Find(SymbolType symbol) const { return impl_->Find(symbol); }
 
   // Same as CheckSum(), but returns an label-dependent version.
-  virtual const std::string &LabeledCheckSum() const {
+  const std::string &LabeledCheckSum() const {
     return impl_->LabeledCheckSum();
   }
 
-  virtual bool Member(int64 key) const { return impl_->Member(key); }
+  bool Member(int64 key) const { return impl_->Member(key); }
 
-  virtual bool Member(SymbolType symbol) const { return impl_->Member(symbol); }
+  bool Member(SymbolType symbol) const { return impl_->Member(symbol); }
 
   // Returns the name of the symbol table.
-  virtual const std::string &Name() const { return impl_->Name(); }
+  const std::string &Name() const { return impl_->Name(); }
 
   // Returns the current number of symbols in table (not necessarily equal to
   // AvailableKey()).
-  virtual size_t NumSymbols() const { return impl_->NumSymbols(); }
+  size_t NumSymbols() const { return impl_->NumSymbols(); }
 
-  virtual void RemoveSymbol(int64 key) {
+  void RemoveSymbol(int64 key) {
     MutateCheck();
     return impl_->RemoveSymbol(key);
   }
 
   // Sets the name of the symbol table.
-  virtual void SetName(const std::string &new_name) {
+  void SetName(const std::string &new_name) {
     MutateCheck();
     impl_->SetName(new_name);
   }
 
-  virtual bool Write(std::ostream &strm) const { return impl_->Write(strm); }
-
-  virtual bool Write(const std::string &filename) const {
-    if (!filename.empty()) {
-      std::ofstream strm(filename,
-                               std::ios_base::out | std::ios_base::binary);
-      if (!strm) {
-        LOG(ERROR) << "SymbolTable::Write: Can't open file: " << filename;
-        return false;
-      }
-      if (!Write(strm)) {
-        LOG(ERROR) << "SymbolTable::Write: Write failed: " << filename;
-        return false;
-      }
-      return true;
-    } else {
-      return Write(std::cout);
-    }
+  bool Write(std::ostream &strm) const { return impl_->Write(strm); }
+
+  bool Write(const std::string &source) const;
+
+  // Dumps a text representation of the symbol table via a stream.
+  bool WriteText(std::ostream &strm, const SymbolTableTextOptions &opts =
+                                         SymbolTableTextOptions()) const;
+
+  // Dumps a text representation of the symbol table.
+  bool WriteText(const std::string &source) const;
+
+ protected:
+  explicit SymbolTable(std::shared_ptr<internal::SymbolTableImplBase> impl)
+      : impl_(impl) {}
+
+  template <class T = internal::SymbolTableImplBase>
+  const T *Impl() const {
+    return static_cast<const T *>(impl_.get());
   }
 
-  // Dump a text representation of the symbol table via a stream.
-  virtual bool WriteText(std::ostream &strm,
-      const SymbolTableTextOptions &opts = SymbolTableTextOptions()) const;
-
-  // Dump a text representation of the symbol table.
-  virtual bool WriteText(const std::string &filename) const {
-    if (!filename.empty()) {
-      std::ofstream strm(filename);
-      if (!strm) {
-        LOG(ERROR) << "SymbolTable::WriteText: Can't open file: " << filename;
-        return false;
-      }
-      if (!WriteText(strm)) {
-        LOG(ERROR) << "SymbolTable::WriteText: Write failed: " << filename;
-        return false;
-      }
-      return true;
-    } else {
-      return WriteText(std::cout);
-    }
+  template <class T = internal::SymbolTableImplBase>
+  T *MutableImpl() {
+    MutateCheck();
+    return static_cast<T *>(impl_.get());
   }
 
  private:
-  explicit SymbolTable(internal::SymbolTableImpl *impl) : impl_(impl) {}
-
   void MutateCheck() {
-    if (!impl_.unique()) impl_.reset(new internal::SymbolTableImpl(*impl_));
+    if (impl_.unique() || !impl_->IsMutable()) return;
+    std::unique_ptr<internal::SymbolTableImplBase> copy = impl_->Copy();
+    CHECK(copy != nullptr);
+    impl_ = std::move(copy);
   }
 
-  const internal::SymbolTableImpl *Impl() const { return impl_.get(); }
-
- private:
-  std::shared_ptr<internal::SymbolTableImpl> impl_;
+  std::shared_ptr<internal::SymbolTableImplBase> impl_;
 };
 
 // Iterator class for symbols in a symbol table.
index 4c5854a..e528da6 100644 (file)
@@ -7,7 +7,6 @@
 #define FST_TEST_ALGO_TEST_H_
 
 #include <fst/log.h>
-
 #include <fst/fstlib.h>
 #include <fst/test/rand-fst.h>
 
@@ -51,8 +50,8 @@ void LookAheadCompose(const Fst<Arc> &ifst1, const Fst<Arc> &ifst2,
 }
 
 // Specialized and epsilon olabel acyclic - lookahead.
-void LookAheadCompose(const Fst<StdArc> &ifst1, const Fst<StdArc> &ifst2,
-                      MutableFst<StdArc> *ofst) {
+inline void LookAheadCompose(const Fst<StdArc> &ifst1, const Fst<StdArc> &ifst2,
+                             MutableFst<StdArc> *ofst) {
   std::vector<StdArc::StateId> order;
   bool acyclic;
   TopOrderVisitor<StdArc> visitor(&order, &acyclic);
@@ -72,9 +71,9 @@ void LookAheadCompose(const Fst<StdArc> &ifst1, const Fst<StdArc> &ifst2,
 template <class Arc, class WeightGenerator>
 class WeightedTester {
  public:
-  typedef typename Arc::Label Label;
-  typedef typename Arc::StateId StateId;
-  typedef typename Arc::Weight Weight;
+  using Label = typename Arc::Label;
+  using StateId = typename Arc::StateId;
+  using Weight = typename Arc::Weight;
 
   WeightedTester(time_t seed, const Fst<Arc> &zero_fst, const Fst<Arc> &one_fst,
                  const Fst<Arc> &univ_fst, WeightGenerator *weight_generator)
@@ -512,7 +511,7 @@ class WeightedTester {
 
     {
       VLOG(1) << "Check all epsilon filters leads to equivalent results.";
-      typedef Matcher<Fst<Arc>> M;
+      using M = Matcher<Fst<Arc>>;
       ComposeFst<Arc> C1(S1, S2);
       ComposeFst<Arc> C2(
           S1, S2, ComposeFstOptions<Arc, M, AltSequenceComposeFilter<M>>());
@@ -1025,10 +1024,10 @@ class UnweightedTester {
 template <>
 class UnweightedTester<StdArc> {
  public:
-  typedef StdArc Arc;
-  typedef Arc::Label Label;
-  typedef Arc::StateId StateId;
-  typedef Arc::Weight Weight;
+  using Arc = StdArc;
+  using Label = Arc::Label;
+  using StateId = Arc::StateId;
+  using Weight = Arc::Weight;
 
   UnweightedTester(const Fst<Arc> &zero_fsa, const Fst<Arc> &one_fsa,
                    const Fst<Arc> &univ_fsa)
@@ -1287,9 +1286,9 @@ class UnweightedTester<StdArc> {
 template <class Arc, class WeightGenerator>
 class AlgoTester {
  public:
-  typedef typename Arc::Label Label;
-  typedef typename Arc::StateId StateId;
-  typedef typename Arc::Weight Weight;
+  using Label = typename Arc::Label;
+  using StateId = typename Arc::StateId;
+  using Weight = typename Arc::Weight;
 
   AlgoTester(WeightGenerator generator, int seed)
       : weight_generator_(generator) {
diff --git a/src/include/fst/test/compactors.h b/src/include/fst/test/compactors.h
new file mode 100644 (file)
index 0000000..e259acf
--- /dev/null
@@ -0,0 +1,148 @@
+#ifndef FST_TEST_COMPACTORS_H_
+#define FST_TEST_COMPACTORS_H_
+
+// See www.openfst.org for extensive documentation on this weighted
+// finite-state transducer library.
+//
+// Compactors for use in tests.  See compact-fst.h.
+
+#include <type_traits>
+
+#include <fst/arc.h>
+#include <fst/fst.h>
+#include <fst/vector-fst.h>
+
+namespace fst {
+
+// A user-defined compactor for test FST.
+// Stores all Arc components as a tuple.
+template <class A>
+class TrivialArcCompactor {
+ public:
+  using Arc = A;
+  using Label = typename A::Label;
+  using StateId = typename A::StateId;
+  using Weight = typename A::Weight;
+  // We use ArcTpl, which is trivially copyable if Weight is.
+  static_assert(std::is_trivially_copyable<Weight>::value,
+                "Weight must be trivially copyable.");
+  using Element = ArcTpl<Weight>;
+  static_assert(std::is_trivially_copyable<Element>::value,
+                "ArcTpl should be trivially copyable; someone broke it.");
+
+  Element Compact(StateId s, const A &arc) const {
+    return Element(arc.ilabel, arc.olabel, arc.weight, arc.nextstate);
+  }
+
+  Arc Expand(StateId s, const Element &e, uint32 f = kArcValueFlags) const {
+    return Arc(e.ilabel, e.olabel, e.weight, e.nextstate);
+  }
+
+  ssize_t Size() const { return -1; }
+
+  uint64 Properties() const { return 0ULL; }
+
+  bool Compatible(const Fst<A> &fst) const { return true; }
+
+  static const std::string &Type() {
+    static const std::string *const type =
+        new std::string("trival_arc_compactor_" + Arc::Type());
+    return *type;
+  }
+
+  bool Write(std::ostream &strm) const { return true; }
+
+  static TrivialArcCompactor *Read(std::istream &strm) {
+    return new TrivialArcCompactor;
+  }
+};
+
+// A user-defined arc compactor for test FST.
+// Doesn't actually do any compacting, but exercises the Compactor interface.
+template <class A>
+class TrivialCompactor {
+ public:
+  using Arc = A;
+  using StateId = typename Arc::StateId;
+  using Weight = typename Arc::Weight;
+
+  TrivialCompactor() { CHECK(false); }
+
+  // Constructor from the Fst to be compacted.  If compactor is present,
+  // only optional state should be copied from it.
+  explicit TrivialCompactor(const Fst<Arc> &fst,
+                            std::shared_ptr<TrivialCompactor> = nullptr)
+      : fst_(fst.Copy()) {}
+
+  // Copy constructor.  Must make a thread-safe copy suitable for use by
+  // by Fst::Copy(/*safe=*/true).
+  TrivialCompactor(const TrivialCompactor &compactor)
+      : fst_(compactor.fst_->Copy(/*safe=*/true)) {}
+
+  StateId Start() const { return fst_->Start(); }
+  StateId NumStates() const { return CountStates(*fst_); }
+  size_t NumArcs() const { return CountArcs(*fst_); }
+
+  // Accessor class for state attributes.
+  class State {
+   public:
+    State() = default;
+    State(const TrivialCompactor *c, StateId s)
+        : c_(c),
+          s_(s),
+          i_(fst::make_unique<ArcIterator<Fst<Arc>>>(*c->fst_, s)) {}
+    StateId GetStateId() const { return s_; }
+    Weight Final() const { return c_->fst_->Final(s_); }
+    size_t NumArcs() const { return c_->fst_->NumArcs(s_); }
+    Arc GetArc(size_t i, uint32 f) const {
+      i_->Seek(i);
+      return i_->Value();
+    }
+
+   private:
+    const TrivialCompactor *c_ = nullptr;
+    StateId s_ = kNoStateId;
+    std::unique_ptr<ArcIterator<Fst<Arc>>> i_;
+  };
+
+  void SetState(StateId s, State *state) { *state = State(this, s); }
+
+  template <typename Arc>
+  bool IsCompatible(const Fst<Arc> &fst) const {
+    return std::is_same<Arc, A>::value;
+  }
+
+  uint64 Properties(uint64 props) const { return props; }
+
+  static const std::string &Type() {
+    static const std::string *const type =
+        new std::string("trivial_compactor_" + Arc::Type());
+    return *type;
+  }
+
+  bool Error() const { return fst_->Properties(kError, /*test=*/false); }
+
+  bool Write(std::ostream &strm, const FstWriteOptions &opts) const {
+    WriteType(strm, Type());
+    // Write as a VectorFst.
+    return VectorFst<Arc>::WriteFst(*fst_, strm, opts);
+  }
+
+  static TrivialCompactor *Read(std::istream &strm, FstReadOptions opts,
+                                const FstHeader &hdr) {
+    std::string type;
+    ReadType(strm, &type);
+    if (type != Type()) return nullptr;
+    opts.header = nullptr;
+    auto fst = fst::WrapUnique(VectorFst<Arc>::Read(strm, opts));
+    if (fst == nullptr) return nullptr;
+    return new TrivialCompactor(*fst);
+  }
+
+ private:
+  std::unique_ptr<Fst<Arc>> fst_;
+};
+
+}  // namespace fst
+
+#endif  // FST_TEST_COMPACTORS_H_
index 997c241..6184c4c 100644 (file)
@@ -26,33 +26,33 @@ namespace fst {
 template <class F>
 class FstTester {
  public:
-  typedef typename F::Arc Arc;
-  typedef typename Arc::StateId StateId;
-  typedef typename Arc::Weight Weight;
-  typedef typename Arc::Label Label;
+  using Arc = typename F::Arc;
+  using StateId = typename Arc::StateId;
+  using Weight = typename Arc::Weight;
+  using Label = typename Arc::Label;
 
-  FstTester() {
+  explicit FstTester(size_t num_states = 128, bool weighted = true)
+      : num_states_(num_states), weighted_(weighted) {
     VectorFst<Arc> vfst;
-    InitFst(&vfst, 128);
+    InitFst(&vfst, num_states);
     testfst_ = new F(vfst);
   }
 
-  explicit FstTester(F *testfst) : testfst_(testfst) {}
-
   ~FstTester() { delete testfst_; }
 
   // This verifies the contents described in InitFst() using
   // methods defined in a generic Fst.
   template <class G>
   void TestBase(const G &fst) const {
-    CHECK(Verify(fst));
-    CHECK_EQ(fst.Start(), 0);
     StateId ns = 0;
     StateIterator<G> siter(fst);
     Matcher<G> matcher(fst, MATCH_INPUT);
     MatchType match_type = matcher.Type(true);
+    bool has_states = false;
     for (; !siter.Done(); siter.Next()) {
+      has_states = true;
     }
+    CHECK_EQ(fst.Start(), has_states ? 0 : kNoStateId);
     for (siter.Reset(); !siter.Done(); siter.Next()) {
       StateId s = siter.Value();
       matcher.SetState(s);
@@ -67,25 +67,31 @@ class FstTester {
         CHECK_EQ(arc.ilabel, na);
         CHECK_EQ(arc.olabel, 0);
         CHECK_EQ(arc.weight, NthWeight(na));
-        CHECK_EQ(arc.nextstate, s);
+        if (na == ns + 1) {
+          CHECK_EQ(arc.nextstate, s == num_states_ - 1 ? 0 : s + 1);
+        } else {
+          CHECK_EQ(arc.nextstate, s);
+        }
         if (match_type == MATCH_INPUT) {
           CHECK(matcher.Find(arc.ilabel));
           CHECK_EQ(matcher.Value().ilabel, arc.ilabel);
         }
       }
-      CHECK_EQ(na, s);
+      CHECK_EQ(na, s + 1);
       CHECK_EQ(na, aiter.Position());
-      CHECK_EQ(fst.NumArcs(s), s);
+      CHECK_EQ(fst.NumArcs(s), s + 1);
       CHECK_EQ(fst.NumInputEpsilons(s), 0);
-      CHECK_EQ(fst.NumOutputEpsilons(s), s);
-      CHECK(!matcher.Find(s + 1));     // out-of-range
-      CHECK(!matcher.Find(kNoLabel));  // no explicit epsilons
+      CHECK_EQ(fst.NumOutputEpsilons(s), s + 1);
+      CHECK(!matcher.Find(s + 2));     // out-of-range
+      CHECK(!matcher.Find(kNoLabel));  // no explicit input epsilons
       CHECK(matcher.Find(0));
       CHECK_EQ(matcher.Value().ilabel, kNoLabel);  // implicit epsilon loop
       ++ns;
     }
-    CHECK(fst.Properties(kNotAcceptor, true));
-    CHECK(fst.Properties(kOEpsilons, true));
+    CHECK_EQ(num_states_, ns);
+    CHECK(Verify(fst));
+    CHECK(fst.Properties(ns > 0 ? kNotAcceptor : kAcceptor, true));
+    CHECK(fst.Properties(ns > 0 ? kOEpsilons : kNoOEpsilons, true));
   }
 
   void TestBase() const { TestBase(*testfst_); }
@@ -93,6 +99,7 @@ class FstTester {
   // This verifies methods specfic to an ExpandedFst.
   template <class G>
   void TestExpanded(const G &fst) const {
+    CHECK_EQ(fst.NumStates(), num_states_);
     StateId ns = 0;
     for (StateIterator<G> siter(fst); !siter.Done(); siter.Next()) {
       ++ns;
@@ -145,27 +152,27 @@ class FstTester {
 
   void TestMutable() { TestMutable(testfst_); }
 
-  // This verifies the copy methods.
+  // This verifies operator=
   template <class G>
-  void TestAssign(G *fst) const {
+  void TestAssign(const G &fst) const {
     // Assignment from G
     G afst1;
-    afst1 = *fst;
-    CHECK(Equal(*fst, afst1));
+    afst1 = fst;
+    CHECK(Equal(fst, afst1));
 
     // Assignment from Fst
     G afst2;
-    afst2 = *static_cast<const Fst<Arc> *>(fst);
-    CHECK(Equal(*fst, afst2));
+    afst2 = static_cast<const Fst<Arc> &>(fst);
+    CHECK(Equal(fst, afst2));
 
     // Assignment from self
     afst2.operator=(afst2);
-    CHECK(Equal(*fst, afst2));
+    CHECK(Equal(fst, afst2));
   }
 
-  void TestAssign() { TestAssign(testfst_); }
+  void TestAssign() { TestAssign(*testfst_); }
 
-  // This verifies the copy methods.
+  // This verifies the copy constructor and Copy method.
   template <class G>
   void TestCopy(const G &fst) const {
     // Copy from G
@@ -281,15 +288,20 @@ class FstTester {
   // (II) Start() = 0
   // (III) Final(s) =  NthWeight(s)
   // (IV) For state s:
-  //     (a) NumArcs(s) == s
-  //     (b) For ith arc of s:
+  //     (a) NumArcs(s) == s + 1
+  //     (b) For ith arc (i: 1 to s) of s:
   //         (1) ilabel = i
   //         (2) olabel = 0
   //         (3) weight = NthWeight(i)
   //         (4) nextstate = s
+  //     (c) s+1st arc of s:
+  //         (1) ilabel = s + 1
+  //         (2) olabel = 0
+  //         (3) weight = NthWeight(s + 1)
+  //         (4) nextstate = s + 1 if s < nstates - 1
+  //                         0 if s == nstates - 1
   void InitFst(MutableFst<Arc> *fst, size_t nstates) const {
     fst->DeleteStates();
-    CHECK_GT(nstates, 0);
 
     for (StateId s = 0; s < nstates; ++s) {
       fst->AddState();
@@ -298,18 +310,24 @@ class FstTester {
         Arc arc(i, 0, NthWeight(i), s);
         fst->AddArc(s, arc);
       }
+      fst->AddArc(
+          s, Arc(s + 1, 0, NthWeight(s + 1), s == nstates - 1 ? 0 : s + 1));
     }
 
-    fst->SetStart(0);
+    if (nstates > 0) fst->SetStart(0);
   }
 
-  // Generates One() + ... + One() (n times)
+  // Generates One() + ... + One() (n times) if weighted_,
+  // otherwise One().
   Weight NthWeight(int n) const {
+    if (!weighted_) return Weight::One();
     Weight w = Weight::Zero();
     for (int i = 0; i < n; ++i) w = Plus(w, Weight::One());
     return w;
   }
 
+  size_t num_states_ = 0;
+  bool weighted_ = true;
   F *testfst_;  // what we're testing
 };
 
index f2f34c6..5c0cda6 100644 (file)
@@ -12,9 +12,9 @@ template <class Arc, class WeightGenerator>
 void RandFst(const int num_random_states, const int num_random_arcs,
              const int num_random_labels, const float acyclic_prob,
              WeightGenerator *weight_generator, MutableFst<Arc> *fst) {
-  typedef typename Arc::Label Label;
-  typedef typename Arc::StateId StateId;
-  typedef typename Arc::Weight Weight;
+  using Label = typename Arc::Label;
+  using StateId = typename Arc::StateId;
+  using Weight = typename Arc::Weight;
 
   // Determines direction of the arcs wrt state numbering. This way we
   // can force acyclicity when desired.
index 6a35417..ff5bead 100644 (file)
@@ -20,7 +20,7 @@ namespace fst {
 template <class Weight, class WeightGenerator>
 class WeightTester {
  public:
-  WeightTester(WeightGenerator generator)
+  explicit WeightTester(WeightGenerator generator)
       : weight_generator_(std::move(generator)) {}
 
   void Test(int iterations, bool test_division = true) {
@@ -141,7 +141,7 @@ class WeightTester {
 
   // Tests reverse operation.
   void TestReverse(Weight w1, Weight w2) {
-    typedef typename Weight::ReverseWeight ReverseWeight;
+    using ReverseWeight = typename Weight::ReverseWeight;
 
     ReverseWeight rw1 = w1.Reverse();
     ReverseWeight rw2 = w2.Reverse();
index f3aec8a..25c7875 100644 (file)
@@ -10,6 +10,7 @@
 #include <utility>
 #include <vector>
 
+#include <fst/expanded-fst.h>
 #include <fst/mutable-fst.h>
 #include <fst/rational.h>
 
@@ -39,7 +40,8 @@ void Union(MutableFst<Arc> *fst1, const Fst<Arc> &fst2) {
     return;
   }
   const auto numstates1 = fst1->NumStates();
-  const bool initial_acyclic1 = fst1->Properties(kInitialAcyclic, true);
+  const bool initial_acyclic1 =
+      fst1->Properties(kInitialAcyclic, false) == kInitialAcyclic;
   const auto props1 = fst1->Properties(kFstProperties, false);
   const auto props2 = fst2.Properties(kFstProperties, false);
   const auto start2 = fst2.Start();
@@ -79,6 +81,15 @@ void Union(MutableFst<Arc> *fst1, const Fst<Arc> &fst2) {
   fst1->SetProperties(UnionProperties(props1, props2), kFstProperties);
 }
 
+// Same as the above but can handle arbitrarily many right-hand-side FSTs,
+// preallocating the states.
+template <class Arc>
+void Union(MutableFst<Arc> *fst1, const std::vector<const Fst<Arc> *> &fsts2) {
+  // We add 1 just in case fst1 has an initial cycle.
+  fst1->ReserveStates(1 + fst1->NumStates() + CountStates(fsts2));
+  for (const auto *fst2 : fsts2) Union(fst1, *fst2);
+}
+
 // Computes the union of two FSTs, modifying the RationalFst argument.
 template <class Arc>
 void Union(RationalFst<Arc> *fst1, const Fst<Arc> &fst2) {
index 38b3218..789c621 100644 (file)
@@ -176,14 +176,19 @@ inline std::ostream &WriteType(std::ostream &strm,  // NOLINT
 
 template <typename... T>
 std::ostream &WriteType(std::ostream &strm, const std::vector<T...> &c);
+
 template <typename... T>
 std::ostream &WriteType(std::ostream &strm, const std::list<T...> &c);
+
 template <typename... T>
 std::ostream &WriteType(std::ostream &strm, const std::set<T...> &c);
+
 template <typename... T>
 std::ostream &WriteType(std::ostream &strm, const std::map<T...> &c);
+
 template <typename... T>
 std::ostream &WriteType(std::ostream &strm, const std::unordered_map<T...> &c);
+
 template <typename... T>
 std::ostream &WriteType(std::ostream &strm, const std::unordered_set<T...> &c);
 
@@ -206,6 +211,7 @@ std::ostream &WriteContainer(std::ostream &strm, const C &c) {
   }
   return strm;
 }
+
 }  // namespace internal
 
 template <typename... T>
@@ -240,17 +246,18 @@ std::ostream &WriteType(std::ostream &strm, const std::unordered_set<T...> &c) {
 
 // Utilities for converting between int64 or Weight and string.
 
-int64 StrToInt64(const std::string &s, const std::string &src, size_t nline,
+int64 StrToInt64(const std::string &s, const std::string &source, size_t nline,
                  bool allow_negative, bool *error = nullptr);
 
 template <typename Weight>
-Weight StrToWeight(const std::string &s, const std::string &src, size_t nline) {
+Weight StrToWeight(const std::string &s, const std::string &source,
+                   size_t nline) {
   Weight w;
   std::istringstream strm(s);
   strm >> w;
   if (!strm) {
-    FSTERROR() << "StrToWeight: Bad weight = \"" << s << "\", source = " << src
-               << ", line = " << nline;
+    FSTERROR() << "StrToWeight: Bad weight = \"" << s
+               << "\", source = " << source << ", line = " << nline;
     return Weight::NoWeight();
   }
   return w;
@@ -264,19 +271,19 @@ void WeightToStr(Weight w, std::string *s) {
   s->append(strm.str().data(), strm.str().size());
 }
 
-// Utilities for reading/writing integer pairs (typically labels)
+// Utilities for reading/writing integer pairs (typically labels).
 
 // Modifies line using a vector of pointers to a buffer beginning with line.
 void SplitString(char *line, const char *delim, std::vector<char *> *vec,
                  bool omit_empty_strings);
 
 template <typename I>
-bool ReadIntPairs(const std::string &filename,
+bool ReadIntPairs(const std::string &source,
                   std::vector<std::pair<I, I>> *pairs,
                   bool allow_negative = false) {
-  std::ifstream strm(filename, std::ios_base::in);
+  std::ifstream strm(source, std::ios_base::in);
   if (!strm) {
-    LOG(ERROR) << "ReadIntPairs: Can't open file: " << filename;
+    LOG(ERROR) << "ReadIntPairs: Can't open file: " << source;
     return false;
   }
   const int kLineLen = 8096;
@@ -291,13 +298,13 @@ bool ReadIntPairs(const std::string &filename,
     if (col.empty() || col[0][0] == '\0' || col[0][0] == '#') continue;
     if (col.size() != 2) {
       LOG(ERROR) << "ReadIntPairs: Bad number of columns, "
-                 << "file = " << filename << ", line = " << nline;
+                 << "file = " << source << ", line = " << nline;
       return false;
     }
     bool err;
-    I i1 = StrToInt64(col[0], filename, nline, allow_negative, &err);
+    I i1 = StrToInt64(col[0], source, nline, allow_negative, &err);
     if (err) return false;
-    I i2 = StrToInt64(col[1], filename, nline, allow_negative, &err);
+    I i2 = StrToInt64(col[1], source, nline, allow_negative, &err);
     if (err) return false;
     pairs->emplace_back(i1, i2);
   }
@@ -305,41 +312,36 @@ bool ReadIntPairs(const std::string &filename,
 }
 
 template <typename I>
-bool WriteIntPairs(const std::string &filename,
+bool WriteIntPairs(const std::string &source,
                    const std::vector<std::pair<I, I>> &pairs) {
-  std::ostream *strm = &std::cout;
-  if (!filename.empty()) {
-    strm = new std::ofstream(filename);
-    if (!*strm) {
-      LOG(ERROR) << "WriteIntPairs: Can't open file: " << filename;
+  std::ofstream fstrm;
+  if (!source.empty()) {
+    fstrm.open(source);
+    if (!fstrm) {
+      LOG(ERROR) << "WriteIntPairs: Can't open file: " << source;
       return false;
     }
   }
-  for (ssize_t n = 0; n < pairs.size(); ++n) {
-    *strm << pairs[n].first << "\t" << pairs[n].second << "\n";
-  }
-  if (!*strm) {
-    LOG(ERROR) << "WriteIntPairs: Write failed: "
-               << (filename.empty() ? "standard output" : filename);
-    return false;
+  std::ostream &ostrm = fstrm.is_open() ? fstrm : std::cout;
+  for (const auto &pair : pairs) {
+    ostrm << pair.first << "\t" << pair.second << "\n";
   }
-  if (strm != &std::cout) delete strm;
-  return true;
+  return !!ostrm;
 }
 
 // Utilities for reading/writing label pairs.
 
 template <typename Label>
-bool ReadLabelPairs(const std::string &filename,
+bool ReadLabelPairs(const std::string &source,
                     std::vector<std::pair<Label, Label>> *pairs,
                     bool allow_negative = false) {
-  return ReadIntPairs(filename, pairs, allow_negative);
+  return ReadIntPairs(source, pairs, allow_negative);
 }
 
 template <typename Label>
-bool WriteLabelPairs(const std::string &filename,
+bool WriteLabelPairs(const std::string &source,
                      const std::vector<std::pair<Label, Label>> &pairs) {
-  return WriteIntPairs(filename, pairs);
+  return WriteIntPairs(source, pairs);
 }
 
 // Utilities for converting a type name to a legal C symbol.
index 4f96c50..1af1f1b 100644 (file)
@@ -556,10 +556,10 @@ class VectorFst : public ImplToMutableFst<internal::VectorFstImpl<S>> {
                 : nullptr;
   }
 
-  // Read a VectorFst from a file, returning nullptr on error; empty filename
+  // Read a VectorFst from a file, returning nullptr on error; empty source
   // reads from standard input.
-  static VectorFst<Arc, State> *Read(const std::string &filename) {
-    auto *impl = ImplToExpandedFst<Impl, MutableFst<Arc>>::Read(filename);
+  static VectorFst<Arc, State> *Read(const std::string &source) {
+    auto *impl = ImplToExpandedFst<Impl, MutableFst<Arc>>::Read(source);
     return impl ? new VectorFst<Arc, State>(std::shared_ptr<Impl>(impl))
                 : nullptr;
   }
@@ -568,8 +568,8 @@ class VectorFst : public ImplToMutableFst<internal::VectorFstImpl<S>> {
     return WriteFst(*this, strm, opts);
   }
 
-  bool Write(const std::string &filename) const override {
-    return Fst<Arc>::WriteFile(filename);
+  bool Write(const std::string &source) const override {
+    return Fst<Arc>::WriteFile(source);
   }
 
   template <class FST>
@@ -710,9 +710,9 @@ class ArcIterator<VectorFst<Arc, State>> {
 
   size_t Position() const { return i_; }
 
-  constexpr uint32 Flags() const { return kArcValueFlags; }
+  constexpr uint8 Flags() const { return kArcValueFlags; }
 
-  void SetFlags(uint32, uint32) {}
+  void SetFlags(uint8, uint8) {}
 
  private:
   const Arc *arcs_;
@@ -784,9 +784,9 @@ class MutableArcIterator<VectorFst<Arc, State>>
                     kNoOEpsilons | kWeighted | kUnweighted;
   }
 
-  uint32 Flags() const final { return kArcValueFlags; }
+  uint8 Flags() const final { return kArcValueFlags; }
 
-  void SetFlags(uint32, uint32) final {}
+  void SetFlags(uint8, uint8) final {}
 
  private:
   State *state_;
index 27f0f6c..1562581 100644 (file)
@@ -1,8 +1,8 @@
 AM_CPPFLAGS = -I$(srcdir)/../include $(ICU_CPPFLAGS)
 
 lib_LTLIBRARIES = libfst.la
-libfst_la_SOURCES = compat.cc flags.cc fst.cc fst-types.cc mapped-file.cc \
-                    properties.cc symbol-table.cc symbol-table-ops.cc \
-                    weight.cc util.cc
+libfst_la_SOURCES = compat.cc encode.cc flags.cc fst.cc fst-types.cc \
+                    mapped-file.cc properties.cc symbol-table.cc \
+                    symbol-table-ops.cc weight.cc util.cc
 libfst_la_LDFLAGS = -version-info 17:0:0
 libfst_la_LIBADD = $(DL_LIBS)
index 2a85d60..38a101e 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -90,7 +90,7 @@ build_triplet = @build@
 host_triplet = @host@
 subdir = src/lib
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_python_devel.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
        $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
@@ -133,8 +133,8 @@ am__installdirs = "$(DESTDIR)$(libdir)"
 LTLIBRARIES = $(lib_LTLIBRARIES)
 am__DEPENDENCIES_1 =
 libfst_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
-am_libfst_la_OBJECTS = compat.lo flags.lo fst.lo fst-types.lo \
-       mapped-file.lo properties.lo symbol-table.lo \
+am_libfst_la_OBJECTS = compat.lo encode.lo flags.lo fst.lo \
+       fst-types.lo mapped-file.lo properties.lo symbol-table.lo \
        symbol-table-ops.lo weight.lo util.lo
 libfst_la_OBJECTS = $(am_libfst_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
@@ -158,7 +158,13 @@ am__v_at_0 = @
 am__v_at_1 = 
 DEFAULT_INCLUDES = 
 depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/compat.Plo ./$(DEPDIR)/encode.Plo \
+       ./$(DEPDIR)/flags.Plo ./$(DEPDIR)/fst-types.Plo \
+       ./$(DEPDIR)/fst.Plo ./$(DEPDIR)/mapped-file.Plo \
+       ./$(DEPDIR)/properties.Plo ./$(DEPDIR)/symbol-table-ops.Plo \
+       ./$(DEPDIR)/symbol-table.Plo ./$(DEPDIR)/util.Plo \
+       ./$(DEPDIR)/weight.Plo
 am__mv = mv -f
 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
        $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
@@ -273,7 +279,7 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
@@ -345,9 +351,9 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 AM_CPPFLAGS = -I$(srcdir)/../include $(ICU_CPPFLAGS)
 lib_LTLIBRARIES = libfst.la
-libfst_la_SOURCES = compat.cc flags.cc fst.cc fst-types.cc mapped-file.cc \
-                    properties.cc symbol-table.cc symbol-table-ops.cc \
-                    weight.cc util.cc
+libfst_la_SOURCES = compat.cc encode.cc flags.cc fst.cc fst-types.cc \
+                    mapped-file.cc properties.cc symbol-table.cc \
+                    symbol-table-ops.cc weight.cc util.cc
 
 libfst_la_LDFLAGS = -version-info 17:0:0
 libfst_la_LIBADD = $(DL_LIBS)
@@ -372,8 +378,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
          *config.status*) \
            cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
          *) \
-           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
        esac;
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@@ -429,16 +435,23 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compat.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flags.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fst-types.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fst.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mapped-file.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/properties.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symbol-table-ops.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symbol-table.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/weight.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compat.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/encode.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flags.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fst-types.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fst.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mapped-file.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/properties.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symbol-table-ops.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symbol-table.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/weight.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+       @$(MKDIR_P) $(@D)
+       @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
 
 .cc.o:
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -522,7 +535,10 @@ cscopelist-am: $(am__tagged_files)
 distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
-distdir: $(DISTFILES)
+distdir: $(BUILT_SOURCES)
+       $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
        @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        list='$(DISTFILES)'; \
@@ -595,7 +611,17 @@ clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
        mostlyclean-am
 
 distclean: distclean-am
-       -rm -rf ./$(DEPDIR)
+               -rm -f ./$(DEPDIR)/compat.Plo
+       -rm -f ./$(DEPDIR)/encode.Plo
+       -rm -f ./$(DEPDIR)/flags.Plo
+       -rm -f ./$(DEPDIR)/fst-types.Plo
+       -rm -f ./$(DEPDIR)/fst.Plo
+       -rm -f ./$(DEPDIR)/mapped-file.Plo
+       -rm -f ./$(DEPDIR)/properties.Plo
+       -rm -f ./$(DEPDIR)/symbol-table-ops.Plo
+       -rm -f ./$(DEPDIR)/symbol-table.Plo
+       -rm -f ./$(DEPDIR)/util.Plo
+       -rm -f ./$(DEPDIR)/weight.Plo
        -rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
        distclean-tags
@@ -641,7 +667,17 @@ install-ps-am:
 installcheck-am:
 
 maintainer-clean: maintainer-clean-am
-       -rm -rf ./$(DEPDIR)
+               -rm -f ./$(DEPDIR)/compat.Plo
+       -rm -f ./$(DEPDIR)/encode.Plo
+       -rm -f ./$(DEPDIR)/flags.Plo
+       -rm -f ./$(DEPDIR)/fst-types.Plo
+       -rm -f ./$(DEPDIR)/fst.Plo
+       -rm -f ./$(DEPDIR)/mapped-file.Plo
+       -rm -f ./$(DEPDIR)/properties.Plo
+       -rm -f ./$(DEPDIR)/symbol-table-ops.Plo
+       -rm -f ./$(DEPDIR)/symbol-table.Plo
+       -rm -f ./$(DEPDIR)/util.Plo
+       -rm -f ./$(DEPDIR)/weight.Plo
        -rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
@@ -662,9 +698,9 @@ uninstall-am: uninstall-libLTLIBRARIES
 
 .MAKE: install-am install-strip
 
-.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
-       clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \
-       ctags-am distclean distclean-compile distclean-generic \
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
+       clean-generic clean-libLTLIBRARIES clean-libtool cscopelist-am \
+       ctags ctags-am distclean distclean-compile distclean-generic \
        distclean-libtool distclean-tags distdir dvi dvi-am html \
        html-am info info-am install install-am install-data \
        install-data-am install-dvi install-dvi-am install-exec \
index 39e6e98..6695b2c 100644 (file)
 //
 // Google compatibility definitions.
 
+#include <fst/compat.h>
+
+#include <algorithm>
 #include <cstdlib>
 #include <iostream>
-
-#include <fst/compat.h>
+#include <numeric>
 
 void FailedNewHandler() {
   std::cerr << "Memory allocation failed" << std::endl;
   std::exit(1);
 }
+
+namespace fst {
+
+CheckSummer::CheckSummer() : count_(0) {
+  check_sum_.resize(kCheckSumLength, '\0');
+}
+
+void CheckSummer::Reset() {
+  count_ = 0;
+  for (int i = 0; i < kCheckSumLength; ++i) check_sum_[i] = '\0';
+}
+
+void CheckSummer::Update(void const *data, int size) {
+  const char *p = reinterpret_cast<const char *>(data);
+  for (int i = 0; i < size; ++i) {
+    check_sum_[(count_++) % kCheckSumLength] ^= p[i];
+  }
+}
+
+void CheckSummer::Update(std::string const &data) {
+  for (int i = 0; i < data.size(); ++i) {
+    check_sum_[(count_++) % kCheckSumLength] ^= data[i];
+  }
+}
+
+// String joining and splitting.
+
+namespace {
+
+// Computes size of joined string.
+size_t GetResultSize(const std::vector<std::string> &elements, size_t s_size) {
+  const auto lambda = [](size_t partial, const std::string &right) {
+    return partial + right.size();
+  };
+  return (std::accumulate(elements.begin(), elements.end(), 0, lambda) +
+          s_size * (elements.size() - 1));
+}
+
+}  // namespace
+
+// Joins a vector of strings on a given delimiter.
+
+std::string StringJoin(const std::vector<std::string> &elements,
+                       const std::string &delim) {
+  std::string result;
+  if (elements.empty()) return result;
+  size_t s_size = delim.size();
+  result.reserve(GetResultSize(elements, s_size));
+  auto it = elements.begin();
+  result.append(it->data(), it->size());
+  for (++it; it != elements.end(); ++it) {
+    result.append(delim.data(), s_size);
+    result.append(it->data(), it->size());
+  }
+  return result;
+}
+
+std::string StringJoin(const std::vector<std::string> &elements,
+                       const char *delim) {
+  const std::string str_delim(delim);
+  return StringJoin(elements, str_delim);
+}
+
+std::string StringJoin(const std::vector<std::string> &elements, char delim) {
+  const std::string str_delim{delim};
+  return StringJoin(elements, str_delim);
+}
+
+// Splits a string according to delimiter, skipping over consecutive
+// delimiters.
+
+std::vector<std::string> StringSplit(const std::string &full,
+                                     const std::string &delim) {
+  size_t prev = 0;
+  size_t found = full.find_first_of(delim);
+  size_t size = found - prev;
+  std::vector<std::string> result;
+  if (size > 0) result.push_back(full.substr(prev, size));
+  while (found != std::string::npos) {
+    prev = found + 1;
+    found = full.find_first_of(delim, prev);
+    size = found - prev;
+    if (size > 0) result.push_back(full.substr(prev, size));
+  }
+  return result;
+}
+
+std::vector<std::string> StringSplit(const std::string &full,
+                                     const char *delim) {
+  const std::string str_delim(delim);
+  return StringSplit(full, str_delim);
+}
+
+std::vector<std::string> StringSplit(const std::string &full, char delim) {
+  const std::string str_delim{delim};
+  return StringSplit(full, str_delim);
+}
+
+void StripTrailingAsciiWhitespace(std::string *full) {
+  const auto lambda = [](char ch) { return !std::isspace(ch); };
+  const auto pos = std::find_if(full->rbegin(), full->rend(), lambda).base();
+  full->erase(pos, full->end());
+}
+
+std::string StripTrailingAsciiWhitespace(const std::string &full) {
+  std::string copy(full);
+  StripTrailingAsciiWhitespace(&copy);
+  return copy;
+}
+
+}  // namespace fst
diff --git a/src/lib/encode.cc b/src/lib/encode.cc
new file mode 100644 (file)
index 0000000..fa130dd
--- /dev/null
@@ -0,0 +1,51 @@
+// See www.openfst.org for extensive documentation on this weighted
+// finite-state transducer library.
+//
+// Definitions for encode table header.
+
+#include <fst/encode.h>
+
+namespace fst {
+
+bool EncodeTableHeader::Read(std::istream &strm, const std::string &source) {
+  int32 magic_number;
+  ReadType(strm, &magic_number);
+  if (magic_number == internal::kEncodeMagicNumber) {
+    ReadType(strm, &arctype_);
+    ReadType(strm, &flags_);
+    ReadType(strm, &size_);
+  } else if (magic_number == internal::kEncodeDeprecatedMagicNumber) {
+    // TODO(b/141172858): deprecated, remove by 2020-01-01.
+    uint32 flags;
+    ReadType(strm, &flags);
+    flags_ = flags;
+    int64 size;
+    ReadType(strm, &size);
+    size_ = size;
+  } else {
+    LOG(ERROR) << "EncodeTableHeader::Read: Bad encode table header: "
+               << source;
+    return false;
+  }
+  if (!strm) {
+    LOG(ERROR) << "EncodeTableHeader::Read: Read failed: " << source;
+    return false;
+  }
+  return true;
+}
+
+bool EncodeTableHeader::Write(std::ostream &strm,
+                              const std::string &source) const {
+  WriteType(strm, internal::kEncodeMagicNumber);
+  WriteType(strm, arctype_);
+  WriteType(strm, flags_);
+  WriteType(strm, size_);
+  strm.flush();
+  if (!strm) {
+    LOG(ERROR) << "EncodeTableHeader::Write: Write failed: " << source;
+    return false;
+  }
+  return true;
+}
+
+}  // namespace fst
index cdcf1be..c602aad 100644 (file)
@@ -72,36 +72,36 @@ SymbolTable *CompactSymbolTable(const SymbolTable &syms) {
   return compact;
 }
 
-SymbolTable *FstReadSymbols(const std::string &filename, bool input_symbols) {
-  std::ifstream in(filename, std::ios_base::in | std::ios_base::binary);
+SymbolTable *FstReadSymbols(const std::string &source, bool input_symbols) {
+  std::ifstream in(source, std::ios_base::in | std::ios_base::binary);
   if (!in) {
-    LOG(ERROR) << "FstReadSymbols: Can't open file " << filename;
+    LOG(ERROR) << "FstReadSymbols: Can't open file " << source;
     return nullptr;
   }
   FstHeader hdr;
-  if (!hdr.Read(in, filename)) {
-    LOG(ERROR) << "FstReadSymbols: Couldn't read header from " << filename;
+  if (!hdr.Read(in, source)) {
+    LOG(ERROR) << "FstReadSymbols: Couldn't read header from " << source;
     return nullptr;
   }
   if (hdr.GetFlags() & FstHeader::HAS_ISYMBOLS) {
-    std::unique_ptr<SymbolTable> isymbols(SymbolTable::Read(in, filename));
+    std::unique_ptr<SymbolTable> isymbols(SymbolTable::Read(in, source));
     if (isymbols == nullptr) {
       LOG(ERROR) << "FstReadSymbols: Couldn't read input symbols from "
-                 << filename;
+                 << source;
       return nullptr;
     }
     if (input_symbols) return isymbols.release();
   }
   if (hdr.GetFlags() & FstHeader::HAS_OSYMBOLS) {
-    std::unique_ptr<SymbolTable> osymbols(SymbolTable::Read(in, filename));
+    std::unique_ptr<SymbolTable> osymbols(SymbolTable::Read(in, source));
     if (osymbols == nullptr) {
       LOG(ERROR) << "FstReadSymbols: Couldn't read output symbols from "
-                 << filename;
+                 << source;
       return nullptr;
     }
     if (!input_symbols) return osymbols.release();
   }
-  LOG(ERROR) << "FstReadSymbols: The file " << filename
+  LOG(ERROR) << "FstReadSymbols: The file " << source
              << " doesn't contain the requested symbols";
   return nullptr;
 }
index 2a659ba..785e17a 100644 (file)
@@ -30,24 +30,20 @@ const int kLineLen = 8096;
 // Identifies stream data as a symbol table (and its endianity).
 static constexpr int32 kSymbolTableMagicNumber = 2125658996;
 
-DenseSymbolMap::DenseSymbolMap()
-    : empty_(-1), buckets_(1 << 4), hash_mask_(buckets_.size() - 1) {
-  std::uninitialized_fill(buckets_.begin(), buckets_.end(), empty_);
-}
+constexpr int64 DenseSymbolMap::kEmptyBucket;
 
-DenseSymbolMap::DenseSymbolMap(const DenseSymbolMap &other)
-    : empty_(-1),
-      symbols_(other.symbols_),
-      buckets_(other.buckets_),
-      hash_mask_(other.hash_mask_) {}
+DenseSymbolMap::DenseSymbolMap()
+    : str_hash_(),
+      buckets_(1 << 4, kEmptyBucket),
+      hash_mask_(buckets_.size() - 1) {}
 
 std::pair<int64, bool> DenseSymbolMap::InsertOrFind(KeyType key) {
   static constexpr float kMaxOccupancyRatio = 0.75;  // Grows when 75% full.
   if (Size() >= kMaxOccupancyRatio * buckets_.size()) {
     Rehash(buckets_.size() * 2);
   }
-  size_t idx = str_hash_(key) & hash_mask_;
-  while (buckets_[idx] != empty_) {
+  size_t idx = GetHash(key);
+  while (buckets_[idx] != kEmptyBucket) {
     const auto stored_value = buckets_[idx];
     if (symbols_[stored_value] == key) return {stored_value, false};
     idx = (idx + 1) & hash_mask_;
@@ -60,7 +56,7 @@ std::pair<int64, bool> DenseSymbolMap::InsertOrFind(KeyType key) {
 
 int64 DenseSymbolMap::Find(KeyType key) const {
   size_t idx = str_hash_(key) & hash_mask_;
-  while (buckets_[idx] != empty_) {
+  while (buckets_[idx] != kEmptyBucket) {
     const auto stored_value = buckets_[idx];
     if (symbols_[stored_value] == key) return stored_value;
     idx = (idx + 1) & hash_mask_;
@@ -71,10 +67,10 @@ int64 DenseSymbolMap::Find(KeyType key) const {
 void DenseSymbolMap::Rehash(size_t num_buckets) {
   buckets_.resize(num_buckets);
   hash_mask_ = buckets_.size() - 1;
-  std::uninitialized_fill(buckets_.begin(), buckets_.end(), empty_);
+  std::fill(buckets_.begin(), buckets_.end(), kEmptyBucket);
   for (size_t i = 0; i < Size(); ++i) {
-    size_t idx = str_hash_(symbols_[i]) & hash_mask_;
-    while (buckets_[idx] != empty_) {
+    size_t idx = GetHash(symbols_[i]);
+    while (buckets_[idx] != kEmptyBucket) {
       idx = (idx + 1) & hash_mask_;
     }
     buckets_[idx] = i;
@@ -86,10 +82,46 @@ void DenseSymbolMap::RemoveSymbol(size_t idx) {
   Rehash(buckets_.size());
 }
 
+void DenseSymbolMap::ShrinkToFit() {
+  symbols_.shrink_to_fit();
+}
+
+void MutableSymbolTableImpl::AddTable(const SymbolTable &table) {
+  for (SymbolTableIterator iter(table); !iter.Done(); iter.Next()) {
+    AddSymbol(iter.Symbol());
+  }
+}
+
+std::unique_ptr<SymbolTableImplBase> ConstSymbolTableImpl::Copy() const {
+  LOG(FATAL) << "ConstSymbolTableImpl can't be copied";
+  return nullptr;
+}
+
+int64 ConstSymbolTableImpl::AddSymbol(SymbolType symbol, int64 key) {
+  LOG(FATAL) << "ConstSymbolTableImpl does not support AddSymbol";
+  return kNoSymbol;
+}
+
+int64 ConstSymbolTableImpl::AddSymbol(SymbolType symbol) {
+  return AddSymbol(symbol, kNoSymbol);
+}
+
+void ConstSymbolTableImpl::RemoveSymbol(int64 key) {
+  LOG(FATAL) << "ConstSymbolTableImpl does not support RemoveSymbol";
+}
+
+void ConstSymbolTableImpl::SetName(const std::string &new_name) {
+  LOG(FATAL) << "ConstSymbolTableImpl does not support SetName";
+}
+
+void ConstSymbolTableImpl::AddTable(const SymbolTable &table) {
+  LOG(FATAL) << "ConstSymbolTableImpl does not support AddTable";
+}
+
 SymbolTableImpl *SymbolTableImpl::ReadText(std::istream &strm,
-                                           const std::string &filename,
+                                           const std::string &source,
                                            const SymbolTableTextOptions &opts) {
-  std::unique_ptr<SymbolTableImpl> impl(new SymbolTableImpl(filename));
+  std::unique_ptr<SymbolTableImpl> impl(new SymbolTableImpl(source));
   int64 nline = 0;
   char line[kLineLen];
   while (!strm.getline(line, kLineLen).fail()) {
@@ -101,8 +133,8 @@ SymbolTableImpl *SymbolTableImpl::ReadText(std::istream &strm,
     if (col.size() != 2) {
       LOG(ERROR) << "SymbolTable::ReadText: Bad number of columns ("
                  << col.size() << "), "
-                 << "file = " << filename << ", line = " << nline << ":<"
-                 << line << ">";
+                 << "file = " << source << ", line = " << nline << ":<" << line
+                 << ">";
       return nullptr;
     }
     const char *symbol = col[0];
@@ -113,11 +145,12 @@ SymbolTableImpl *SymbolTableImpl::ReadText(std::istream &strm,
         key == kNoSymbol) {
       LOG(ERROR) << "SymbolTable::ReadText: Bad non-negative integer \""
                  << value << "\", "
-                 << "file = " << filename << ", line = " << nline;
+                 << "file = " << source << ", line = " << nline;
       return nullptr;
     }
     impl->AddSymbol(symbol, key);
   }
+  impl->ShrinkToFit();
   return impl.release();
 }
 
@@ -159,6 +192,17 @@ void SymbolTableImpl::MaybeRecomputeCheckSum() const {
   check_sum_finalized_ = true;
 }
 
+std::string SymbolTableImpl::Find(int64 key) const {
+  int64 idx = key;
+  if (key < 0 || key >= dense_key_limit_) {
+    const auto it = key_map_.find(key);
+    if (it == key_map_.end()) return "";
+    idx = it->second;
+  }
+  if (idx < 0 || idx >= symbols_.Size()) return "";
+  return symbols_.GetSymbol(idx);
+}
+
 int64 SymbolTableImpl::AddSymbol(SymbolType symbol, int64 key) {
   if (key == kNoSymbol) return key;
   const auto insert_key = symbols_.InsertOrFind(symbol);
@@ -224,8 +268,8 @@ void SymbolTableImpl::RemoveSymbol(const int64 key) {
   if (key == available_key_ - 1) available_key_ = key;
 }
 
-SymbolTableImpl *SymbolTableImpl::Read(
-    std::istream &strm, const SymbolTableReadOptions &) {
+SymbolTableImpl *SymbolTableImpl::Read(std::istream &strm,
+                                       const SymbolTableReadOptions &) {
   int32 magic_number = 0;
   ReadType(strm, &magic_number);
   if (strm.fail()) {
@@ -254,6 +298,7 @@ SymbolTableImpl *SymbolTableImpl::Read(
     }
     impl->AddSymbol(symbol, key);
   }
+  impl->ShrinkToFit();
   return impl.release();
 }
 
@@ -263,10 +308,13 @@ bool SymbolTableImpl::Write(std::ostream &strm) const {
   WriteType(strm, available_key_);
   const int64 size = symbols_.Size();
   WriteType(strm, size);
-  for (int64 i = 0; i < size; ++i) {
-    auto key = (i < dense_key_limit_) ? i : idx_key_[i - dense_key_limit_];
+  for (int64 i = 0; i < dense_key_limit_; ++i) {
     WriteType(strm, symbols_.GetSymbol(i));
-    WriteType(strm, key);
+    WriteType(strm, i);
+  }
+  for (const auto &p : key_map_) {
+    WriteType(strm, symbols_.GetSymbol(p.second));
+    WriteType(strm, p.first);
   }
   strm.flush();
   if (strm.fail()) {
@@ -276,12 +324,37 @@ bool SymbolTableImpl::Write(std::ostream &strm) const {
   return true;
 }
 
+void SymbolTableImpl::ShrinkToFit() {
+  symbols_.ShrinkToFit();
+}
+
 }  // namespace internal
 
-void SymbolTable::AddTable(const SymbolTable &table) {
-  MutateCheck();
-  for (SymbolTableIterator iter(table); !iter.Done(); iter.Next()) {
-    impl_->AddSymbol(iter.Symbol());
+SymbolTable *SymbolTable::ReadText(const std::string &source,
+                                   const SymbolTableTextOptions &opts) {
+  std::ifstream strm(source, std::ios_base::in);
+  if (!strm.good()) {
+    LOG(ERROR) << "SymbolTable::ReadText: Can't open file: " << source;
+    return nullptr;
+  }
+  return ReadText(strm, source, opts);
+}
+
+bool SymbolTable::Write(const std::string &source) const {
+  if (!source.empty()) {
+    std::ofstream strm(source,
+                             std::ios_base::out | std::ios_base::binary);
+    if (!strm) {
+      LOG(ERROR) << "SymbolTable::Write: Can't open file: " << source;
+      return false;
+    }
+    if (!Write(strm)) {
+      LOG(ERROR) << "SymbolTable::Write: Write failed: " << source;
+      return false;
+    }
+    return true;
+  } else {
+    return Write(std::cout);
   }
 }
 
@@ -305,6 +378,23 @@ bool SymbolTable::WriteText(std::ostream &strm,
   return true;
 }
 
+bool SymbolTable::WriteText(const std::string &source) const {
+  if (!source.empty()) {
+    std::ofstream strm(source);
+    if (!strm) {
+      LOG(ERROR) << "SymbolTable::WriteText: Can't open file: " << source;
+      return false;
+    }
+    if (!WriteText(strm, SymbolTableTextOptions())) {
+      LOG(ERROR) << "SymbolTable::WriteText: Write failed: " << source;
+      return false;
+    }
+    return true;
+  } else {
+    return WriteText(std::cout, SymbolTableTextOptions());
+  }
+}
+
 bool CompatSymbols(const SymbolTable *syms1, const SymbolTable *syms2,
                    bool warning) {
   // Flag can explicitly override this check.
index 00b8b5c..438c023 100644 (file)
@@ -33,7 +33,7 @@ void SplitString(char *full, const char *delim, std::vector<char *> *vec,
   }
 }
 
-int64 StrToInt64(const std::string &s, const std::string &src, size_t nline,
+int64 StrToInt64(const std::string &s, const std::string &source, size_t nline,
                  bool allow_negative, bool *error) {
   int64 n;
   const char *cs = s.c_str();
@@ -41,7 +41,7 @@ int64 StrToInt64(const std::string &s, const std::string &src, size_t nline,
   if (error) *error = false;
   n = strtoll(cs, &p, 10);
   if (p < cs + s.size() || (!allow_negative && n < 0)) {
-    FSTERROR() << "StrToInt64: Bad integer = " << s << "\", source = " << src
+    FSTERROR() << "StrToInt64: Bad integer = " << s << "\", source = " << source
                << ", line = " << nline;
     if (error) *error = true;
     return 0;
index 599c005..362b922 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -90,7 +90,7 @@ build_triplet = @build@
 host_triplet = @host@
 subdir = src/script
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_python_devel.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
        $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
@@ -184,7 +184,32 @@ am__v_at_0 = @
 am__v_at_1 = 
 DEFAULT_INCLUDES = 
 depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/arciterator-class.Plo \
+       ./$(DEPDIR)/arcsort.Plo ./$(DEPDIR)/closure.Plo \
+       ./$(DEPDIR)/compile.Plo ./$(DEPDIR)/compose.Plo \
+       ./$(DEPDIR)/concat.Plo ./$(DEPDIR)/connect.Plo \
+       ./$(DEPDIR)/convert.Plo ./$(DEPDIR)/decode.Plo \
+       ./$(DEPDIR)/determinize.Plo ./$(DEPDIR)/difference.Plo \
+       ./$(DEPDIR)/disambiguate.Plo ./$(DEPDIR)/draw.Plo \
+       ./$(DEPDIR)/encode.Plo ./$(DEPDIR)/encodemapper-class.Plo \
+       ./$(DEPDIR)/epsnormalize.Plo ./$(DEPDIR)/equal.Plo \
+       ./$(DEPDIR)/equivalent.Plo ./$(DEPDIR)/fst-class.Plo \
+       ./$(DEPDIR)/getters.Plo ./$(DEPDIR)/info-impl.Plo \
+       ./$(DEPDIR)/info.Plo ./$(DEPDIR)/intersect.Plo \
+       ./$(DEPDIR)/invert.Plo ./$(DEPDIR)/isomorphic.Plo \
+       ./$(DEPDIR)/map.Plo ./$(DEPDIR)/minimize.Plo \
+       ./$(DEPDIR)/print.Plo ./$(DEPDIR)/project.Plo \
+       ./$(DEPDIR)/prune.Plo ./$(DEPDIR)/push.Plo \
+       ./$(DEPDIR)/randequivalent.Plo ./$(DEPDIR)/randgen.Plo \
+       ./$(DEPDIR)/relabel.Plo ./$(DEPDIR)/replace.Plo \
+       ./$(DEPDIR)/reverse.Plo ./$(DEPDIR)/reweight.Plo \
+       ./$(DEPDIR)/rmepsilon.Plo ./$(DEPDIR)/shortest-distance.Plo \
+       ./$(DEPDIR)/shortest-path.Plo \
+       ./$(DEPDIR)/stateiterator-class.Plo \
+       ./$(DEPDIR)/synchronize.Plo ./$(DEPDIR)/text-io.Plo \
+       ./$(DEPDIR)/topsort.Plo ./$(DEPDIR)/union.Plo \
+       ./$(DEPDIR)/verify.Plo ./$(DEPDIR)/weight-class.Plo
 am__mv = mv -f
 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
        $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
@@ -299,7 +324,7 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
@@ -404,8 +429,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
          *config.status*) \
            cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
          *) \
-           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
        esac;
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@@ -461,53 +486,59 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arciterator-class.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arcsort.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/closure.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compile.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compose.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/concat.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connect.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/convert.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/decode.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/determinize.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/difference.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/disambiguate.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/draw.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/encode.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/encodemapper-class.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epsnormalize.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/equal.Plo@am__quote@
-@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@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isomorphic.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/map.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minimize.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/print.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/project.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prune.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/push.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/randequivalent.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/randgen.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/relabel.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/replace.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reverse.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reweight.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rmepsilon.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shortest-distance.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shortest-path.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stateiterator-class.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/synchronize.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/text-io.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/topsort.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/union.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verify.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/weight-class.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arciterator-class.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arcsort.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/closure.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compile.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compose.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/concat.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connect.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/convert.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/decode.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/determinize.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/difference.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/disambiguate.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/draw.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/encode.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/encodemapper-class.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epsnormalize.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/equal.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/equivalent.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fst-class.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getters.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/info-impl.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/info.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/intersect.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/invert.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isomorphic.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/map.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minimize.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/print.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/project.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prune.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/push.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/randequivalent.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/randgen.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/relabel.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/replace.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reverse.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reweight.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rmepsilon.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shortest-distance.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shortest-path.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stateiterator-class.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/synchronize.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/text-io.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/topsort.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/union.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verify.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/weight-class.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+       @$(MKDIR_P) $(@D)
+       @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
 
 .cc.o:
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -591,7 +622,10 @@ cscopelist-am: $(am__tagged_files)
 distclean-tags:
        -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
-distdir: $(DISTFILES)
+distdir: $(BUILT_SOURCES)
+       $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
        @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        list='$(DISTFILES)'; \
@@ -664,7 +698,53 @@ clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
        mostlyclean-am
 
 distclean: distclean-am
-       -rm -rf ./$(DEPDIR)
+               -rm -f ./$(DEPDIR)/arciterator-class.Plo
+       -rm -f ./$(DEPDIR)/arcsort.Plo
+       -rm -f ./$(DEPDIR)/closure.Plo
+       -rm -f ./$(DEPDIR)/compile.Plo
+       -rm -f ./$(DEPDIR)/compose.Plo
+       -rm -f ./$(DEPDIR)/concat.Plo
+       -rm -f ./$(DEPDIR)/connect.Plo
+       -rm -f ./$(DEPDIR)/convert.Plo
+       -rm -f ./$(DEPDIR)/decode.Plo
+       -rm -f ./$(DEPDIR)/determinize.Plo
+       -rm -f ./$(DEPDIR)/difference.Plo
+       -rm -f ./$(DEPDIR)/disambiguate.Plo
+       -rm -f ./$(DEPDIR)/draw.Plo
+       -rm -f ./$(DEPDIR)/encode.Plo
+       -rm -f ./$(DEPDIR)/encodemapper-class.Plo
+       -rm -f ./$(DEPDIR)/epsnormalize.Plo
+       -rm -f ./$(DEPDIR)/equal.Plo
+       -rm -f ./$(DEPDIR)/equivalent.Plo
+       -rm -f ./$(DEPDIR)/fst-class.Plo
+       -rm -f ./$(DEPDIR)/getters.Plo
+       -rm -f ./$(DEPDIR)/info-impl.Plo
+       -rm -f ./$(DEPDIR)/info.Plo
+       -rm -f ./$(DEPDIR)/intersect.Plo
+       -rm -f ./$(DEPDIR)/invert.Plo
+       -rm -f ./$(DEPDIR)/isomorphic.Plo
+       -rm -f ./$(DEPDIR)/map.Plo
+       -rm -f ./$(DEPDIR)/minimize.Plo
+       -rm -f ./$(DEPDIR)/print.Plo
+       -rm -f ./$(DEPDIR)/project.Plo
+       -rm -f ./$(DEPDIR)/prune.Plo
+       -rm -f ./$(DEPDIR)/push.Plo
+       -rm -f ./$(DEPDIR)/randequivalent.Plo
+       -rm -f ./$(DEPDIR)/randgen.Plo
+       -rm -f ./$(DEPDIR)/relabel.Plo
+       -rm -f ./$(DEPDIR)/replace.Plo
+       -rm -f ./$(DEPDIR)/reverse.Plo
+       -rm -f ./$(DEPDIR)/reweight.Plo
+       -rm -f ./$(DEPDIR)/rmepsilon.Plo
+       -rm -f ./$(DEPDIR)/shortest-distance.Plo
+       -rm -f ./$(DEPDIR)/shortest-path.Plo
+       -rm -f ./$(DEPDIR)/stateiterator-class.Plo
+       -rm -f ./$(DEPDIR)/synchronize.Plo
+       -rm -f ./$(DEPDIR)/text-io.Plo
+       -rm -f ./$(DEPDIR)/topsort.Plo
+       -rm -f ./$(DEPDIR)/union.Plo
+       -rm -f ./$(DEPDIR)/verify.Plo
+       -rm -f ./$(DEPDIR)/weight-class.Plo
        -rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
        distclean-tags
@@ -710,7 +790,53 @@ install-ps-am:
 installcheck-am:
 
 maintainer-clean: maintainer-clean-am
-       -rm -rf ./$(DEPDIR)
+               -rm -f ./$(DEPDIR)/arciterator-class.Plo
+       -rm -f ./$(DEPDIR)/arcsort.Plo
+       -rm -f ./$(DEPDIR)/closure.Plo
+       -rm -f ./$(DEPDIR)/compile.Plo
+       -rm -f ./$(DEPDIR)/compose.Plo
+       -rm -f ./$(DEPDIR)/concat.Plo
+       -rm -f ./$(DEPDIR)/connect.Plo
+       -rm -f ./$(DEPDIR)/convert.Plo
+       -rm -f ./$(DEPDIR)/decode.Plo
+       -rm -f ./$(DEPDIR)/determinize.Plo
+       -rm -f ./$(DEPDIR)/difference.Plo
+       -rm -f ./$(DEPDIR)/disambiguate.Plo
+       -rm -f ./$(DEPDIR)/draw.Plo
+       -rm -f ./$(DEPDIR)/encode.Plo
+       -rm -f ./$(DEPDIR)/encodemapper-class.Plo
+       -rm -f ./$(DEPDIR)/epsnormalize.Plo
+       -rm -f ./$(DEPDIR)/equal.Plo
+       -rm -f ./$(DEPDIR)/equivalent.Plo
+       -rm -f ./$(DEPDIR)/fst-class.Plo
+       -rm -f ./$(DEPDIR)/getters.Plo
+       -rm -f ./$(DEPDIR)/info-impl.Plo
+       -rm -f ./$(DEPDIR)/info.Plo
+       -rm -f ./$(DEPDIR)/intersect.Plo
+       -rm -f ./$(DEPDIR)/invert.Plo
+       -rm -f ./$(DEPDIR)/isomorphic.Plo
+       -rm -f ./$(DEPDIR)/map.Plo
+       -rm -f ./$(DEPDIR)/minimize.Plo
+       -rm -f ./$(DEPDIR)/print.Plo
+       -rm -f ./$(DEPDIR)/project.Plo
+       -rm -f ./$(DEPDIR)/prune.Plo
+       -rm -f ./$(DEPDIR)/push.Plo
+       -rm -f ./$(DEPDIR)/randequivalent.Plo
+       -rm -f ./$(DEPDIR)/randgen.Plo
+       -rm -f ./$(DEPDIR)/relabel.Plo
+       -rm -f ./$(DEPDIR)/replace.Plo
+       -rm -f ./$(DEPDIR)/reverse.Plo
+       -rm -f ./$(DEPDIR)/reweight.Plo
+       -rm -f ./$(DEPDIR)/rmepsilon.Plo
+       -rm -f ./$(DEPDIR)/shortest-distance.Plo
+       -rm -f ./$(DEPDIR)/shortest-path.Plo
+       -rm -f ./$(DEPDIR)/stateiterator-class.Plo
+       -rm -f ./$(DEPDIR)/synchronize.Plo
+       -rm -f ./$(DEPDIR)/text-io.Plo
+       -rm -f ./$(DEPDIR)/topsort.Plo
+       -rm -f ./$(DEPDIR)/union.Plo
+       -rm -f ./$(DEPDIR)/verify.Plo
+       -rm -f ./$(DEPDIR)/weight-class.Plo
        -rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
@@ -731,9 +857,9 @@ uninstall-am: uninstall-libLTLIBRARIES
 
 .MAKE: install-am install-strip
 
-.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
-       clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \
-       ctags-am distclean distclean-compile distclean-generic \
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
+       clean-generic clean-libLTLIBRARIES clean-libtool cscopelist-am \
+       ctags ctags-am distclean distclean-compile distclean-generic \
        distclean-libtool distclean-tags distdir dvi dvi-am html \
        html-am info info-am install install-am install-data \
        install-data-am install-dvi install-dvi-am install-exec \
index a64dc32..f3ef2ab 100644 (file)
@@ -22,17 +22,10 @@ MutableArcIteratorClass::MutableArcIteratorClass(MutableFstClass *fst,
       "InitMutableArcIteratorClass", fst->ArcType(), &args);
 }
 
-REGISTER_FST_OPERATION(InitArcIteratorClass, StdArc, InitArcIteratorClassArgs);
-REGISTER_FST_OPERATION(InitArcIteratorClass, LogArc, InitArcIteratorClassArgs);
-REGISTER_FST_OPERATION(InitArcIteratorClass, Log64Arc,
-                       InitArcIteratorClassArgs);
-
-REGISTER_FST_OPERATION(InitMutableArcIteratorClass, StdArc,
-                       InitMutableArcIteratorClassArgs);
-REGISTER_FST_OPERATION(InitMutableArcIteratorClass, LogArc,
-                       InitMutableArcIteratorClassArgs);
-REGISTER_FST_OPERATION(InitMutableArcIteratorClass, Log64Arc,
-                       InitMutableArcIteratorClassArgs);
+REGISTER_FST_OPERATION_3ARCS(InitArcIteratorClass, InitArcIteratorClassArgs);
+
+REGISTER_FST_OPERATION_3ARCS(InitMutableArcIteratorClass,
+                             InitMutableArcIteratorClassArgs);
 
 }  // namespace script
 }  // namespace fst
index 1171f67..ca359d5 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/arcsort.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -14,9 +13,7 @@ void ArcSort(MutableFstClass *fst, ArcSortType sort_type) {
   Apply<Operation<ArcSortArgs>>("ArcSort", fst->ArcType(), &args);
 }
 
-REGISTER_FST_OPERATION(ArcSort, StdArc, ArcSortArgs);
-REGISTER_FST_OPERATION(ArcSort, LogArc, ArcSortArgs);
-REGISTER_FST_OPERATION(ArcSort, Log64Arc, ArcSortArgs);
+REGISTER_FST_OPERATION_3ARCS(ArcSort, ArcSortArgs);
 
 }  // namespace script
 }  // namespace fst
index 9e17b2e..21022cd 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/closure.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -14,9 +13,7 @@ void Closure(MutableFstClass *fst, ClosureType closure_type) {
   Apply<Operation<ClosureArgs>>("Closure", fst->ArcType(), &args);
 }
 
-REGISTER_FST_OPERATION(Closure, StdArc, ClosureArgs);
-REGISTER_FST_OPERATION(Closure, LogArc, ClosureArgs);
-REGISTER_FST_OPERATION(Closure, Log64Arc, ClosureArgs);
+REGISTER_FST_OPERATION_3ARCS(Closure, ClosureArgs);
 
 }  // namespace script
 }  // namespace fst
index c88db63..56f80dd 100644 (file)
@@ -3,10 +3,6 @@
 
 #include <fst/script/compile.h>
 
-#include <istream>
-#include <string>
-
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -38,10 +34,8 @@ FstClass *CompileFstInternal(std::istream &istrm, const std::string &source,
   return args.retval;
 }
 
-// This registers 2; 1 does not require registration.
-REGISTER_FST_OPERATION(CompileFstInternal, StdArc, CompileFstArgs);
-REGISTER_FST_OPERATION(CompileFstInternal, LogArc, CompileFstArgs);
-REGISTER_FST_OPERATION(CompileFstInternal, Log64Arc, CompileFstArgs);
+// This registers form 2; 1 does not require registration.
+REGISTER_FST_OPERATION_3ARCS(CompileFstInternal, CompileFstArgs);
 
 }  // namespace script
 }  // namespace fst
index a206093..a39504c 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/compose.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -20,9 +19,7 @@ void Compose(const FstClass &ifst1, const FstClass &ifst2,
   Apply<Operation<ComposeArgs>>("Compose", ifst1.ArcType(), &args);
 }
 
-REGISTER_FST_OPERATION(Compose, StdArc, ComposeArgs);
-REGISTER_FST_OPERATION(Compose, LogArc, ComposeArgs);
-REGISTER_FST_OPERATION(Compose, Log64Arc, ComposeArgs);
+REGISTER_FST_OPERATION_3ARCS(Compose, ComposeArgs);
 
 }  // namespace script
 }  // namespace fst
index 9a9cd28..3f813fa 100644 (file)
@@ -3,39 +3,42 @@
 
 #include <fst/script/concat.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
 namespace script {
 
-// 1
-void Concat(MutableFstClass *ofst, const FstClass &ifst) {
-  if (!internal::ArcTypesMatch(*ofst, ifst, "Concat")) {
-    ofst->SetProperties(kError, kError);
+void Concat(MutableFstClass *fst1, const FstClass &fst2) {
+  if (!internal::ArcTypesMatch(*fst1, fst2, "Concat")) {
+    fst1->SetProperties(kError, kError);
     return;
   }
-  ConcatArgs1 args(ofst, ifst);
-  Apply<Operation<ConcatArgs1>>("Concat", ofst->ArcType(), &args);
+  ConcatArgs1 args(fst1, fst2);
+  Apply<Operation<ConcatArgs1>>("Concat", fst1->ArcType(), &args);
 }
 
-// 2
-void Concat(const FstClass &ifst, MutableFstClass *ofst) {
-  if (!internal::ArcTypesMatch(ifst, *ofst, "Concat")) {
-    ofst->SetProperties(kError, kError);
+void Concat(const FstClass &fst1, MutableFstClass *fst2) {
+  if (!internal::ArcTypesMatch(fst1, *fst2, "Concat")) {
+    fst2->SetProperties(kError, kError);
     return;
   }
-  ConcatArgs2 args(ifst, ofst);
-  Apply<Operation<ConcatArgs2>>("Concat", ofst->ArcType(), &args);
+  ConcatArgs2 args(fst1, fst2);
+  Apply<Operation<ConcatArgs2>>("Concat", fst2->ArcType(), &args);
 }
 
-REGISTER_FST_OPERATION(Concat, StdArc, ConcatArgs1);
-REGISTER_FST_OPERATION(Concat, LogArc, ConcatArgs1);
-REGISTER_FST_OPERATION(Concat, Log64Arc, ConcatArgs1);
+void Concat(const std::vector<FstClass *> &fsts1, MutableFstClass *fst2) {
+  for (const auto *fst1 : fsts1) {
+    if (!internal::ArcTypesMatch(*fst1, *fst2, "Concat")) {
+      fst2->SetProperties(kError, kError);
+      return;
+    }
+  }
+  ConcatArgs3 args(fsts1, fst2);
+  Apply<Operation<ConcatArgs3>>("Concat", fst2->ArcType(), &args);
+}
 
-REGISTER_FST_OPERATION(Concat, StdArc, ConcatArgs2);
-REGISTER_FST_OPERATION(Concat, LogArc, ConcatArgs2);
-REGISTER_FST_OPERATION(Concat, Log64Arc, ConcatArgs2);
+REGISTER_FST_OPERATION_3ARCS(Concat, ConcatArgs1);
+REGISTER_FST_OPERATION_3ARCS(Concat, ConcatArgs2);
 
 }  // namespace script
 }  // namespace fst
index ff43568..2acb4de 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/connect.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -13,9 +12,7 @@ void Connect(MutableFstClass *fst) {
   Apply<Operation<MutableFstClass>>("Connect", fst->ArcType(), fst);
 }
 
-REGISTER_FST_OPERATION(Connect, StdArc, MutableFstClass);
-REGISTER_FST_OPERATION(Connect, LogArc, MutableFstClass);
-REGISTER_FST_OPERATION(Connect, Log64Arc, MutableFstClass);
+REGISTER_FST_OPERATION_3ARCS(Connect, MutableFstClass);
 
 }  // namespace script
 }  // namespace fst
index d14d50b..1c31fcb 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/convert.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -16,9 +15,7 @@ FstClass *Convert(const FstClass &ifst, const std::string &new_type) {
   return args.retval;
 }
 
-REGISTER_FST_OPERATION(Convert, StdArc, ConvertArgs);
-REGISTER_FST_OPERATION(Convert, LogArc, ConvertArgs);
-REGISTER_FST_OPERATION(Convert, Log64Arc, ConvertArgs);
+REGISTER_FST_OPERATION_3ARCS(Convert, ConvertArgs);
 
 }  // namespace script
 }  // namespace fst
index e3ed701..314f367 100644 (file)
@@ -3,34 +3,21 @@
 
 #include <fst/script/decode.h>
 
-#include <fst/encode.h>
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
 namespace script {
 
-void Decode(MutableFstClass *fst, const std::string &coder_fname) {
-  DecodeArgs1 args(fst, coder_fname);
-  Apply<Operation<DecodeArgs1>>("Decode", fst->ArcType(), &args);
-}
-
-void Decode(MutableFstClass *fst, const EncodeMapperClass &encoder) {
-  if (!internal::ArcTypesMatch(*fst, encoder, "Decode")) {
+void Decode(MutableFstClass *fst, const EncodeMapperClass &mapper) {
+  if (!internal::ArcTypesMatch(*fst, mapper, "Decode")) {
     fst->SetProperties(kError, kError);
     return;
   }
-  DecodeArgs2 args(fst, encoder);
-  Apply<Operation<DecodeArgs2>>("Decode", fst->ArcType(), &args);
+  DecodeArgs args(fst, mapper);
+  Apply<Operation<DecodeArgs>>("Decode", fst->ArcType(), &args);
 }
 
-REGISTER_FST_OPERATION(Decode, StdArc, DecodeArgs1);
-REGISTER_FST_OPERATION(Decode, LogArc, DecodeArgs1);
-REGISTER_FST_OPERATION(Decode, Log64Arc, DecodeArgs1);
-
-REGISTER_FST_OPERATION(Decode, StdArc, DecodeArgs2);
-REGISTER_FST_OPERATION(Decode, LogArc, DecodeArgs2);
-REGISTER_FST_OPERATION(Decode, Log64Arc, DecodeArgs2);
+REGISTER_FST_OPERATION_3ARCS(Decode, DecodeArgs);
 
 }  // namespace script
 }  // namespace fst
index e87fa81..81056de 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/determinize.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -20,9 +19,7 @@ void Determinize(const FstClass &ifst, MutableFstClass *ofst,
   Apply<Operation<DeterminizeArgs>>("Determinize", ifst.ArcType(), &args);
 }
 
-REGISTER_FST_OPERATION(Determinize, StdArc, DeterminizeArgs);
-REGISTER_FST_OPERATION(Determinize, LogArc, DeterminizeArgs);
-REGISTER_FST_OPERATION(Determinize, Log64Arc, DeterminizeArgs);
+REGISTER_FST_OPERATION_3ARCS(Determinize, DeterminizeArgs);
 
 }  // namespace script
 }  // namespace fst
index 82b96d0..4b7efe0 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/difference.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -20,9 +19,7 @@ void Difference(const FstClass &ifst1, const FstClass &ifst2,
   Apply<Operation<DifferenceArgs>>("Difference", ifst1.ArcType(), &args);
 }
 
-REGISTER_FST_OPERATION(Difference, StdArc, DifferenceArgs);
-REGISTER_FST_OPERATION(Difference, LogArc, DifferenceArgs);
-REGISTER_FST_OPERATION(Difference, Log64Arc, DifferenceArgs);
+REGISTER_FST_OPERATION_3ARCS(Difference, DifferenceArgs);
 
 }  // namespace script
 }  // namespace fst
index 1b484e6..a39a0de 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/disambiguate.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -20,9 +19,7 @@ void Disambiguate(const FstClass &ifst, MutableFstClass *ofst,
   Apply<Operation<DisambiguateArgs>>("Disambiguate", ifst.ArcType(), &args);
 }
 
-REGISTER_FST_OPERATION(Disambiguate, StdArc, DisambiguateArgs);
-REGISTER_FST_OPERATION(Disambiguate, LogArc, DisambiguateArgs);
-REGISTER_FST_OPERATION(Disambiguate, Log64Arc, DisambiguateArgs);
+REGISTER_FST_OPERATION_3ARCS(Disambiguate, DisambiguateArgs);
 
 }  // namespace script
 }  // namespace fst
index c63f882..27e6707 100644 (file)
@@ -3,31 +3,24 @@
 
 #include <fst/script/draw.h>
 
-#include <ostream>
-#include <string>
-
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
 namespace script {
 
-void DrawFst(const FstClass &fst, const SymbolTable *isyms,
-             const SymbolTable *osyms, const SymbolTable *ssyms, bool accep,
-             const std::string &title, float width, float height, bool portrait,
-             bool vertical, float ranksep, float nodesep, int fontsize,
-             int precision, const std::string &float_format,
-             bool show_weight_one, std::ostream *ostrm,
-             const std::string &dest) {
-  FstDrawerArgs args(fst, isyms, osyms, ssyms, accep, title, width, height,
-                     portrait, vertical, ranksep, nodesep, fontsize, precision,
-                     float_format, show_weight_one, ostrm, dest);
-  Apply<Operation<FstDrawerArgs>>("DrawFst", fst.ArcType(), &args);
+void Draw(const FstClass &fst, const SymbolTable *isyms,
+          const SymbolTable *osyms, const SymbolTable *ssyms, bool accep,
+          const std::string &title, float width, float height, bool portrait,
+          bool vertical, float ranksep, float nodesep, int fontsize,
+          int precision, const std::string &float_format, bool show_weight_one,
+          std::ostream &ostrm, const std::string &dest) {
+  DrawArgs args(fst, isyms, osyms, ssyms, accep, title, width, height, portrait,
+                vertical, ranksep, nodesep, fontsize, precision, float_format,
+                show_weight_one, ostrm, dest);
+  Apply<Operation<DrawArgs>>("Draw", fst.ArcType(), &args);
 }
 
-REGISTER_FST_OPERATION(DrawFst, StdArc, FstDrawerArgs);
-REGISTER_FST_OPERATION(DrawFst, LogArc, FstDrawerArgs);
-REGISTER_FST_OPERATION(DrawFst, Log64Arc, FstDrawerArgs);
+REGISTER_FST_OPERATION_3ARCS(Draw, DrawArgs);
 
 }  // namespace script
 }  // namespace fst
index 46457d7..37faf91 100644 (file)
@@ -1,37 +1,23 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/encode.h>
-
 #include <fst/script/encode.h>
-#include <fst/script/fst-class.h>
+
 #include <fst/script/script-impl.h>
 
 namespace fst {
 namespace script {
 
-void Encode(MutableFstClass *fst, uint32 flags, bool reuse_encoder,
-            const std::string &coder_fname) {
-  EncodeArgs1 args(fst, flags, reuse_encoder, coder_fname);
-  Apply<Operation<EncodeArgs1>>("Encode", fst->ArcType(), &args);
-}
-
-void Encode(MutableFstClass *fst, EncodeMapperClass *encoder) {
-  if (!internal::ArcTypesMatch(*fst, *encoder, "Encode")) {
+void Encode(MutableFstClass *fst, EncodeMapperClass *mapper) {
+  if (!internal::ArcTypesMatch(*fst, *mapper, "Encode")) {
     fst->SetProperties(kError, kError);
     return;
   }
-  EncodeArgs2 args(fst, encoder);
-  Apply<Operation<EncodeArgs2>>("Encode", fst->ArcType(), &args);
+  EncodeArgs args(fst, mapper);
+  Apply<Operation<EncodeArgs>>("Encode", fst->ArcType(), &args);
 }
 
-REGISTER_FST_OPERATION(Encode, StdArc, EncodeArgs1);
-REGISTER_FST_OPERATION(Encode, LogArc, EncodeArgs1);
-REGISTER_FST_OPERATION(Encode, Log64Arc, EncodeArgs1);
-
-REGISTER_FST_OPERATION(Encode, StdArc, EncodeArgs2);
-REGISTER_FST_OPERATION(Encode, LogArc, EncodeArgs2);
-REGISTER_FST_OPERATION(Encode, Log64Arc, EncodeArgs2);
+REGISTER_FST_OPERATION_3ARCS(Encode, EncodeArgs);
 
 }  // namespace script
 }  // namespace fst
index 6d179cc..6ecd7ee 100644 (file)
@@ -7,21 +7,73 @@
 
 namespace fst {
 namespace script {
+namespace {
 
-EncodeMapperClass::EncodeMapperClass(const std::string &arc_type, uint32 flags,
+// Helper methods.
+
+EncodeMapperClass *ReadEncodeMapper(std::istream &istrm,
+                                    const std::string &source) {
+  if (!istrm) {
+    LOG(ERROR) << "ReadEncodeMapperClass: Can't open file: " << source;
+    return nullptr;
+  }
+  EncodeTableHeader hdr;
+  if (!hdr.Read(istrm, source)) return nullptr;
+  const auto &arc_type = hdr.ArcType();
+  // TODO(b/141172858): deprecated, remove by 2020-01-01.
+  if (arc_type.empty()) {
+    LOG(ERROR) << "Old-style EncodeMapper cannot be used with script interface";
+    return nullptr;
+  }
+  // The actual reader also consumes the header, so to be kind we rewind.
+  istrm.seekg(0, istrm.beg);
+  static const auto *reg =
+      EncodeMapperClassIORegistration::Register::GetRegister();
+  const auto reader = reg->GetReader(arc_type);
+  if (!reader) {
+    LOG(ERROR) << "EncodeMapperClass::Read: Unknown arc type: " << arc_type;
+    return nullptr;
+  }
+  return reader(istrm, source);
+}
+
+EncodeMapperImplBase *CreateEncodeMapper(const std::string &arc_type,
+                                         uint8 flags, EncodeType type) {
+  static const auto *reg =
+      EncodeMapperClassIORegistration::Register::GetRegister();
+  auto creator = reg->GetCreator(arc_type);
+  if (!creator) {
+    FSTERROR() << "EncodeMapperClass: Unknown arc type: " << arc_type;
+    return nullptr;
+  }
+  return creator(flags, type);
+}
+
+}  // namespace
+
+EncodeMapperClass::EncodeMapperClass(const std::string &arc_type, uint8 flags,
                                      EncodeType type)
-    : impl_(nullptr) {
-  InitEncodeMapperClassArgs args(flags, type, this);
-  Apply<Operation<InitEncodeMapperClassArgs>>("InitEncodeMapperClass",
-                                              arc_type, &args);
+    : impl_(CreateEncodeMapper(arc_type, flags, type)) {}
+
+EncodeMapperClass *EncodeMapperClass::Read(const std::string &source) {
+  if (!source.empty()) {
+    std::ifstream strm(source, std::ios_base::in | std::ios_base::binary);
+    return ReadEncodeMapper(strm, source);
+  } else {
+    return ReadEncodeMapper(std::cin, "standard input");
+  }
 }
 
-REGISTER_FST_OPERATION(InitEncodeMapperClass, StdArc,
-                       InitEncodeMapperClassArgs);
-REGISTER_FST_OPERATION(InitEncodeMapperClass, LogArc,
-                       InitEncodeMapperClassArgs);
-REGISTER_FST_OPERATION(InitEncodeMapperClass, Log64Arc,
-                       InitEncodeMapperClassArgs);
+EncodeMapperClass *EncodeMapperClass::Read(std::istream &strm,
+                                           const std::string &source) {
+  return ReadEncodeMapper(strm, source);
+}
+
+// Registration.
+
+REGISTER_ENCODEMAPPER_CLASS(StdArc);
+REGISTER_ENCODEMAPPER_CLASS(LogArc);
+REGISTER_ENCODEMAPPER_CLASS(Log64Arc);
 
 }  // namespace script
 }  // namespace fst
index 1d3d3f5..025a28a 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/epsnormalize.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -19,9 +18,7 @@ void EpsNormalize(const FstClass &ifst, MutableFstClass *ofst,
   Apply<Operation<EpsNormalizeArgs>>("EpsNormalize", ifst.ArcType(), &args);
 }
 
-REGISTER_FST_OPERATION(EpsNormalize, StdArc, EpsNormalizeArgs);
-REGISTER_FST_OPERATION(EpsNormalize, LogArc, EpsNormalizeArgs);
-REGISTER_FST_OPERATION(EpsNormalize, Log64Arc, EpsNormalizeArgs);
+REGISTER_FST_OPERATION_3ARCS(EpsNormalize, EpsNormalizeArgs);
 
 }  // namespace script
 }  // namespace fst
index 3812039..9868de3 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/equal.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -17,9 +16,7 @@ bool Equal(const FstClass &fst1, const FstClass &fst2, float delta) {
   return args.retval;
 }
 
-REGISTER_FST_OPERATION(Equal, StdArc, EqualArgs);
-REGISTER_FST_OPERATION(Equal, LogArc, EqualArgs);
-REGISTER_FST_OPERATION(Equal, Log64Arc, EqualArgs);
+REGISTER_FST_OPERATION_3ARCS(Equal, EqualArgs);
 
 }  // namespace script
 }  // namespace fst
index 49616c7..376db22 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/equivalent.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -17,9 +16,7 @@ bool Equivalent(const FstClass &fst1, const FstClass &fst2, float delta) {
   return args.retval;
 }
 
-REGISTER_FST_OPERATION(Equivalent, StdArc, EquivalentArgs);
-REGISTER_FST_OPERATION(Equivalent, LogArc, EquivalentArgs);
-REGISTER_FST_OPERATION(Equivalent, Log64Arc, EquivalentArgs);
+REGISTER_FST_OPERATION_3ARCS(Equivalent, EquivalentArgs);
 
 }  // namespace script
 }  // namespace fst
index 799ea6d..3ef73f4 100644 (file)
 #include <fst/fst-decl.h>
 #include <fst/reverse.h>
 #include <fst/union.h>
-#include <fst/script/register.h>
 
 namespace fst {
 namespace script {
-
-// Registration.
-
-REGISTER_FST_CLASSES(StdArc);
-REGISTER_FST_CLASSES(LogArc);
-REGISTER_FST_CLASSES(Log64Arc);
+namespace {
 
 // Helper functions.
 
-namespace {
-
 template <class F>
-F *ReadFstClass(std::istream &istrm, const std::string &fname) {
+F *ReadFstClass(std::istream &istrm, const std::string &source) {
   if (!istrm) {
-    LOG(ERROR) << "ReadFstClass: Can't open file: " << fname;
+    LOG(ERROR) << "ReadFstClass: Can't open file: " << source;
     return nullptr;
   }
   FstHeader hdr;
-  if (!hdr.Read(istrm, fname)) return nullptr;
-  const FstReadOptions read_options(fname, &hdr);
+  if (!hdr.Read(istrm, source)) return nullptr;
+  const FstReadOptions read_options(source, &hdr);
   const auto &arc_type = hdr.ArcType();
-  static const auto *io_register = IORegistration<F>::Register::GetRegister();
-  const auto reader = io_register->GetReader(arc_type);
+  static const auto *reg = FstClassIORegistration<F>::Register::GetRegister();
+  const auto reader = reg->GetReader(arc_type);
   if (!reader) {
     LOG(ERROR) << "ReadFstClass: Unknown arc type: " << arc_type;
     return nullptr;
@@ -50,9 +42,8 @@ F *ReadFstClass(std::istream &istrm, const std::string &fname) {
 
 template <class F>
 FstClassImplBase *CreateFstClass(const std::string &arc_type) {
-  static const auto *io_register =
-      IORegistration<F>::Register::GetRegister();
-  auto creator = io_register->GetCreator(arc_type);
+  static const auto *reg = FstClassIORegistration<F>::Register::GetRegister();
+  auto creator = reg->GetCreator(arc_type);
   if (!creator) {
     FSTERROR() << "CreateFstClass: Unknown arc type: " << arc_type;
     return nullptr;
@@ -62,9 +53,8 @@ FstClassImplBase *CreateFstClass(const std::string &arc_type) {
 
 template <class F>
 FstClassImplBase *ConvertFstClass(const FstClass &other) {
-  static const auto *io_register =
-      IORegistration<F>::Register::GetRegister();
-  auto converter = io_register->GetConverter(other.ArcType());
+  static const auto *reg = FstClassIORegistration<F>::Register::GetRegister();
+  auto converter = reg->GetConverter(other.ArcType());
   if (!converter) {
     FSTERROR() << "ConvertFstClass: Unknown arc type: " << other.ArcType();
     return nullptr;
@@ -74,13 +64,12 @@ FstClassImplBase *ConvertFstClass(const FstClass &other) {
 
 }  // namespace
 
-
 // FstClass methods.
 
-FstClass *FstClass::Read(const std::string &fname) {
-  if (!fname.empty()) {
-    std::ifstream istrm(fname, std::ios_base::in | std::ios_base::binary);
-    return ReadFstClass<FstClass>(istrm, fname);
+FstClass *FstClass::Read(const std::string &source) {
+  if (!source.empty()) {
+    std::ifstream istrm(source, std::ios_base::in | std::ios_base::binary);
+    return ReadFstClass<FstClass>(istrm, source);
   } else {
     return ReadFstClass<FstClass>(std::cin, "standard input");
   }
@@ -102,16 +91,17 @@ bool FstClass::WeightTypesMatch(const WeightClass &weight,
 
 // MutableFstClass methods.
 
-MutableFstClass *MutableFstClass::Read(const std::string &fname, bool convert) {
+MutableFstClass *MutableFstClass::Read(const std::string &source,
+                                       bool convert) {
   if (convert == false) {
-    if (!fname.empty()) {
-      std::ifstream in(fname, std::ios_base::in | std::ios_base::binary);
-      return ReadFstClass<MutableFstClass>(in, fname);
+    if (!source.empty()) {
+      std::ifstream in(source, std::ios_base::in | std::ios_base::binary);
+      return ReadFstClass<MutableFstClass>(in, source);
     } else {
       return ReadFstClass<MutableFstClass>(std::cin, "standard input");
     }
   } else {  // Converts to VectorFstClass if not mutable.
-    std::unique_ptr<FstClass> ifst(FstClass::Read(fname));
+    std::unique_ptr<FstClass> ifst(FstClass::Read(source));
     if (!ifst) return nullptr;
     if (ifst->Properties(kMutable, false) == kMutable) {
       return static_cast<MutableFstClass *>(ifst.release());
@@ -123,10 +113,10 @@ MutableFstClass *MutableFstClass::Read(const std::string &fname, bool convert) {
 
 // VectorFstClass methods.
 
-VectorFstClass *VectorFstClass::Read(const std::string &fname) {
-  if (!fname.empty()) {
-    std::ifstream in(fname, std::ios_base::in | std::ios_base::binary);
-    return ReadFstClass<VectorFstClass>(in, fname);
+VectorFstClass *VectorFstClass::Read(const std::string &source) {
+  if (!source.empty()) {
+    std::ifstream in(source, std::ios_base::in | std::ios_base::binary);
+    return ReadFstClass<VectorFstClass>(in, source);
   } else {
     return ReadFstClass<VectorFstClass>(std::cin, "standard input");
   }
@@ -138,5 +128,11 @@ VectorFstClass::VectorFstClass(const std::string &arc_type)
 VectorFstClass::VectorFstClass(const FstClass &other)
     : MutableFstClass(ConvertFstClass<VectorFstClass>(other)) {}
 
+// Registration.
+
+REGISTER_FST_CLASSES(StdArc);
+REGISTER_FST_CLASSES(LogArc);
+REGISTER_FST_CLASSES(Log64Arc);
+
 }  // namespace script
 }  // namespace fst
index c3afb1d..8c07c52 100644 (file)
@@ -1,3 +1,6 @@
+// See www.openfst.org for extensive documentation on this weighted
+// finite-state transducer library.
+
 #include <fst/script/getters.h>
 
 namespace fst {
index 0dba623..7614cf9 100644 (file)
@@ -1,96 +1,97 @@
+// See www.openfst.org for extensive documentation on this weighted
+// finite-state transducer library.
+
 #include <fst/script/info-impl.h>
 
 namespace fst {
 
-void PrintFstInfoImpl(const FstInfo &fstinfo, bool pipe) {
-  std::ostream &ostrm = pipe ? std::cerr : std::cout;
+void FstInfo::Info() const {
+  std::ostream &ostrm = std::cout;
   const auto old = ostrm.setf(std::ios::left);
   ostrm.width(50);
-  ostrm << "fst type" << fstinfo.FstType() << std::endl;
+  ostrm << "fst type" << FstType() << std::endl;
   ostrm.width(50);
-  ostrm << "arc type" << fstinfo.ArcType() << std::endl;
+  ostrm << "arc type" << ArcType() << std::endl;
   ostrm.width(50);
-  ostrm << "input symbol table" << fstinfo.InputSymbols() << std::endl;
+  ostrm << "input symbol table" << InputSymbols() << std::endl;
   ostrm.width(50);
-  ostrm << "output symbol table" << fstinfo.OutputSymbols() << std::endl;
-  if (!fstinfo.LongInfo()) {
+  ostrm << "output symbol table" << OutputSymbols() << std::endl;
+  if (!LongInfo()) {
     ostrm.setf(old);
     return;
   }
   ostrm.width(50);
-  ostrm << "# of states" << fstinfo.NumStates() << std::endl;
+  ostrm << "# of states" << NumStates() << std::endl;
   ostrm.width(50);
-  ostrm << "# of arcs" << fstinfo.NumArcs() << std::endl;
+  ostrm << "# of arcs" << NumArcs() << std::endl;
   ostrm.width(50);
-  ostrm << "initial state" << fstinfo.Start() << std::endl;
+  ostrm << "initial state" << Start() << std::endl;
   ostrm.width(50);
-  ostrm << "# of final states" << fstinfo.NumFinal() << std::endl;
+  ostrm << "# of final states" << NumFinal() << std::endl;
   ostrm.width(50);
-  ostrm << "# of input/output epsilons" << fstinfo.NumEpsilons() << std::endl;
+  ostrm << "# of input/output epsilons" << NumEpsilons() << std::endl;
   ostrm.width(50);
-  ostrm << "# of input epsilons" << fstinfo.NumInputEpsilons() << std::endl;
+  ostrm << "# of input epsilons" << NumInputEpsilons() << std::endl;
   ostrm.width(50);
-  ostrm << "# of output epsilons" << fstinfo.NumOutputEpsilons() << std::endl;
+  ostrm << "# of output epsilons" << NumOutputEpsilons() << std::endl;
   ostrm.width(50);
-  ostrm << "input label multiplicity" << fstinfo.InputLabelMultiplicity()
-        << std::endl;
+  ostrm << "input label multiplicity" << InputLabelMultiplicity() << std::endl;
   ostrm.width(50);
-  ostrm << "output label multiplicity" << fstinfo.OutputLabelMultiplicity()
+  ostrm << "output label multiplicity" << OutputLabelMultiplicity()
         << std::endl;
   ostrm.width(50);
   std::string arc_type = "";
-  if (fstinfo.ArcFilterType() == "epsilon")
+  if (ArcFilterType() == "epsilon")
     arc_type = "epsilon ";
-  else if (fstinfo.ArcFilterType() == "iepsilon")
+  else if (ArcFilterType() == "iepsilon")
     arc_type = "input-epsilon ";
-  else if (fstinfo.ArcFilterType() == "oepsilon")
+  else if (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;
+  ostrm << accessible_label << NumAccessible() << std::endl;
   const auto coaccessible_label = "# of " + arc_type + "coaccessible states";
   ostrm.width(50);
-  ostrm << coaccessible_label << fstinfo.NumCoAccessible() << std::endl;
+  ostrm << coaccessible_label << NumCoAccessible() << std::endl;
   const auto connected_label = "# of " + arc_type + "connected states";
   ostrm.width(50);
-  ostrm << connected_label << fstinfo.NumConnected() << std::endl;
+  ostrm << connected_label << NumConnected() << std::endl;
   const auto numcc_label = "# of " + arc_type + "connected components";
   ostrm.width(50);
-  ostrm << numcc_label << fstinfo.NumCc() << std::endl;
+  ostrm << numcc_label << NumCc() << std::endl;
   const auto numscc_label = "# of " + arc_type + "strongly conn components";
   ostrm.width(50);
-  ostrm << numscc_label << fstinfo.NumScc() << std::endl;
+  ostrm << numscc_label << NumScc() << std::endl;
   ostrm.width(50);
   ostrm << "input matcher"
-        << (fstinfo.InputMatchType() == MATCH_INPUT
+        << (InputMatchType() == MATCH_INPUT
                 ? 'y'
-                : fstinfo.InputMatchType() == MATCH_NONE ? 'n' : '?')
+                : InputMatchType() == MATCH_NONE ? 'n' : '?')
         << std::endl;
   ostrm.width(50);
   ostrm << "output matcher"
-        << (fstinfo.OutputMatchType() == MATCH_OUTPUT
+        << (OutputMatchType() == MATCH_OUTPUT
                 ? 'y'
-                : fstinfo.OutputMatchType() == MATCH_NONE ? 'n' : '?')
+                : OutputMatchType() == MATCH_NONE ? 'n' : '?')
         << std::endl;
   ostrm.width(50);
-  ostrm << "input lookahead" << (fstinfo.InputLookAhead() ? 'y' : 'n')
-        << std::endl;
+  ostrm << "input lookahead" << (InputLookAhead() ? 'y' : 'n') << std::endl;
   ostrm.width(50);
-  ostrm << "output lookahead" << (fstinfo.OutputLookAhead() ? 'y' : 'n')
-        << std::endl;
+  ostrm << "output lookahead" << (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';
+      if (Properties() & prop) value = 'y';
       ostrm.width(50);
       ostrm << PropertyNames[i] << value << std::endl;
     } else if (prop & kPosTrinaryProperties) {
       char value = '?';
-      if (fstinfo.Properties() & prop)
+      if (Properties() & prop) {
         value = 'y';
-      else if (fstinfo.Properties() & prop << 1)
+      } else if (Properties() & prop << 1) {
         value = 'n';
+      }
       ostrm.width(50);
       ostrm << PropertyNames[i] << value << std::endl;
     }
index bcf0d6d..f8e3cc1 100644 (file)
@@ -3,35 +3,19 @@
 
 #include <fst/script/info.h>
 
-#include <string>
-
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
 namespace script {
 
-void PrintFstInfo(const FstClass &fst, bool test_properties,
-                  const std::string &arc_filter, const std::string &info_type,
-                  bool pipe, bool verify) {
-  InfoArgs args(fst, test_properties, arc_filter, info_type, pipe, verify);
-  Apply<Operation<InfoArgs>>("PrintFstInfo", fst.ArcType(), &args);
-}
-
-void GetFstInfo(const FstClass &fst, bool test_properties,
-                const std::string &arc_filter, const std::string &info_type,
-                bool verify, FstInfo *result) {
-  GetInfoArgs args(fst, test_properties, arc_filter, info_type, verify, result);
-  Apply<Operation<GetInfoArgs>>("GetFstInfo", fst.ArcType(), &args);
+void Info(const FstClass &fst, bool test_properties,
+          const std::string &arc_filter, const std::string &info_type,
+          bool verify) {
+  InfoArgs args(fst, test_properties, arc_filter, info_type, verify);
+  Apply<Operation<InfoArgs>>("Info", 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);
+REGISTER_FST_OPERATION_3ARCS(Info, InfoArgs);
 
 }  // namespace script
 }  // namespace fst
index 58dec06..be3fc80 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/intersect.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -20,9 +19,7 @@ void Intersect(const FstClass &ifst1, const FstClass &ifst2,
   Apply<Operation<IntersectArgs>>("Intersect", ifst1.ArcType(), &args);
 }
 
-REGISTER_FST_OPERATION(Intersect, StdArc, IntersectArgs);
-REGISTER_FST_OPERATION(Intersect, LogArc, IntersectArgs);
-REGISTER_FST_OPERATION(Intersect, Log64Arc, IntersectArgs);
+REGISTER_FST_OPERATION_3ARCS(Intersect, IntersectArgs);
 
 }  // namespace script
 }  // namespace fst
index 6276aac..e6e836b 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/invert.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -13,9 +12,7 @@ void Invert(MutableFstClass *fst) {
   Apply<Operation<MutableFstClass>>("Invert", fst->ArcType(), fst);
 }
 
-REGISTER_FST_OPERATION(Invert, StdArc, MutableFstClass);
-REGISTER_FST_OPERATION(Invert, LogArc, MutableFstClass);
-REGISTER_FST_OPERATION(Invert, Log64Arc, MutableFstClass);
+REGISTER_FST_OPERATION_3ARCS(Invert, MutableFstClass);
 
 }  // namespace script
 }  // namespace fst
index e6eb1d5..23cb792 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/isomorphic.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -17,9 +16,7 @@ bool Isomorphic(const FstClass &fst1, const FstClass &fst2, float delta) {
   return args.retval;
 }
 
-REGISTER_FST_OPERATION(Isomorphic, StdArc, IsomorphicArgs);
-REGISTER_FST_OPERATION(Isomorphic, LogArc, IsomorphicArgs);
-REGISTER_FST_OPERATION(Isomorphic, Log64Arc, IsomorphicArgs);
+REGISTER_FST_OPERATION_3ARCS(Isomorphic, IsomorphicArgs);
 
 }  // namespace script
 }  // namespace fst
index f479f4c..ff15d55 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/map.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -18,9 +17,7 @@ FstClass *Map(const FstClass &ifst, MapType map_type, float delta, double power,
   return args.retval;
 }
 
-REGISTER_FST_OPERATION(Map, StdArc, MapArgs);
-REGISTER_FST_OPERATION(Map, LogArc, MapArgs);
-REGISTER_FST_OPERATION(Map, Log64Arc, MapArgs);
+REGISTER_FST_OPERATION_3ARCS(Map, MapArgs);
 
 }  // namespace script
 }  // namespace fst
index 0fcc78c..96e5ed8 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/minimize.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -20,9 +19,7 @@ void Minimize(MutableFstClass *ofst1, MutableFstClass *ofst2, float delta,
   Apply<Operation<MinimizeArgs>>("Minimize", ofst1->ArcType(), &args);
 }
 
-REGISTER_FST_OPERATION(Minimize, StdArc, MinimizeArgs);
-REGISTER_FST_OPERATION(Minimize, LogArc, MinimizeArgs);
-REGISTER_FST_OPERATION(Minimize, Log64Arc, MinimizeArgs);
+REGISTER_FST_OPERATION_3ARCS(Minimize, MinimizeArgs);
 
 }  // namespace script
 }  // namespace fst
index 36ca7f0..05dd478 100644 (file)
@@ -3,28 +3,31 @@
 
 #include <fst/script/print.h>
 
-#include <ostream>
-#include <string>
-
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
 namespace script {
 
+void Print(const FstClass &fst, std::ostream &ostrm, const std::string &dest,
+           const SymbolTable *isyms, const SymbolTable *osyms,
+           const SymbolTable *ssyms, bool accept, bool show_weight_one,
+           const std::string &missing_sym) {
+  const auto sep = FLAGS_fst_field_separator.substr(0, 1);
+  PrintArgs args(fst, isyms, osyms, ssyms, accept, show_weight_one, ostrm, dest,
+                 sep, missing_sym);
+  Apply<Operation<PrintArgs>>("Print", fst.ArcType(), &args);
+}
+
+// TODO(kbg,2019-09-01): Deprecated.
 void PrintFst(const FstClass &fst, std::ostream &ostrm, const std::string &dest,
               const SymbolTable *isyms, const SymbolTable *osyms,
               const SymbolTable *ssyms, bool accept, bool show_weight_one,
               const std::string &missing_sym) {
-  const auto sep = FLAGS_fst_field_separator.substr(0, 1);
-  FstPrinterArgs args(fst, isyms, osyms, ssyms, accept, show_weight_one, &ostrm,
-                      dest, sep, missing_sym);
-  Apply<Operation<FstPrinterArgs>>("PrintFst", fst.ArcType(), &args);
+  Print(fst, ostrm, dest, isyms, osyms, ssyms, accept, show_weight_one,
+        missing_sym);
 }
 
-REGISTER_FST_OPERATION(PrintFst, StdArc, FstPrinterArgs);
-REGISTER_FST_OPERATION(PrintFst, LogArc, FstPrinterArgs);
-REGISTER_FST_OPERATION(PrintFst, Log64Arc, FstPrinterArgs);
+REGISTER_FST_OPERATION_3ARCS(Print, PrintArgs);
 
 }  // namespace script
 }  // namespace fst
index ed635fd..8bba946 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/project.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -15,9 +14,7 @@ void Project(MutableFstClass *ofst, ProjectType project_type) {
   Apply<Operation<ProjectArgs>>("Project", ofst->ArcType(), &args);
 }
 
-REGISTER_FST_OPERATION(Project, StdArc, ProjectArgs);
-REGISTER_FST_OPERATION(Project, LogArc, ProjectArgs);
-REGISTER_FST_OPERATION(Project, Log64Arc, ProjectArgs);
+REGISTER_FST_OPERATION_3ARCS(Project, ProjectArgs);
 
 }  // namespace script
 }  // namespace fst
index b3042e5..cf90938 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/prune.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -31,13 +30,8 @@ void Prune(MutableFstClass *fst, const WeightClass &weight_threshold,
   Apply<Operation<PruneArgs2>>("Prune", fst->ArcType(), &args);
 }
 
-REGISTER_FST_OPERATION(Prune, StdArc, PruneArgs1);
-REGISTER_FST_OPERATION(Prune, LogArc, PruneArgs1);
-REGISTER_FST_OPERATION(Prune, Log64Arc, PruneArgs1);
-
-REGISTER_FST_OPERATION(Prune, StdArc, PruneArgs2);
-REGISTER_FST_OPERATION(Prune, LogArc, PruneArgs2);
-REGISTER_FST_OPERATION(Prune, Log64Arc, PruneArgs2);
+REGISTER_FST_OPERATION_3ARCS(Prune, PruneArgs1);
+REGISTER_FST_OPERATION_3ARCS(Prune, PruneArgs2);
 
 }  // namespace script
 }  // namespace fst
index 7d75807..056b9a3 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/push.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -15,7 +14,7 @@ void Push(MutableFstClass *fst, ReweightType rew_type, float delta,
   Apply<Operation<PushArgs1>>("Push", fst->ArcType(), &args);
 }
 
-void Push(const FstClass &ifst, MutableFstClass *ofst, uint32 flags,
+void Push(const FstClass &ifst, MutableFstClass *ofst, uint8 flags,
           ReweightType rew_type, float delta) {
   if (!internal::ArcTypesMatch(ifst, *ofst, "Push")) {
     ofst->SetProperties(kError, kError);
@@ -25,13 +24,8 @@ void Push(const FstClass &ifst, MutableFstClass *ofst, uint32 flags,
   Apply<Operation<PushArgs2>>("Push", ifst.ArcType(), &args);
 }
 
-REGISTER_FST_OPERATION(Push, StdArc, PushArgs1);
-REGISTER_FST_OPERATION(Push, LogArc, PushArgs1);
-REGISTER_FST_OPERATION(Push, Log64Arc, PushArgs1);
-
-REGISTER_FST_OPERATION(Push, StdArc, PushArgs2);
-REGISTER_FST_OPERATION(Push, LogArc, PushArgs2);
-REGISTER_FST_OPERATION(Push, Log64Arc, PushArgs2);
+REGISTER_FST_OPERATION_3ARCS(Push, PushArgs1);
+REGISTER_FST_OPERATION_3ARCS(Push, PushArgs2);
 
 }  // namespace script
 }  // namespace fst
index efe87b8..b858ef6 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/randequivalent.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -19,9 +18,7 @@ bool RandEquivalent(const FstClass &fst1, const FstClass &fst2, int32 npath,
   return args.retval;
 }
 
-REGISTER_FST_OPERATION(RandEquivalent, StdArc, RandEquivalentArgs);
-REGISTER_FST_OPERATION(RandEquivalent, LogArc, RandEquivalentArgs);
-REGISTER_FST_OPERATION(RandEquivalent, Log64Arc, RandEquivalentArgs);
+REGISTER_FST_OPERATION_3ARCS(RandEquivalent, RandEquivalentArgs);
 
 }  // namespace script
 }  // namespace fst
index 1e8c0b7..92242ea 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/randgen.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -19,9 +18,7 @@ void RandGen(const FstClass &ifst, MutableFstClass *ofst, time_t seed,
   Apply<Operation<RandGenArgs>>("RandGen", ifst.ArcType(), &args);
 }
 
-REGISTER_FST_OPERATION(RandGen, StdArc, RandGenArgs);
-REGISTER_FST_OPERATION(RandGen, LogArc, RandGenArgs);
-REGISTER_FST_OPERATION(RandGen, Log64Arc, RandGenArgs);
+REGISTER_FST_OPERATION_3ARCS(RandGen, RandGenArgs);
 
 }  // namespace script
 }  // namespace fst
index 722a200..548580f 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/relabel.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -20,19 +19,15 @@ void Relabel(MutableFstClass *ofst, const SymbolTable *old_isyms,
   Apply<Operation<RelabelArgs1>>("Relabel", ofst->ArcType(), &args);
 }
 
-void Relabel(MutableFstClass *ofst, const std::vector<LabelPair> &ipairs,
-             const std::vector<LabelPair> &opairs) {
+void Relabel(MutableFstClass *ofst,
+             const std::vector<std::pair<int64, int64>> &ipairs,
+             const std::vector<std::pair<int64, int64>> &opairs) {
   RelabelArgs2 args(ofst, ipairs, opairs);
   Apply<Operation<RelabelArgs2>>("Relabel", ofst->ArcType(), &args);
 }
 
-REGISTER_FST_OPERATION(Relabel, StdArc, RelabelArgs1);
-REGISTER_FST_OPERATION(Relabel, LogArc, RelabelArgs1);
-REGISTER_FST_OPERATION(Relabel, Log64Arc, RelabelArgs1);
-
-REGISTER_FST_OPERATION(Relabel, StdArc, RelabelArgs2);
-REGISTER_FST_OPERATION(Relabel, LogArc, RelabelArgs2);
-REGISTER_FST_OPERATION(Relabel, Log64Arc, RelabelArgs2);
+REGISTER_FST_OPERATION_3ARCS(Relabel, RelabelArgs1);
+REGISTER_FST_OPERATION_3ARCS(Relabel, RelabelArgs2);
 
 }  // namespace script
 }  // namespace fst
index d5ce482..c78e1cb 100644 (file)
@@ -3,22 +3,15 @@
 
 #include <fst/script/replace.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
 namespace script {
 
-void Replace(const std::vector<LabelFstClassPair> &pairs, MutableFstClass *ofst,
-             const ReplaceOptions &opts) {
-  if (!pairs.empty()) {
-    for (auto it = pairs.begin(); it != pairs.end() - 1; ++it) {
-      if (!internal::ArcTypesMatch(*it->second, *(it + 1)->second, "Replace")) {
-        ofst->SetProperties(kError, kError);
-        return;
-      }
-    }
-    if (!internal::ArcTypesMatch(*pairs[0].second, *ofst, "Replace")) {
+void Replace(const std::vector<std::pair<int64, const FstClass *>> &pairs,
+             MutableFstClass *ofst, const ReplaceOptions &opts) {
+  for (const auto &pair : pairs) {
+    if (!internal::ArcTypesMatch(*pair.second, *ofst, "Replace")) {
       ofst->SetProperties(kError, kError);
       return;
     }
@@ -27,9 +20,7 @@ void Replace(const std::vector<LabelFstClassPair> &pairs, MutableFstClass *ofst,
   Apply<Operation<ReplaceArgs>>("Replace", ofst->ArcType(), &args);
 }
 
-REGISTER_FST_OPERATION(Replace, StdArc, ReplaceArgs);
-REGISTER_FST_OPERATION(Replace, LogArc, ReplaceArgs);
-REGISTER_FST_OPERATION(Replace, Log64Arc, ReplaceArgs);
+REGISTER_FST_OPERATION_3ARCS(Replace, ReplaceArgs);
 
 }  // namespace script
 }  // namespace fst
index d411fee..066e4ac 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/reverse.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -19,9 +18,7 @@ void Reverse(const FstClass &ifst, MutableFstClass *ofst,
   Apply<Operation<ReverseArgs>>("Reverse", ifst.ArcType(), &args);
 }
 
-REGISTER_FST_OPERATION(Reverse, StdArc, ReverseArgs);
-REGISTER_FST_OPERATION(Reverse, LogArc, ReverseArgs);
-REGISTER_FST_OPERATION(Reverse, Log64Arc, ReverseArgs);
+REGISTER_FST_OPERATION_3ARCS(Reverse, ReverseArgs);
 
 }  // namespace script
 }  // namespace fst
index 3018ded..bd4be66 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/reweight.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -15,9 +14,7 @@ void Reweight(MutableFstClass *fst, const std::vector<WeightClass> &potential,
   Apply<Operation<ReweightArgs>>("Reweight", fst->ArcType(), &args);
 }
 
-REGISTER_FST_OPERATION(Reweight, StdArc, ReweightArgs);
-REGISTER_FST_OPERATION(Reweight, LogArc, ReweightArgs);
-REGISTER_FST_OPERATION(Reweight, Log64Arc, ReweightArgs);
+REGISTER_FST_OPERATION_3ARCS(Reweight, ReweightArgs);
 
 }  // namespace script
 }  // namespace fst
index 9757b00..e9886dd 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/rmepsilon.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -18,9 +17,7 @@ void RmEpsilon(MutableFstClass *fst, const RmEpsilonOptions &opts) {
   Apply<Operation<RmEpsilonArgs>>("RmEpsilon", fst->ArcType(), &args);
 }
 
-REGISTER_FST_OPERATION(RmEpsilon, StdArc, RmEpsilonArgs);
-REGISTER_FST_OPERATION(RmEpsilon, LogArc, RmEpsilonArgs);
-REGISTER_FST_OPERATION(RmEpsilon, Log64Arc, RmEpsilonArgs);
+REGISTER_FST_OPERATION_3ARCS(RmEpsilon, RmEpsilonArgs);
 
 }  // namespace script
 }  // namespace fst
index 70c9cbb..567ff51 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/shortest-distance.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -23,13 +22,8 @@ void ShortestDistance(const FstClass &ifst, std::vector<WeightClass> *distance,
                                           &args);
 }
 
-REGISTER_FST_OPERATION(ShortestDistance, StdArc, ShortestDistanceArgs1);
-REGISTER_FST_OPERATION(ShortestDistance, LogArc, ShortestDistanceArgs1);
-REGISTER_FST_OPERATION(ShortestDistance, Log64Arc, ShortestDistanceArgs1);
-
-REGISTER_FST_OPERATION(ShortestDistance, StdArc, ShortestDistanceArgs2);
-REGISTER_FST_OPERATION(ShortestDistance, LogArc, ShortestDistanceArgs2);
-REGISTER_FST_OPERATION(ShortestDistance, Log64Arc, ShortestDistanceArgs2);
+REGISTER_FST_OPERATION_3ARCS(ShortestDistance, ShortestDistanceArgs1);
+REGISTER_FST_OPERATION_3ARCS(ShortestDistance, ShortestDistanceArgs2);
 
 }  // namespace script
 }  // namespace fst
index 08630e3..09d4f4f 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/shortest-path.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -19,9 +18,7 @@ void ShortestPath(const FstClass &ifst, MutableFstClass *ofst,
   Apply<Operation<ShortestPathArgs>>("ShortestPath", ifst.ArcType(), &args);
 }
 
-REGISTER_FST_OPERATION(ShortestPath, StdArc, ShortestPathArgs);
-REGISTER_FST_OPERATION(ShortestPath, LogArc, ShortestPathArgs);
-REGISTER_FST_OPERATION(ShortestPath, Log64Arc, ShortestPathArgs);
+REGISTER_FST_OPERATION_3ARCS(ShortestPath, ShortestPathArgs);
 
 }  // namespace script
 }  // namespace fst
index 91d60b7..6a258b8 100644 (file)
@@ -14,12 +14,8 @@ StateIteratorClass::StateIteratorClass(const FstClass &fst) : impl_(nullptr) {
                                                fst.ArcType(), &args);
 }
 
-REGISTER_FST_OPERATION(InitStateIteratorClass, StdArc,
-                       InitStateIteratorClassArgs);
-REGISTER_FST_OPERATION(InitStateIteratorClass, LogArc,
-                       InitStateIteratorClassArgs);
-REGISTER_FST_OPERATION(InitStateIteratorClass, Log64Arc,
-                       InitStateIteratorClassArgs);
+REGISTER_FST_OPERATION_3ARCS(InitStateIteratorClass,
+                             InitStateIteratorClassArgs);
 
 }  // namespace script
 }  // namespace fst
index de34b81..f40e47b 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/synchronize.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -18,9 +17,7 @@ void Synchronize(const FstClass &ifst, MutableFstClass *ofst) {
   Apply<Operation<SynchronizeArgs>>("Synchronize", ifst.ArcType(), &args);
 }
 
-REGISTER_FST_OPERATION(Synchronize, StdArc, SynchronizeArgs);
-REGISTER_FST_OPERATION(Synchronize, LogArc, SynchronizeArgs);
-REGISTER_FST_OPERATION(Synchronize, Log64Arc, SynchronizeArgs);
+REGISTER_FST_OPERATION_3ARCS(Synchronize, SynchronizeArgs);
 
 }  // namespace script
 }  // namespace fst
index 720e2d6..a490557 100644 (file)
@@ -4,7 +4,6 @@
 #include <fst/script/text-io.h>
 
 #include <cstring>
-#include <fstream>
 #include <ostream>
 #include <sstream>
 #include <utility>
@@ -17,11 +16,11 @@ namespace fst {
 namespace script {
 
 // Reads vector of weights; returns true on success.
-bool ReadPotentials(const std::string &weight_type, const std::string &filename,
+bool ReadPotentials(const std::string &weight_type, const std::string &source,
                     std::vector<WeightClass> *potentials) {
-  std::ifstream istrm(filename);
-  if (!istrm.good()) {
-    LOG(ERROR) << "ReadPotentials: Can't open file: " << filename;
+  std::ifstream istrm(source);
+  if (!istrm) {
+    LOG(ERROR) << "ReadPotentials: Can't open file: " << source;
     return false;
   }
   static constexpr int kLineLen = 8096;
@@ -35,10 +34,10 @@ bool ReadPotentials(const std::string &weight_type, const std::string &filename,
     if (col.empty() || col[0][0] == '\0') continue;
     if (col.size() != 2) {
       FSTERROR() << "ReadPotentials: Bad number of columns, "
-                 << "file = " << filename << ", line = " << nline;
+                 << "file = " << source << ", line = " << nline;
       return false;
     }
-    const ssize_t s = StrToInt64(col[0], filename, nline, false);
+    const ssize_t s = StrToInt64(col[0], source, nline, false);
     const WeightClass weight(weight_type, col[1]);
     while (potentials->size() <= s) {
       potentials->push_back(WeightClass::Zero(weight_type));
@@ -49,13 +48,13 @@ bool ReadPotentials(const std::string &weight_type, const std::string &filename,
 }
 
 // Writes vector of weights; returns true on success.
-bool WritePotentials(const std::string &filename,
+bool WritePotentials(const std::string &source,
                      const std::vector<WeightClass> &potentials) {
   std::ofstream ostrm;
-  if (!filename.empty()) {
-    ostrm.open(filename);
-    if (!ostrm.good()) {
-      LOG(ERROR) << "WritePotentials: Can't open file: " << filename;
+  if (!source.empty()) {
+    ostrm.open(source);
+    if (!ostrm) {
+      LOG(ERROR) << "WritePotentials: Can't open file: " << source;
       return false;
     }
   }
@@ -66,7 +65,7 @@ bool WritePotentials(const std::string &filename,
   }
   if (strm.fail()) {
     LOG(ERROR) << "WritePotentials: Write failed: "
-               << (filename.empty() ? "standard output" : filename);
+               << (source.empty() ? "standard output" : source);
     return false;
   }
   return true;
index 36d6fc8..faf5021 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/topsort.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -15,9 +14,7 @@ bool TopSort(MutableFstClass *fst) {
   return args.retval;
 }
 
-REGISTER_FST_OPERATION(TopSort, StdArc, TopSortArgs);
-REGISTER_FST_OPERATION(TopSort, LogArc, TopSortArgs);
-REGISTER_FST_OPERATION(TopSort, Log64Arc, TopSortArgs);
+REGISTER_FST_OPERATION_3ARCS(TopSort, TopSortArgs);
 
 }  // namespace script
 }  // namespace fst
index 31b83b9..e264b28 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/union.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -14,13 +13,23 @@ void Union(MutableFstClass *fst1, const FstClass &fst2) {
     fst1->SetProperties(kError, kError);
     return;
   }
-  UnionArgs args(fst1, fst2);
-  Apply<Operation<UnionArgs>>("Union", fst1->ArcType(), &args);
+  UnionArgs1 args(fst1, fst2);
+  Apply<Operation<UnionArgs1>>("Union", fst1->ArcType(), &args);
 }
 
-REGISTER_FST_OPERATION(Union, StdArc, UnionArgs);
-REGISTER_FST_OPERATION(Union, LogArc, UnionArgs);
-REGISTER_FST_OPERATION(Union, Log64Arc, UnionArgs);
+void Union(MutableFstClass *fst1, const std::vector<const FstClass *> &fsts2) {
+  for (const auto *fst2 : fsts2) {
+    if (!internal::ArcTypesMatch(*fst1, *fst2, "Union")) {
+      fst1->SetProperties(kError, kError);
+      return;
+    }
+  }
+  UnionArgs2 args(fst1, fsts2);
+  Apply<Operation<UnionArgs2>>("Union", fst1->ArcType(), &args);
+}
+
+REGISTER_FST_OPERATION_3ARCS(Union, UnionArgs1);
+REGISTER_FST_OPERATION_3ARCS(Union, UnionArgs2);
 
 }  // namespace script
 }  // namespace fst
index 848abcb..367cd74 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <fst/script/verify.h>
 
-#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -15,9 +14,7 @@ bool Verify(const FstClass &fst) {
   return args.retval;
 }
 
-REGISTER_FST_OPERATION(Verify, StdArc, VerifyArgs);
-REGISTER_FST_OPERATION(Verify, LogArc, VerifyArgs);
-REGISTER_FST_OPERATION(Verify, Log64Arc, VerifyArgs);
+REGISTER_FST_OPERATION_3ARCS(Verify, VerifyArgs);
 
 }  // namespace script
 }  // namespace fst
index ab45f9c..ea525c0 100644 (file)
@@ -22,6 +22,10 @@ WeightClass::WeightClass(const std::string &weight_type,
   impl_.reset(stw(weight_str, "WeightClass", 0));
 }
 
+constexpr char WeightClass::__ZERO__[];
+constexpr char WeightClass::__ONE__[];
+constexpr char WeightClass::__NOWEIGHT__[];
+
 WeightClass WeightClass::Zero(const std::string &weight_type) {
   return WeightClass(weight_type, __ZERO__);
 }
@@ -34,11 +38,12 @@ WeightClass WeightClass::NoWeight(const std::string &weight_type) {
   return WeightClass(weight_type, __NOWEIGHT__);
 }
 
-bool WeightClass::WeightTypesMatch(const WeightClass &other,
-                                   const std::string &op_name) const {
-  if (Type() != other.Type()) {
+bool WeightClass::WeightTypesMatch(const WeightClass &lhs,
+                                   const WeightClass &rhs,
+                                   const std::string &op_name) {
+  if (lhs.Type() != rhs.Type()) {
     FSTERROR() << "Weights with non-matching types passed to " << op_name
-               << ": " << Type() << " and " << other.Type();
+               << ": " << lhs.Type() << " and " << rhs.Type();
     return false;
   }
   return true;
@@ -47,7 +52,8 @@ bool WeightClass::WeightTypesMatch(const WeightClass &other,
 bool operator==(const WeightClass &lhs, const WeightClass &rhs) {
   const auto *lhs_impl = lhs.GetImpl();
   const auto *rhs_impl = rhs.GetImpl();
-  if (!(lhs_impl && rhs_impl && lhs.WeightTypesMatch(rhs, "operator=="))) {
+  if (!(lhs_impl && rhs_impl &&
+        WeightClass::WeightTypesMatch(lhs, rhs, "operator=="))) {
     return false;
   }
   return *lhs_impl == *rhs_impl;
@@ -59,7 +65,8 @@ bool operator!=(const WeightClass &lhs, const WeightClass &rhs) {
 
 WeightClass Plus(const WeightClass &lhs, const WeightClass &rhs) {
   const auto *rhs_impl = rhs.GetImpl();
-  if (!(lhs.GetImpl() && rhs_impl && lhs.WeightTypesMatch(rhs, "Plus"))) {
+  if (!(lhs.GetImpl() && rhs_impl &&
+        WeightClass::WeightTypesMatch(lhs, rhs, "Plus"))) {
     return WeightClass();
   }
   WeightClass result(lhs);
@@ -69,7 +76,8 @@ WeightClass Plus(const WeightClass &lhs, const WeightClass &rhs) {
 
 WeightClass Times(const WeightClass &lhs, const WeightClass &rhs) {
   const auto *rhs_impl = rhs.GetImpl();
-  if (!(lhs.GetImpl() && rhs_impl && lhs.WeightTypesMatch(rhs, "Plus"))) {
+  if (!(lhs.GetImpl() && rhs_impl &&
+        WeightClass::WeightTypesMatch(lhs, rhs, "Times"))) {
     return WeightClass();
   }
   WeightClass result(lhs);
@@ -79,7 +87,8 @@ WeightClass Times(const WeightClass &lhs, const WeightClass &rhs) {
 
 WeightClass Divide(const WeightClass &lhs, const WeightClass &rhs) {
   const auto *rhs_impl = rhs.GetImpl();
-  if (!(lhs.GetImpl() && rhs_impl && lhs.WeightTypesMatch(rhs, "Divide"))) {
+  if (!(lhs.GetImpl() && rhs_impl &&
+        WeightClass::WeightTypesMatch(lhs, rhs, "Divide"))) {
     return WeightClass();
   }
   WeightClass result(lhs);
index 333adad..b98c4d2 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -93,7 +93,7 @@ check_PROGRAMS = fst_test$(EXEEXT) weight_test$(EXEEXT) \
        algo_test_power$(EXEEXT)
 subdir = src/test
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_python_devel.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
        $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
@@ -160,7 +160,14 @@ am__v_at_0 = @
 am__v_at_1 = 
 DEFAULT_INCLUDES = 
 depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade =  \
+       ./$(DEPDIR)/algo_test_lexicographic-algo_test.Po \
+       ./$(DEPDIR)/algo_test_log-algo_test.Po \
+       ./$(DEPDIR)/algo_test_minmax-algo_test.Po \
+       ./$(DEPDIR)/algo_test_power-algo_test.Po \
+       ./$(DEPDIR)/algo_test_tropical-algo_test.Po \
+       ./$(DEPDIR)/fst_test.Po ./$(DEPDIR)/weight_test.Po
 am__mv = mv -f
 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
        $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
@@ -486,7 +493,7 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
-PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIBS = @PYTHON_LIBS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
@@ -593,8 +600,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
          *config.status*) \
            cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
          *) \
-           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
        esac;
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@@ -649,13 +656,19 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/algo_test_lexicographic-algo_test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/algo_test_log-algo_test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/algo_test_minmax-algo_test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/algo_test_power-algo_test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/algo_test_tropical-algo_test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fst_test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/weight_test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/algo_test_lexicographic-algo_test.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/algo_test_log-algo_test.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/algo_test_minmax-algo_test.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/algo_test_power-algo_test.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/algo_test_tropical-algo_test.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fst_test.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/weight_test.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+       @$(MKDIR_P) $(@D)
+       @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
 
 .cc.o:
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -929,7 +942,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
        fi;                                                             \
        $$success || exit 1
 
-check-TESTS:
+check-TESTS: $(check_PROGRAMS)
        @list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
        @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
        @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
@@ -1014,7 +1027,10 @@ algo_test_power.log: algo_test_power$(EXEEXT)
 @am__EXEEXT_TRUE@      $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
 @am__EXEEXT_TRUE@      "$$tst" $(AM_TESTS_FD_REDIRECT)
 
-distdir: $(DISTFILES)
+distdir: $(BUILT_SOURCES)
+       $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
        @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
        list='$(DISTFILES)'; \
@@ -1089,7 +1105,13 @@ clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
        mostlyclean-am
 
 distclean: distclean-am
-       -rm -rf ./$(DEPDIR)
+               -rm -f ./$(DEPDIR)/algo_test_lexicographic-algo_test.Po
+       -rm -f ./$(DEPDIR)/algo_test_log-algo_test.Po
+       -rm -f ./$(DEPDIR)/algo_test_minmax-algo_test.Po
+       -rm -f ./$(DEPDIR)/algo_test_power-algo_test.Po
+       -rm -f ./$(DEPDIR)/algo_test_tropical-algo_test.Po
+       -rm -f ./$(DEPDIR)/fst_test.Po
+       -rm -f ./$(DEPDIR)/weight_test.Po
        -rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
        distclean-tags
@@ -1135,7 +1157,13 @@ install-ps-am:
 installcheck-am:
 
 maintainer-clean: maintainer-clean-am
-       -rm -rf ./$(DEPDIR)
+               -rm -f ./$(DEPDIR)/algo_test_lexicographic-algo_test.Po
+       -rm -f ./$(DEPDIR)/algo_test_log-algo_test.Po
+       -rm -f ./$(DEPDIR)/algo_test_minmax-algo_test.Po
+       -rm -f ./$(DEPDIR)/algo_test_power-algo_test.Po
+       -rm -f ./$(DEPDIR)/algo_test_tropical-algo_test.Po
+       -rm -f ./$(DEPDIR)/fst_test.Po
+       -rm -f ./$(DEPDIR)/weight_test.Po
        -rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
@@ -1156,16 +1184,16 @@ uninstall-am:
 
 .MAKE: check-am install-am install-strip
 
-.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
-       clean-checkPROGRAMS clean-generic clean-libtool cscopelist-am \
-       ctags ctags-am distclean distclean-compile distclean-generic \
-       distclean-libtool distclean-tags distdir dvi dvi-am html \
-       html-am info info-am install install-am install-data \
-       install-data-am install-dvi install-dvi-am install-exec \
-       install-exec-am install-html install-html-am install-info \
-       install-info-am install-man install-pdf install-pdf-am \
-       install-ps install-ps-am install-strip installcheck \
-       installcheck-am installdirs maintainer-clean \
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+       check-am clean clean-checkPROGRAMS clean-generic clean-libtool \
+       cscopelist-am ctags ctags-am distclean distclean-compile \
+       distclean-generic distclean-libtool distclean-tags distdir dvi \
+       dvi-am html html-am info info-am install install-am \
+       install-data install-data-am install-dvi install-dvi-am \
+       install-exec install-exec-am install-html install-html-am \
+       install-info install-info-am install-man install-pdf \
+       install-pdf-am install-ps install-ps-am install-strip \
+       installcheck installcheck-am installdirs maintainer-clean \
        maintainer-clean-generic mostlyclean mostlyclean-compile \
        mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
        recheck tags tags-am uninstall uninstall-am
index 63404b8..014b826 100644 (file)
@@ -6,7 +6,6 @@
 #include <fst/test/algo_test.h>
 
 #include <cstdlib>
-
 #include <vector>
 
 #include <fst/flags.h>
index 990084d..a9d7c5e 100644 (file)
@@ -5,26 +5,25 @@
 
 #include <fst/test/fst_test.h>
 
-#include <utility>
-
 #include <fst/flags.h>
 #include <fst/log.h>
 #include <fst/compact-fst.h>
 #include <fst/const-fst.h>
 #include <fst/edit-fst.h>
 #include <fst/matcher-fst.h>
+#include <fst/test/compactors.h>
 
 namespace fst {
 namespace {
 
 // A user-defined arc type.
 struct CustomArc {
-  typedef int16 Label;
-  typedef ProductWeight<TropicalWeight, LogWeight> Weight;
-  typedef int64 StateId;
+  using Label = int16;
+  using Weight = ProductWeight<TropicalWeight, LogWeight>;
+  using StateId = int64;
 
   CustomArc(Label i, Label o, Weight w, StateId s)
-      : ilabel(i), olabel(o), weight(std::move(w)), nextstate(s) {}
+      : ilabel(i), olabel(o), weight(w), nextstate(s) {}
   CustomArc() {}
 
   static const std::string &Type() {  // Arc type name
@@ -38,69 +37,40 @@ struct CustomArc {
   StateId nextstate;  // Transition destination state
 };
 
-// A user-defined compactor for test FST.
-template <class A>
-class CustomCompactor {
- public:
-  typedef A Arc;
-  typedef typename A::Label Label;
-  typedef typename A::StateId StateId;
-  typedef typename A::Weight Weight;
-  typedef std::pair<Label, Weight> Element;
-
-  Element Compact(StateId s, const A &arc) const {
-    return std::make_pair(arc.ilabel, arc.weight);
-  }
-
-  Arc Expand(StateId s, const Element &p, uint32 f = kArcValueFlags) const {
-    return p.first == kNoLabel ? Arc(kNoLabel, kNoLabel, p.second, kNoStateId)
-                               : Arc(p.first, 0, p.second, s);
-  }
-
-  ssize_t Size() const { return -1; }
-
-  uint64 Properties() const { return 0ULL; }
-
-  bool Compatible(const Fst<A> &fst) const { return true; }
-
-  static const std::string &Type() {
-    static const std::string *const type = new std::string("my");
-    return *type;
-  }
-
-  bool Write(std::ostream &strm) const { return true; }
-
-  static CustomCompactor *Read(std::istream &strm) {
-    return new CustomCompactor;
-  }
-};
-
 REGISTER_FST(VectorFst, CustomArc);
 REGISTER_FST(ConstFst, CustomArc);
-static fst::FstRegisterer<CompactFst<StdArc, CustomCompactor<StdArc>>>
-    CompactFst_StdArc_CustomCompactor_registerer;
-static fst::FstRegisterer<CompactFst<CustomArc, CustomCompactor<CustomArc>>>
-    CompactFst_CustomArc_CustomCompactor_registerer;
+static fst::FstRegisterer<
+    CompactArcFst<StdArc, TrivialArcCompactor<StdArc>>>
+    CompactFst_StdArc_TrivialCompactor_registerer;
+static fst::FstRegisterer<
+    CompactArcFst<CustomArc, TrivialArcCompactor<CustomArc>>>
+    CompactFst_CustomArc_TrivialCompactor_registerer;
 static fst::FstRegisterer<ConstFst<StdArc, uint16>>
     ConstFst_StdArc_uint16_registerer;
 static fst::FstRegisterer<
-    CompactFst<StdArc, CustomCompactor<StdArc>, uint16>>
-    CompactFst_StdArc_CustomCompactor_uint16_registerer;
+    CompactArcFst<StdArc, TrivialArcCompactor<StdArc>, uint16>>
+    CompactFst_StdArc_TrivialCompactor_uint16_registerer;
+static fst::FstRegisterer<CompactFst<StdArc, TrivialCompactor<StdArc>>>
+    CompactFst_StdArc_CustomCompactor_registerer;
+static fst::FstRegisterer<
+    CompactFst<CustomArc, TrivialCompactor<CustomArc>>>
+    CompactFst_CustomArc_CustomCompactor_registerer;
 
 }  // namespace
 }  // namespace fst
 
-using fst::FstTester;
-using fst::VectorFst;
+using fst::CompactArcFst;
+using fst::CompactFst;
 using fst::ConstFst;
+using fst::CustomArc;
+using fst::EditFst;
+using fst::FstTester;
 using fst::MatcherFst;
-using fst::CompactFst;
-using fst::Fst;
 using fst::StdArc;
-using fst::CustomArc;
-using fst::CustomCompactor;
 using fst::StdArcLookAheadFst;
-using fst::EditFst;
+using fst::TrivialArcCompactor;
+using fst::TrivialCompactor;
+using fst::VectorFst;
 
 int main(int argc, char **argv) {
   FLAGS_fst_verify_properties = true;
@@ -109,13 +79,30 @@ int main(int argc, char **argv) {
 
   // VectorFst<StdArc> tests
   {
-    FstTester<VectorFst<StdArc>> std_vector_tester;
-    std_vector_tester.TestBase();
-    std_vector_tester.TestExpanded();
-    std_vector_tester.TestAssign();
-    std_vector_tester.TestCopy();
-    std_vector_tester.TestIO();
-    std_vector_tester.TestMutable();
+    for (const size_t num_states : {0, 1, 2, 3, 128}) {
+      FstTester<VectorFst<StdArc>> std_vector_tester(num_states);
+      std_vector_tester.TestBase();
+      std_vector_tester.TestExpanded();
+      std_vector_tester.TestAssign();
+      std_vector_tester.TestCopy();
+      std_vector_tester.TestIO();
+      std_vector_tester.TestMutable();
+    }
+
+    // Test with a default-constructed Fst, not a copied Fst.
+    FstTester<VectorFst<StdArc>> empty_tester(/*num_states=*/0);
+    {
+      const VectorFst<StdArc> empty_fst;
+      empty_tester.TestBase(empty_fst);
+      empty_tester.TestExpanded(empty_fst);
+      empty_tester.TestCopy(empty_fst);
+      empty_tester.TestIO(empty_fst);
+      empty_tester.TestAssign(empty_fst);
+    }
+    {
+      VectorFst<StdArc> empty_fst;
+      empty_tester.TestMutable(&empty_fst);
+    }
   }
 
   // ConstFst<StdArc> tests
@@ -127,15 +114,30 @@ int main(int argc, char **argv) {
     std_const_tester.TestIO();
   }
 
-  // CompactFst<StdArc, CustomCompactor<StdArc>>
+  // CompactArcFst<StdArc, TrivialArcCompactor<StdArc>>
   {
-    FstTester<CompactFst<StdArc, CustomCompactor<StdArc>>> std_compact_tester;
+    FstTester<CompactArcFst<StdArc, TrivialArcCompactor<StdArc>>>
+        std_compact_tester;
     std_compact_tester.TestBase();
     std_compact_tester.TestExpanded();
     std_compact_tester.TestCopy();
     std_compact_tester.TestIO();
   }
 
+  // CompactFst<StdArc, TrivialArcCompactor<StdArc>>
+  {
+    for (const size_t num_states : {0, 1, 2, 3, 128}) {
+      FstTester<CompactFst<StdArc, TrivialCompactor<StdArc>>>
+          std_compact_tester(num_states);
+      std_compact_tester.TestBase();
+      std_compact_tester.TestExpanded();
+      std_compact_tester.TestCopy();
+      std_compact_tester.TestIO();
+    }
+
+    // TODO(jrosenstock): Add tests on default-constructed Fst.
+  }
+
   // VectorFst<CustomArc> tests
   {
     FstTester<VectorFst<CustomArc>> std_vector_tester;
@@ -156,14 +158,42 @@ int main(int argc, char **argv) {
     std_const_tester.TestIO();
   }
 
-  // CompactFst<CustomArc, CustomCompactor<CustomArc>>
+  // CompactArcFst<CustomArc, TrivialArcCompactor<CustomArc>>
   {
-    FstTester<CompactFst<CustomArc, CustomCompactor<CustomArc>>>
-        std_compact_tester;
-    std_compact_tester.TestBase();
-    std_compact_tester.TestExpanded();
-    std_compact_tester.TestCopy();
-    std_compact_tester.TestIO();
+    for (const size_t num_states : {0, 1, 2, 3, 128}) {
+      FstTester<CompactArcFst<CustomArc, TrivialArcCompactor<CustomArc>>>
+          std_compact_tester(num_states);
+      std_compact_tester.TestBase();
+      std_compact_tester.TestExpanded();
+      std_compact_tester.TestCopy();
+      std_compact_tester.TestIO();
+    }
+
+    // TODO(jrosenstock): Make this work.
+#if 0
+    // Test with a default-constructed Fst, not a copied Fst.
+    FstTester<CompactArcFst<CustomArc, CustomCompactor<CustomArc>>>
+        empty_tester(/*num_states=*/0);
+    const CompactArcFst<CustomArc, CustomCompactor<CustomArc>> empty_fst;
+    empty_tester.TestBase(empty_fst);
+    empty_tester.TestExpanded(empty_fst);
+    empty_tester.TestCopy(empty_fst);
+    empty_tester.TestIO(empty_fst);
+#endif
+  }
+
+  // CompactFst<CustomArc, TrivialArcCompactor<CustomArc>>
+  {
+    for (const size_t num_states : {0, 1, 2, 3, 128}) {
+      FstTester<CompactFst<CustomArc, TrivialCompactor<CustomArc>>>
+          std_compact_tester(num_states);
+      std_compact_tester.TestBase();
+      std_compact_tester.TestExpanded();
+      std_compact_tester.TestCopy();
+      std_compact_tester.TestIO();
+    }
+
+    // TODO(jrosenstock): Add tests on default-constructed Fst.
   }
 
   // ConstFst<StdArc, uint16> tests
@@ -175,9 +205,9 @@ int main(int argc, char **argv) {
     std_const_tester.TestIO();
   }
 
-  // CompactFst<StdArc, CustomCompactor<StdArc>, uint16>
+  // CompactArcFst<StdArc, TrivialArcCompactor<StdArc>, uint16>
   {
-    FstTester<CompactFst<StdArc, CustomCompactor<StdArc>, uint16>>
+    FstTester<CompactArcFst<StdArc, TrivialArcCompactor<StdArc>, uint16>>
         std_compact_tester;
     std_compact_tester.TestBase();
     std_compact_tester.TestExpanded();
index 8e575b0..b8521a4 100755 (executable)
@@ -1,9 +1,9 @@
 #! /bin/sh
 # test-driver - basic testsuite driver script.
 
-scriptversion=2013-07-13.22; # UTC
+scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 2011-2014 Free Software Foundation, Inc.
+# Copyright (C) 2011-2018 Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@ scriptversion=2013-07-13.22; # UTC
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -140,9 +140,9 @@ echo ":copy-in-global-log: $gcopy" >> $trs_file
 # Local Variables:
 # mode: shell-script
 # sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-time-zone: "UTC0"
 # time-stamp-end: "; # UTC"
 # End: