From ca3da3a815b6e85531d6ded07e7d6bec7852748c Mon Sep 17 00:00:00 2001
From: Michael Denkowski <michael.j.denkowski@gmail.com>
Date: Thu, 24 Jan 2013 16:55:21 -0500
Subject: Scored grammars from online extraction.  Don't trust them yet.

---
 python/pkg/cdec/sa/extract.py   |  6 ++--
 python/pkg/cdec/sa/extractor.py | 15 ++++++++--
 python/pkg/cdec/sa/features.py  | 61 +++++++++++++++++++++++++++++++++++------
 3 files changed, 68 insertions(+), 14 deletions(-)

(limited to 'python/pkg/cdec')

diff --git a/python/pkg/cdec/sa/extract.py b/python/pkg/cdec/sa/extract.py
index 9fc37345..20eab9dd 100644
--- a/python/pkg/cdec/sa/extract.py
+++ b/python/pkg/cdec/sa/extract.py
@@ -12,10 +12,10 @@ extractor, prefix = None, None
 online = False
 
 def make_extractor(config, grammars, features):
-    global extractor, prefix
+    global extractor, prefix, online
     signal.signal(signal.SIGINT, signal.SIG_IGN) # Let parent process catch Ctrl+C
     load_features(features)
-    extractor = cdec.sa.GrammarExtractor(config)
+    extractor = cdec.sa.GrammarExtractor(config, online)
     prefix = grammars
 
 def load_features(features):
@@ -53,7 +53,7 @@ def extract(inp):
     # Add training instance _after_ extracting grammars
     if online:
         extractor.add_instance(sentence, reference, alignment)
-        extractor.dump_online_stats()
+        #extractor.dump_online_stats()
     grammar_file = os.path.abspath(grammar_file)
     return '<seg grammar="{0}" id="{1}"> {2} </seg>{3}'.format(grammar_file, i, sentence, suffix)
 
diff --git a/python/pkg/cdec/sa/extractor.py b/python/pkg/cdec/sa/extractor.py
index 62a251a7..5ef8041c 100644
--- a/python/pkg/cdec/sa/extractor.py
+++ b/python/pkg/cdec/sa/extractor.py
@@ -2,14 +2,15 @@ from itertools import chain
 import os, sys
 import cdec.configobj
 from cdec.sa.features import EgivenFCoherent, SampleCountF, CountEF,\
-        MaxLexEgivenF, MaxLexFgivenE, IsSingletonF, IsSingletonFE
+        MaxLexEgivenF, MaxLexFgivenE, IsSingletonF, IsSingletonFE,\
+        IsSupportedOnline
 import cdec.sa
 
 # maximum span of a grammar rule in TEST DATA
 MAX_INITIAL_SIZE = 15
 
 class GrammarExtractor:
-    def __init__(self, config, features=None):
+    def __init__(self, config, online=False, features=None):
         if isinstance(config, basestring):
             if not os.path.exists(config):
                 raise IOError('cannot read configuration from {0}'.format(config))
@@ -57,11 +58,19 @@ class GrammarExtractor:
         # lexical weighting tables
         tt = cdec.sa.BiLex(from_binary=config['lex_file'])
 
+        # TODO: clean this up
+        extended_features = []
+        #extended_features.append(IsSupportedOnline)
+        if online:
+            extended_features.append(IsSupportedOnline)
+            
         # TODO: use @cdec.sa.features decorator for standard features too
         # + add a mask to disable features
+        for f in cdec.sa._SA_FEATURES:
+            extended_features.append(f)
         scorer = cdec.sa.Scorer(EgivenFCoherent, SampleCountF, CountEF, 
             MaxLexFgivenE(tt), MaxLexEgivenF(tt), IsSingletonF, IsSingletonFE,
-            *cdec.sa._SA_FEATURES)
+            *extended_features)
 
         fsarray = cdec.sa.SuffixArray(from_binary=config['f_sa_file'])
         edarray = cdec.sa.DataArray(from_binary=config['e_file'])
diff --git a/python/pkg/cdec/sa/features.py b/python/pkg/cdec/sa/features.py
index a4ae23e8..cede5304 100644
--- a/python/pkg/cdec/sa/features.py
+++ b/python/pkg/cdec/sa/features.py
@@ -4,20 +4,39 @@ import math
 MAXSCORE = 99
 
 def EgivenF(ctx): # p(e|f) = c(e, f)/c(f)
-    return -math.log10(ctx.paircount/ctx.fcount)
+    if not ctx.online:
+        prob = ctx.paircount/ctx.fcount
+    else:
+        prob = (ctx.paircount + ctx.online.paircount) / (ctx.fcount + ctx.online.fcount)
+    return -math.log10(prob)
 
 def CountEF(ctx): # c(e, f)
-    return math.log10(1 + ctx.paircount)
+    if not ctx.online:
+        count = 1 + ctx.paircount
+    else:
+        count = 1 + ctx.paircount + ctx.online.paircount
+    return math.log10(count)
 
 def SampleCountF(ctx): # sample c(f)
-    return math.log10(1 + ctx.fsample_count)
+    if not ctx.online:
+        count = 1 + ctx.fsample_count
+    else:
+        count = 1 + ctx.fsample_count + ctx.online.fcount
+    return math.log10(count)
 
 def EgivenFCoherent(ctx): # c(e, f) / sample c(f)
-    prob = ctx.paircount/ctx.fsample_count
+    if not ctx.online:
+        prob = ctx.paircount/ctx.fsample_count
+    else:
+        prob = (ctx.paircount + ctx.online.paircount) / (ctx.fsample_count + ctx.online.fcount)
     return -math.log10(prob) if prob > 0 else MAXSCORE
 
 def CoherenceProb(ctx): # c(f) / sample c(f)
-    return -math.log10(ctx.fcount/ctx.fsample_count)
+    if not ctx.online:
+        prob = ctx.fcount/ctx.fsample_count
+    else:
+        prob = (ctx.fcount + ctx.online.fcount) / (ctx.fsample_count + ctx.online.fcount)
+    return -math.log10(prob)
 
 def MaxLexEgivenF(ttable):
     def MaxLexEgivenF(ctx):
@@ -42,16 +61,42 @@ def MaxLexFgivenE(ttable):
     return MaxLexFgivenE
 
 def IsSingletonF(ctx):
-    return (ctx.fcount == 1)
+    if not ctx.online:
+        count = ctx.fcount
+    else:
+        count = ctx.fcount + ctx.online.fcount  
+    return (count == 1)
 
 def IsSingletonFE(ctx):
-    return (ctx.paircount == 1)
+    if not ctx.online:
+        count = ctx.paircount
+    else:
+        count = ctx.paircount + ctx.online.paircount
+    return (count == 1)
 
 def IsNotSingletonF(ctx):
-    return (ctx.fcount > 1)
+    if not ctx.online:
+        count = ctx.fcount
+    else:
+        count = ctx.fcount + ctx.online.fcount
+    return (count > 1)
 
 def IsNotSingletonFE(ctx):
+    if not ctx.online:
+        count = ctx.paircount
+    else:
+        count = ctx.paircount + ctx.online.paircount
     return (ctx.paircount > 1)
 
 def IsFEGreaterThanZero(ctx):
+    if not ctx.online:
+        count = ctx.paircount
+    else:
+        count = ctx.paircount + ctx.online.paircount
     return (ctx.paircount > 0.01)
+
+def IsSupportedOnline(ctx):
+    if ctx.online:
+        return (ctx.online.fcount > 0.01)
+    else:
+        return False
\ No newline at end of file
-- 
cgit v1.2.3


From 0a6dbb8aefb1662a68f3f14f0c42a72150d8be03 Mon Sep 17 00:00:00 2001
From: Michael Denkowski <michael.j.denkowski@gmail.com>
Date: Sat, 26 Jan 2013 21:12:25 -0500
Subject: Online grammars now diff with incremental suffix array (except lex,
 TODO)

---
 python/pkg/cdec/sa/extract.py   |     1 -
 python/pkg/cdec/sa/extractor.py |    10 +-
 python/pkg/cdec/sa/features.py  |     8 +-
 python/src/sa/_sa.c             | 11925 ++++++++++++++++++--------------------
 python/src/sa/rulefactory.pxi   |    87 +-
 5 files changed, 5656 insertions(+), 6375 deletions(-)

(limited to 'python/pkg/cdec')

diff --git a/python/pkg/cdec/sa/extract.py b/python/pkg/cdec/sa/extract.py
index 20eab9dd..2e596bd3 100644
--- a/python/pkg/cdec/sa/extract.py
+++ b/python/pkg/cdec/sa/extract.py
@@ -53,7 +53,6 @@ def extract(inp):
     # Add training instance _after_ extracting grammars
     if online:
         extractor.add_instance(sentence, reference, alignment)
-        #extractor.dump_online_stats()
     grammar_file = os.path.abspath(grammar_file)
     return '<seg grammar="{0}" id="{1}"> {2} </seg>{3}'.format(grammar_file, i, sentence, suffix)
 
diff --git a/python/pkg/cdec/sa/extractor.py b/python/pkg/cdec/sa/extractor.py
index 5ef8041c..bb552c49 100644
--- a/python/pkg/cdec/sa/extractor.py
+++ b/python/pkg/cdec/sa/extractor.py
@@ -60,9 +60,9 @@ class GrammarExtractor:
 
         # TODO: clean this up
         extended_features = []
-        #extended_features.append(IsSupportedOnline)
-        if online:
-            extended_features.append(IsSupportedOnline)
+        extended_features.append(IsSupportedOnline)
+        #if online:
+        #    extended_features.append(IsSupportedOnline)
             
         # TODO: use @cdec.sa.features decorator for standard features too
         # + add a mask to disable features
@@ -101,4 +101,6 @@ class GrammarExtractor:
     
     # Debugging
     def dump_online_stats(self):
-        self.factory.dump_online_stats()
\ No newline at end of file
+        self.factory.dump_online_stats()
+    def dump_online_rules(self):
+        self.factory.dump_online_rules()
\ No newline at end of file
diff --git a/python/pkg/cdec/sa/features.py b/python/pkg/cdec/sa/features.py
index cede5304..49064f73 100644
--- a/python/pkg/cdec/sa/features.py
+++ b/python/pkg/cdec/sa/features.py
@@ -21,21 +21,21 @@ def SampleCountF(ctx): # sample c(f)
     if not ctx.online:
         count = 1 + ctx.fsample_count
     else:
-        count = 1 + ctx.fsample_count + ctx.online.fcount
+        count = 1 + ctx.fsample_count + ctx.online.fsample_count
     return math.log10(count)
 
 def EgivenFCoherent(ctx): # c(e, f) / sample c(f)
     if not ctx.online:
         prob = ctx.paircount/ctx.fsample_count
     else:
-        prob = (ctx.paircount + ctx.online.paircount) / (ctx.fsample_count + ctx.online.fcount)
+        prob = (ctx.paircount + ctx.online.paircount) / (ctx.fsample_count + ctx.online.fsample_count)
     return -math.log10(prob) if prob > 0 else MAXSCORE
 
 def CoherenceProb(ctx): # c(f) / sample c(f)
     if not ctx.online:
         prob = ctx.fcount/ctx.fsample_count
     else:
-        prob = (ctx.fcount + ctx.online.fcount) / (ctx.fsample_count + ctx.online.fcount)
+        prob = (ctx.fcount + ctx.online.fcount) / (ctx.fsample_count + ctx.online.fsample_count)
     return -math.log10(prob)
 
 def MaxLexEgivenF(ttable):
@@ -95,7 +95,7 @@ def IsFEGreaterThanZero(ctx):
         count = ctx.paircount + ctx.online.paircount
     return (ctx.paircount > 0.01)
 
-def IsSupportedOnline(ctx):
+def IsSupportedOnline(ctx): # Occurs in online data?
     if ctx.online:
         return (ctx.online.fcount > 0.01)
     else:
diff --git a/python/src/sa/_sa.c b/python/src/sa/_sa.c
index a319b68a..5910a81f 100644
--- a/python/src/sa/_sa.c
+++ b/python/src/sa/_sa.c
@@ -1,4 +1,4 @@
-/* Generated by Cython 0.17.1 on Thu Jan 24 16:50:27 2013 */
+/* Generated by Cython 0.17.1 on Sat Jan 26 21:11:32 2013 */
 
 #define PY_SSIZE_T_CLEAN
 #include "Python.h"
@@ -363,8 +363,8 @@ struct __pyx_obj_3_sa___pyx_scope_struct_17_genexpr;
 struct __pyx_obj_3_sa___pyx_scope_struct_20_genexpr;
 struct __pyx_obj_3_sa___pyx_scope_struct_3_compute_stats;
 struct __pyx_obj_3_sa___pyx_scope_struct_12_genexpr;
+struct __pyx_obj_3_sa___pyx_scope_struct_29_genexpr;
 struct __pyx_obj_3_sa_IntList;
-struct __pyx_obj_3_sa___pyx_scope_struct_30___str__;
 struct __pyx_obj_3_sa_VEBIterator;
 struct __pyx_obj_3_sa_BiLex;
 struct __pyx_obj_3_sa_VEB;
@@ -388,8 +388,7 @@ struct __pyx_obj_3_sa___pyx_scope_struct_15___iter__;
 struct __pyx_obj_3_sa___pyx_scope_struct_22_form_rule;
 struct __pyx_obj_3_sa___pyx_scope_struct_25_genexpr;
 struct __pyx_obj_3_sa___pyx_scope_struct_24_fmt_rule;
-struct __pyx_obj_3_sa___pyx_scope_struct_29___iter__;
-struct __pyx_obj_3_sa___pyx_scope_struct_31_genexpr;
+struct __pyx_obj_3_sa___pyx_scope_struct_28___str__;
 struct __pyx_obj_3_sa___pyx_scope_struct_1_read_bitext;
 struct __pyx_obj_3_sa___pyx_scope_struct_13_decode_words;
 struct __pyx_obj_3_sa_FeatureVector;
@@ -400,15 +399,14 @@ struct __pyx_obj_3_sa_Alignment;
 struct __pyx_obj_3_sa_BitSet;
 struct __pyx_obj_3_sa_Sampler;
 struct __pyx_obj_3_sa_StringMap;
+struct __pyx_obj_3_sa___pyx_scope_struct_26_get_f_phrases;
 struct __pyx_obj_3_sa_TrieNode;
 struct __pyx_obj_3_sa_ExtendedTrieNode;
-struct __pyx_obj_3_sa___pyx_scope_struct_28_genexpr;
 struct __pyx_obj_3_sa_TrieMap;
 struct __pyx_obj_3_sa___pyx_scope_struct_8_genexpr;
 struct __pyx_obj_3_sa___pyx_scope_struct_4_make_lattice;
-struct __pyx_obj_3_sa___pyx_scope_struct_27_genexpr;
 struct __pyx_obj_3_sa_Phrase;
-struct __pyx_obj_3_sa___pyx_scope_struct_26_online_match;
+struct __pyx_obj_3_sa___pyx_scope_struct_27___iter__;
 struct __pyx_obj_3_sa___pyx_scope_struct____iter__;
 struct __pyx_obj_3_sa_TrieTable;
 struct __pyx_obj_3_sa___pyx_scope_struct_5_genexpr;
@@ -494,7 +492,7 @@ struct __pyx_t_3_sa__Trie_Node {
   int arr_len;
 };
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":73
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":74
  * 
  * # linked list structure for storing matches in BaselineRuleFactory
  * cdef struct match_node:             # <<<<<<<<<<<<<<
@@ -506,7 +504,7 @@ struct __pyx_t_3_sa_match_node {
   struct __pyx_t_3_sa_match_node *next;
 };
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":169
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":170
  * 
  * # struct used to encapsulate a single matching
  * cdef struct Matching:             # <<<<<<<<<<<<<<
@@ -521,7 +519,7 @@ struct __pyx_t_3_sa_Matching {
   int size;
 };
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":225
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":226
  * 
  * 
  * cdef class HieroCachingRuleFactory:             # <<<<<<<<<<<<<<
@@ -568,6 +566,7 @@ struct __pyx_obj_3_sa_HieroCachingRuleFactory {
   struct __pyx_obj_3_sa_IntList *findexes;
   struct __pyx_obj_3_sa_IntList *findexes1;
   int online;
+  PyObject *samples_f;
   PyObject *phrases_f;
   PyObject *phrases_e;
   PyObject *phrases_fe;
@@ -608,12 +607,12 @@ struct __pyx_obj_3_sa___pyx_scope_struct_17_genexpr {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1175
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1180
  *         # Online rule extraction and scoring
  *         if self.online:
  *             f_syms = tuple(word[0][0] for word in fwords)             # <<<<<<<<<<<<<<
- *             for (f, e, spanlen) in self.online_match(f_syms, seen_phrases):
- *                 scores = self.scorer.score(FeatureContext(
+ *             for (f, lex_i, lex_j) in self.get_f_phrases(f_syms):
+ *                 spanlen = (lex_j - lex_i) + 1
  */
 struct __pyx_obj_3_sa___pyx_scope_struct_20_genexpr {
   PyObject_HEAD
@@ -673,6 +672,23 @@ struct __pyx_obj_3_sa___pyx_scope_struct_12_genexpr {
 };
 
 
+/* "/home/m/workspace/cdec/python/src/sa/features.pxi":21
+ * 
+ *     def __str__(self):
+ *         return ' '.join('%s=%s' % feat for feat in self)             # <<<<<<<<<<<<<<
+ * 
+ * cdef class Scorer:
+ */
+struct __pyx_obj_3_sa___pyx_scope_struct_29_genexpr {
+  PyObject_HEAD
+  struct __pyx_obj_3_sa___pyx_scope_struct_28___str__ *__pyx_outer_scope;
+  PyObject *__pyx_v_feat;
+  PyObject *__pyx_t_0;
+  Py_ssize_t __pyx_t_1;
+  PyObject *(*__pyx_t_2)(PyObject *);
+};
+
+
 /* "_sa.pxd":12
  *     cdef void read_handle(self, FILE* f)
  * 
@@ -690,19 +706,6 @@ struct __pyx_obj_3_sa_IntList {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/features.pxi":20
- *             yield (FD.word(self.names[i]), self.values[i])
- * 
- *     def __str__(self):             # <<<<<<<<<<<<<<
- *         return ' '.join('%s=%s' % feat for feat in self)
- * 
- */
-struct __pyx_obj_3_sa___pyx_scope_struct_30___str__ {
-  PyObject_HEAD
-  struct __pyx_obj_3_sa_FeatureVector *__pyx_v_self;
-};
-
-
 /* "/home/m/workspace/cdec/python/src/sa/veb.pxi":340
  * 
  * 
@@ -812,7 +815,7 @@ struct __pyx_obj_3_sa_BitSetIterator {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2088
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2108
  *         f = Phrase(f_sym)
  *         e = Phrase(e_sym)
  *         a = tuple(self.alignment.link(i, j) for (i, j) in links)             # <<<<<<<<<<<<<<
@@ -965,7 +968,7 @@ struct __pyx_obj_3_sa___pyx_scope_struct_6_genexpr {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1863
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1877
  *     # Aggregate stats from a training instance
  *     # (Extract rules, update counts)
  *     def add_instance(self, f_words, e_words, alignment):             # <<<<<<<<<<<<<<
@@ -1005,7 +1008,7 @@ struct __pyx_obj_3_sa___pyx_scope_struct_2_genexpr {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":81
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":82
  * # in the suffix array; if discontiguous, it is the set of
  * # actual locations (packed into an array)
  * cdef class PhraseLocation:             # <<<<<<<<<<<<<<
@@ -1039,7 +1042,7 @@ struct __pyx_obj_3_sa___pyx_scope_struct_15___iter__ {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2027
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2047
  * 
  *     # Create a rule from source, target, non-terminals, and alignments
  *     def form_rule(self, f_i, e_i, f_span, e_span, nt, al):             # <<<<<<<<<<<<<<
@@ -1053,7 +1056,7 @@ struct __pyx_obj_3_sa___pyx_scope_struct_22_form_rule {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2093
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2113
  *     # Rule string from rule
  *     def fmt_rule(self, f, e, a):
  *         a_str = ' '.join('{0}-{1}'.format(*self.alignment.unlink(packed)) for packed in a)             # <<<<<<<<<<<<<<
@@ -1070,7 +1073,7 @@ struct __pyx_obj_3_sa___pyx_scope_struct_25_genexpr {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2092
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2112
  * 
  *     # Rule string from rule
  *     def fmt_rule(self, f, e, a):             # <<<<<<<<<<<<<<
@@ -1084,36 +1087,16 @@ struct __pyx_obj_3_sa___pyx_scope_struct_24_fmt_rule {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/features.pxi":15
- *         self.values.append(value)
- * 
- *     def __iter__(self):             # <<<<<<<<<<<<<<
- *         cdef unsigned i
- *         for i in range(self.names.len):
- */
-struct __pyx_obj_3_sa___pyx_scope_struct_29___iter__ {
-  PyObject_HEAD
-  unsigned int __pyx_v_i;
-  struct __pyx_obj_3_sa_FeatureVector *__pyx_v_self;
-  int __pyx_t_0;
-  unsigned int __pyx_t_1;
-};
-
-
-/* "/home/m/workspace/cdec/python/src/sa/features.pxi":21
+/* "/home/m/workspace/cdec/python/src/sa/features.pxi":20
+ *             yield (FD.word(self.names[i]), self.values[i])
  * 
- *     def __str__(self):
- *         return ' '.join('%s=%s' % feat for feat in self)             # <<<<<<<<<<<<<<
+ *     def __str__(self):             # <<<<<<<<<<<<<<
+ *         return ' '.join('%s=%s' % feat for feat in self)
  * 
- * cdef class Scorer:
  */
-struct __pyx_obj_3_sa___pyx_scope_struct_31_genexpr {
+struct __pyx_obj_3_sa___pyx_scope_struct_28___str__ {
   PyObject_HEAD
-  struct __pyx_obj_3_sa___pyx_scope_struct_30___str__ *__pyx_outer_scope;
-  PyObject *__pyx_v_feat;
-  PyObject *__pyx_t_0;
-  Py_ssize_t __pyx_t_1;
-  PyObject *(*__pyx_t_2)(PyObject *);
+  struct __pyx_obj_3_sa_FeatureVector *__pyx_v_self;
 };
 
 
@@ -1170,7 +1153,7 @@ struct __pyx_obj_3_sa___pyx_scope_struct_7_decode_lattice {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":965
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":970
  *         return sorted(result);
  * 
  *     def input(self, fwords, meta):             # <<<<<<<<<<<<<<
@@ -1210,6 +1193,8 @@ struct __pyx_obj_3_sa___pyx_scope_struct_19_input {
   int __pyx_v_j;
   int __pyx_v_k;
   PyObject *__pyx_v_key;
+  PyObject *__pyx_v_lex_i;
+  PyObject *__pyx_v_lex_j;
   PyObject *__pyx_v_loc;
   PyObject *__pyx_v_locs;
   int __pyx_v_lookup_required;
@@ -1257,6 +1242,7 @@ struct __pyx_obj_3_sa___pyx_scope_struct_19_input {
   Py_ssize_t __pyx_t_8;
   Py_ssize_t __pyx_t_9;
   PyObject *(*__pyx_t_10)(PyObject *);
+  PyObject *(*__pyx_t_11)(PyObject *);
 };
 
 
@@ -1302,7 +1288,7 @@ struct __pyx_obj_3_sa_BitSet {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":103
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":104
  * 
  * 
  * cdef class Sampler:             # <<<<<<<<<<<<<<
@@ -1330,7 +1316,24 @@ struct __pyx_obj_3_sa_StringMap {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":43
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2159
+ *     # (Used for EGivenFCoherent)
+ *     # Return set of (fphrase, lex_i, lex_j)
+ *     def get_f_phrases(self, f_words):             # <<<<<<<<<<<<<<
+ * 
+ *         f_len = len(f_words)
+ */
+struct __pyx_obj_3_sa___pyx_scope_struct_26_get_f_phrases {
+  PyObject_HEAD
+  PyObject *__pyx_v_extract;
+  PyObject *__pyx_v_f_len;
+  PyObject *__pyx_v_f_words;
+  PyObject *__pyx_v_phrases;
+  struct __pyx_obj_3_sa_HieroCachingRuleFactory *__pyx_v_self;
+};
+
+
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":44
  * cdef int EPSILON = sym_fromstring('*EPS*', True)
  * 
  * cdef class TrieNode:             # <<<<<<<<<<<<<<
@@ -1343,7 +1346,7 @@ struct __pyx_obj_3_sa_TrieNode {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":49
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":50
  *         self.children = {}
  * 
  * cdef class ExtendedTrieNode(TrieNode):             # <<<<<<<<<<<<<<
@@ -1358,24 +1361,6 @@ struct __pyx_obj_3_sa_ExtendedTrieNode {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2176
- *         for line in sorted(' ||| '.join((str(f), str(e))) for (f, e) in matches):
- *             print 'Online new:', line
- *         return ((f, e, matches[(f, e)]) for (f, e) in matches)             # <<<<<<<<<<<<<<
- * 
- * # Spans are _inclusive_ on both ends [i, j]
- */
-struct __pyx_obj_3_sa___pyx_scope_struct_28_genexpr {
-  PyObject_HEAD
-  struct __pyx_obj_3_sa___pyx_scope_struct_26_online_match *__pyx_outer_scope;
-  PyObject *__pyx_v_e;
-  PyObject *__pyx_v_f;
-  PyObject *__pyx_t_0;
-  Py_ssize_t __pyx_t_1;
-  PyObject *(*__pyx_t_2)(PyObject *);
-};
-
-
 /* "/home/m/workspace/cdec/python/src/sa/precomputation.pxi":109
  *         trie_node_to_map(edge.node, result, prefix, include_zeros)
  * 
@@ -1432,24 +1417,6 @@ struct __pyx_obj_3_sa___pyx_scope_struct_4_make_lattice {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2174
- *             extract(f_i, f_i, 0, 0, [])
- * 
- *         for line in sorted(' ||| '.join((str(f), str(e))) for (f, e) in matches):             # <<<<<<<<<<<<<<
- *             print 'Online new:', line
- *         return ((f, e, matches[(f, e)]) for (f, e) in matches)
- */
-struct __pyx_obj_3_sa___pyx_scope_struct_27_genexpr {
-  PyObject_HEAD
-  struct __pyx_obj_3_sa___pyx_scope_struct_26_online_match *__pyx_outer_scope;
-  PyObject *__pyx_v_e;
-  PyObject *__pyx_v_f;
-  PyObject *__pyx_t_0;
-  Py_ssize_t __pyx_t_1;
-  PyObject *(*__pyx_t_2)(PyObject *);
-};
-
-
 /* "_sa.pxd":29
  *     cdef FloatList values
  * 
@@ -1467,21 +1434,19 @@ struct __pyx_obj_3_sa_Phrase {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2136
- *     # Match source words against online data.
- *     # Return (fphrase, ephrase, length)
- *     def online_match(self, f_words, seen_phrases):             # <<<<<<<<<<<<<<
+/* "/home/m/workspace/cdec/python/src/sa/features.pxi":15
+ *         self.values.append(value)
  * 
- *         f_len = len(f_words)
+ *     def __iter__(self):             # <<<<<<<<<<<<<<
+ *         cdef unsigned i
+ *         for i in range(self.names.len):
  */
-struct __pyx_obj_3_sa___pyx_scope_struct_26_online_match {
+struct __pyx_obj_3_sa___pyx_scope_struct_27___iter__ {
   PyObject_HEAD
-  PyObject *__pyx_v_extract;
-  PyObject *__pyx_v_f_len;
-  PyObject *__pyx_v_f_words;
-  PyObject *__pyx_v_matches;
-  PyObject *__pyx_v_seen_phrases;
-  struct __pyx_obj_3_sa_HieroCachingRuleFactory *__pyx_v_self;
+  unsigned int __pyx_v_i;
+  struct __pyx_obj_3_sa_FeatureVector *__pyx_v_self;
+  int __pyx_t_0;
+  unsigned int __pyx_t_1;
 };
 
 
@@ -1501,7 +1466,7 @@ struct __pyx_obj_3_sa___pyx_scope_struct____iter__ {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":60
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":61
  * 
  * 
  * cdef class TrieTable:             # <<<<<<<<<<<<<<
@@ -1684,7 +1649,7 @@ struct __pyx_vtabstruct_3_sa_Phrase {
 static struct __pyx_vtabstruct_3_sa_Phrase *__pyx_vtabptr_3_sa_Phrase;
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":81
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":82
  * # in the suffix array; if discontiguous, it is the set of
  * # actual locations (packed into an array)
  * cdef class PhraseLocation:             # <<<<<<<<<<<<<<
@@ -1782,7 +1747,7 @@ struct __pyx_vtabstruct_3_sa_Alphabet {
 static struct __pyx_vtabstruct_3_sa_Alphabet *__pyx_vtabptr_3_sa_Alphabet;
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":225
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":226
  * 
  * 
  * cdef class HieroCachingRuleFactory:             # <<<<<<<<<<<<<<
@@ -2314,12 +2279,6 @@ static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *m,
                                                             PyObject *tuple);
 static int __Pyx_CyFunction_init(void);
 
-static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
-#if CYTHON_COMPILING_IN_PYPY || PY_MAJOR_VERSION >= 3
-static PyObject* __pyx_print = 0;
-static PyObject* __pyx_print_kwargs = 0;
-#endif
-
 static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject *);
 
 static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject *);
@@ -2470,12 +2429,10 @@ static PyTypeObject *__pyx_ptype_3_sa___pyx_scope_struct_22_form_rule = 0;
 static PyTypeObject *__pyx_ptype_3_sa___pyx_scope_struct_23_genexpr = 0;
 static PyTypeObject *__pyx_ptype_3_sa___pyx_scope_struct_24_fmt_rule = 0;
 static PyTypeObject *__pyx_ptype_3_sa___pyx_scope_struct_25_genexpr = 0;
-static PyTypeObject *__pyx_ptype_3_sa___pyx_scope_struct_26_online_match = 0;
-static PyTypeObject *__pyx_ptype_3_sa___pyx_scope_struct_27_genexpr = 0;
-static PyTypeObject *__pyx_ptype_3_sa___pyx_scope_struct_28_genexpr = 0;
-static PyTypeObject *__pyx_ptype_3_sa___pyx_scope_struct_29___iter__ = 0;
-static PyTypeObject *__pyx_ptype_3_sa___pyx_scope_struct_30___str__ = 0;
-static PyTypeObject *__pyx_ptype_3_sa___pyx_scope_struct_31_genexpr = 0;
+static PyTypeObject *__pyx_ptype_3_sa___pyx_scope_struct_26_get_f_phrases = 0;
+static PyTypeObject *__pyx_ptype_3_sa___pyx_scope_struct_27___iter__ = 0;
+static PyTypeObject *__pyx_ptype_3_sa___pyx_scope_struct_28___str__ = 0;
+static PyTypeObject *__pyx_ptype_3_sa___pyx_scope_struct_29_genexpr = 0;
 static int __pyx_v_3_sa_MIN_BOTTOM_SIZE;
 static int __pyx_v_3_sa_MIN_BOTTOM_BITS;
 static int __pyx_v_3_sa_LOWER_MASK[32];
@@ -2752,11 +2709,10 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
 static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8fmt_rule_genexpr(PyObject *__pyx_self); /* proto */
 static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_29fmt_rule(struct __pyx_obj_3_sa_HieroCachingRuleFactory *__pyx_v_self, PyObject *__pyx_v_f, PyObject *__pyx_v_e, PyObject *__pyx_v_a); /* proto */
 static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(struct __pyx_obj_3_sa_HieroCachingRuleFactory *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_33online_ctx_lookup(struct __pyx_obj_3_sa_HieroCachingRuleFactory *__pyx_v_self, PyObject *__pyx_v_f, PyObject *__pyx_v_e); /* proto */
-static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12online_match_extract(PyObject *__pyx_self, PyObject *__pyx_v_f_i, PyObject *__pyx_v_f_j, PyObject *__pyx_v_wc, PyObject *__pyx_v_ntc, PyObject *__pyx_v_syms); /* proto */
-static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12online_match_2genexpr(PyObject *__pyx_self); /* proto */
-static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12online_match_5genexpr(PyObject *__pyx_self); /* proto */
-static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_35online_match(struct __pyx_obj_3_sa_HieroCachingRuleFactory *__pyx_v_self, PyObject *__pyx_v_f_words, PyObject *__pyx_v_seen_phrases); /* proto */
+static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_33dump_online_rules(struct __pyx_obj_3_sa_HieroCachingRuleFactory *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_35online_ctx_lookup(struct __pyx_obj_3_sa_HieroCachingRuleFactory *__pyx_v_self, PyObject *__pyx_v_f, PyObject *__pyx_v_e); /* proto */
+static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_13get_f_phrases_extract(PyObject *__pyx_self, PyObject *__pyx_v_f_i, PyObject *__pyx_v_f_j, PyObject *__pyx_v_lex_i, PyObject *__pyx_v_lex_j, PyObject *__pyx_v_wc, PyObject *__pyx_v_ntc, PyObject *__pyx_v_syms); /* proto */
+static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_37get_f_phrases(struct __pyx_obj_3_sa_HieroCachingRuleFactory *__pyx_v_self, PyObject *__pyx_v_f_words); /* proto */
 static PyObject *__pyx_pf_3_sa_12span_check(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_vec, PyObject *__pyx_v_i, PyObject *__pyx_v_j); /* proto */
 static PyObject *__pyx_pf_3_sa_14span_inc(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_vec, PyObject *__pyx_v_i, PyObject *__pyx_v_j); /* proto */
 static PyObject *__pyx_pf_3_sa_16span_dec(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_vec, PyObject *__pyx_v_i, PyObject *__pyx_v_j); /* proto */
@@ -2870,15 +2826,12 @@ static char __pyx_k_138[] = "[X] ||| {0} ||| {1} ||| {2}";
 static char __pyx_k_139[] = "------------------------------";
 static char __pyx_k_141[] = "         Online Stats         ";
 static char __pyx_k_145[] = " : ";
-static char __pyx_k_151[] = "Online support:";
-static char __pyx_k_152[] = "|||";
-static char __pyx_k_153[] = "OnlineFeatureContext";
-static char __pyx_k_156[] = "Online new:";
-static char __pyx_k_157[] = "%s=%s";
-static char __pyx_k_160[] = "/home/m/workspace/cdec/python/src/sa/_sa.pyx";
-static char __pyx_k_161[] = "cdec.sa";
-static char __pyx_k_165[] = "/home/m/workspace/cdec/python/src/sa/sym.pxi";
-static char __pyx_k_174[] = "*EPS*";
+static char __pyx_k_151[] = "OnlineFeatureContext";
+static char __pyx_k_154[] = "%s=%s";
+static char __pyx_k_157[] = "/home/m/workspace/cdec/python/src/sa/_sa.pyx";
+static char __pyx_k_158[] = "cdec.sa";
+static char __pyx_k_162[] = "/home/m/workspace/cdec/python/src/sa/sym.pxi";
+static char __pyx_k_171[] = "*EPS*";
 static char __pyx_k__FE[] = "FE";
 static char __pyx_k__al[] = "al";
 static char __pyx_k__fe[] = "fe";
@@ -2938,6 +2891,8 @@ static char __pyx_k__eword[] = "eword";
 static char __pyx_k__fword[] = "fword";
 static char __pyx_k__ifrom[] = "ifrom";
 static char __pyx_k__index[] = "index";
+static char __pyx_k__lex_i[] = "lex_i";
+static char __pyx_k__lex_j[] = "lex_j";
 static char __pyx_k__links[] = "links";
 static char __pyx_k__merge[] = "merge";
 static char __pyx_k__range[] = "range";
@@ -3039,6 +2994,8 @@ static char __pyx_k__increment[] = "increment";
 static char __pyx_k__iteritems[] = "iteritems";
 static char __pyx_k__itertools[] = "itertools";
 static char __pyx_k__min_bound[] = "min_bound";
+static char __pyx_k__new_lex_i[] = "new_lex_i";
+static char __pyx_k__new_lex_j[] = "new_lex_j";
 static char __pyx_k__paircount[] = "paircount";
 static char __pyx_k__partition[] = "partition";
 static char __pyx_k__reachable[] = "reachable";
@@ -3079,12 +3036,11 @@ static char __pyx_k__gzip_or_text[] = "gzip_or_text";
 static char __pyx_k__make_lattice[] = "make_lattice";
 static char __pyx_k__min_gap_size[] = "min_gap_size";
 static char __pyx_k__nt_collision[] = "nt_collision";
-static char __pyx_k__online_match[] = "online_match";
-static char __pyx_k__seen_phrases[] = "seen_phrases";
 static char __pyx_k__StopIteration[] = "StopIteration";
 static char __pyx_k__alphabet_size[] = "alphabet_size";
 static char __pyx_k__from_iterable[] = "from_iterable";
 static char __pyx_k__fsample_count[] = "fsample_count";
+static char __pyx_k__get_f_phrases[] = "get_f_phrases";
 static char __pyx_k__new_min_bound[] = "new_min_bound";
 static char __pyx_k__test_sentence[] = "test_sentence";
 static char __pyx_k__tight_phrases[] = "tight_phrases";
@@ -3106,6 +3062,7 @@ static char __pyx_k__max_initial_size[] = "max_initial_size";
 static char __pyx_k__max_nonterminals[] = "max_nonterminals";
 static char __pyx_k__reachable_buffer[] = "reachable_buffer";
 static char __pyx_k__use_collocations[] = "use_collocations";
+static char __pyx_k__dump_online_rules[] = "dump_online_rules";
 static char __pyx_k__max_target_chunks[] = "max_target_chunks";
 static char __pyx_k__max_target_length[] = "max_target_length";
 static char __pyx_k__online_ctx_lookup[] = "online_ctx_lookup";
@@ -3150,14 +3107,11 @@ static PyObject *__pyx_kp_s_139;
 static PyObject *__pyx_kp_s_14;
 static PyObject *__pyx_kp_s_141;
 static PyObject *__pyx_kp_s_145;
-static PyObject *__pyx_kp_s_151;
-static PyObject *__pyx_kp_s_152;
-static PyObject *__pyx_n_s_153;
-static PyObject *__pyx_kp_s_156;
+static PyObject *__pyx_n_s_151;
+static PyObject *__pyx_kp_s_154;
 static PyObject *__pyx_kp_s_157;
-static PyObject *__pyx_kp_s_160;
-static PyObject *__pyx_kp_s_161;
-static PyObject *__pyx_kp_s_165;
+static PyObject *__pyx_kp_s_158;
+static PyObject *__pyx_kp_s_162;
 static PyObject *__pyx_kp_s_18;
 static PyObject *__pyx_kp_s_2;
 static PyObject *__pyx_kp_s_21;
@@ -3260,6 +3214,7 @@ static PyObject *__pyx_n_s__decode_sentence;
 static PyObject *__pyx_n_s__decode_words;
 static PyObject *__pyx_n_s__defaultdict;
 static PyObject *__pyx_n_s__dist;
+static PyObject *__pyx_n_s__dump_online_rules;
 static PyObject *__pyx_n_s__e;
 static PyObject *__pyx_n_s__e_i;
 static PyObject *__pyx_n_s__e_j;
@@ -3305,6 +3260,7 @@ static PyObject *__pyx_n_s__get;
 static PyObject *__pyx_n_s__getLogger;
 static PyObject *__pyx_n_s__get_e_id;
 static PyObject *__pyx_n_s__get_f_id;
+static PyObject *__pyx_n_s__get_f_phrases;
 static PyObject *__pyx_n_s__get_id;
 static PyObject *__pyx_n_s__get_next_states;
 static PyObject *__pyx_n_s__get_word;
@@ -3333,6 +3289,8 @@ static PyObject *__pyx_n_s__join;
 static PyObject *__pyx_n_s__k;
 static PyObject *__pyx_n_s__key;
 static PyObject *__pyx_n_s__lattice;
+static PyObject *__pyx_n_s__lex_i;
+static PyObject *__pyx_n_s__lex_j;
 static PyObject *__pyx_n_s__lhs;
 static PyObject *__pyx_n_s__link;
 static PyObject *__pyx_n_s__link_i;
@@ -3361,6 +3319,8 @@ static PyObject *__pyx_n_s__name;
 static PyObject *__pyx_n_s__namedtuple;
 static PyObject *__pyx_n_s__new_e_i;
 static PyObject *__pyx_n_s__new_e_j;
+static PyObject *__pyx_n_s__new_lex_i;
+static PyObject *__pyx_n_s__new_lex_j;
 static PyObject *__pyx_n_s__new_min_bound;
 static PyObject *__pyx_n_s__next_states;
 static PyObject *__pyx_n_s__nt;
@@ -3372,7 +3332,6 @@ static PyObject *__pyx_n_s__offset;
 static PyObject *__pyx_n_s__old_last_nt;
 static PyObject *__pyx_n_s__online;
 static PyObject *__pyx_n_s__online_ctx_lookup;
-static PyObject *__pyx_n_s__online_match;
 static PyObject *__pyx_n_s__open;
 static PyObject *__pyx_n_s__pad;
 static PyObject *__pyx_n_s__paircount;
@@ -3411,7 +3370,6 @@ static PyObject *__pyx_n_s__sarray;
 static PyObject *__pyx_n_s__scorer;
 static PyObject *__pyx_n_s__scores;
 static PyObject *__pyx_n_s__seek;
-static PyObject *__pyx_n_s__seen_phrases;
 static PyObject *__pyx_n_s__set;
 static PyObject *__pyx_n_s__shortest;
 static PyObject *__pyx_n_s__side;
@@ -3522,28 +3480,28 @@ static PyObject *__pyx_k_tuple_147;
 static PyObject *__pyx_k_tuple_148;
 static PyObject *__pyx_k_tuple_149;
 static PyObject *__pyx_k_tuple_150;
-static PyObject *__pyx_k_tuple_154;
-static PyObject *__pyx_k_tuple_158;
-static PyObject *__pyx_k_tuple_162;
+static PyObject *__pyx_k_tuple_152;
+static PyObject *__pyx_k_tuple_155;
+static PyObject *__pyx_k_tuple_159;
+static PyObject *__pyx_k_tuple_160;
 static PyObject *__pyx_k_tuple_163;
-static PyObject *__pyx_k_tuple_166;
-static PyObject *__pyx_k_tuple_168;
-static PyObject *__pyx_k_tuple_170;
+static PyObject *__pyx_k_tuple_165;
+static PyObject *__pyx_k_tuple_167;
+static PyObject *__pyx_k_tuple_169;
 static PyObject *__pyx_k_tuple_172;
-static PyObject *__pyx_k_tuple_175;
-static PyObject *__pyx_k_tuple_177;
-static PyObject *__pyx_k_tuple_179;
+static PyObject *__pyx_k_tuple_174;
+static PyObject *__pyx_k_tuple_176;
 static PyObject *__pyx_k_codeobj_135;
-static PyObject *__pyx_k_codeobj_155;
-static PyObject *__pyx_k_codeobj_159;
+static PyObject *__pyx_k_codeobj_153;
+static PyObject *__pyx_k_codeobj_156;
+static PyObject *__pyx_k_codeobj_161;
 static PyObject *__pyx_k_codeobj_164;
-static PyObject *__pyx_k_codeobj_167;
-static PyObject *__pyx_k_codeobj_169;
-static PyObject *__pyx_k_codeobj_171;
+static PyObject *__pyx_k_codeobj_166;
+static PyObject *__pyx_k_codeobj_168;
+static PyObject *__pyx_k_codeobj_170;
 static PyObject *__pyx_k_codeobj_173;
-static PyObject *__pyx_k_codeobj_176;
-static PyObject *__pyx_k_codeobj_178;
-static PyObject *__pyx_k_codeobj_180;
+static PyObject *__pyx_k_codeobj_175;
+static PyObject *__pyx_k_codeobj_177;
 
 /* "_sa.pyx":5
  * import gzip
@@ -36694,7 +36652,7 @@ static int __pyx_pw_3_sa_8TrieNode_1__cinit__(PyObject *__pyx_v_self, PyObject *
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":46
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":47
  *     cdef public children
  * 
  *     def __cinit__(self):             # <<<<<<<<<<<<<<
@@ -36711,14 +36669,14 @@ static int __pyx_pf_3_sa_8TrieNode___cinit__(struct __pyx_obj_3_sa_TrieNode *__p
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__cinit__", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":47
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":48
  * 
  *     def __cinit__(self):
  *         self.children = {}             # <<<<<<<<<<<<<<
  * 
  * cdef class ExtendedTrieNode(TrieNode):
  */
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
   __Pyx_GOTREF(__pyx_v_self->children);
@@ -36748,7 +36706,7 @@ static PyObject *__pyx_pw_3_sa_8TrieNode_8children_1__get__(PyObject *__pyx_v_se
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":44
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":45
  * 
  * cdef class TrieNode:
  *     cdef public children             # <<<<<<<<<<<<<<
@@ -36837,7 +36795,7 @@ static int __pyx_pw_3_sa_16ExtendedTrieNode_1__cinit__(PyObject *__pyx_v_self, P
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__phrase,&__pyx_n_s__phrase_location,&__pyx_n_s__suffix_link,0};
     PyObject* values[3] = {0,0,0};
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":54
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":55
  *     cdef public suffix_link
  * 
  *     def __cinit__(self, phrase=None, phrase_location=None, suffix_link=None):             # <<<<<<<<<<<<<<
@@ -36876,7 +36834,7 @@ static int __pyx_pw_3_sa_16ExtendedTrieNode_1__cinit__(PyObject *__pyx_v_self, P
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -36893,7 +36851,7 @@ static int __pyx_pw_3_sa_16ExtendedTrieNode_1__cinit__(PyObject *__pyx_v_self, P
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.ExtendedTrieNode.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -36909,7 +36867,7 @@ static int __pyx_pf_3_sa_16ExtendedTrieNode___cinit__(struct __pyx_obj_3_sa_Exte
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__cinit__", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":55
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":56
  * 
  *     def __cinit__(self, phrase=None, phrase_location=None, suffix_link=None):
  *         self.phrase = phrase             # <<<<<<<<<<<<<<
@@ -36922,7 +36880,7 @@ static int __pyx_pf_3_sa_16ExtendedTrieNode___cinit__(struct __pyx_obj_3_sa_Exte
   __Pyx_DECREF(__pyx_v_self->phrase);
   __pyx_v_self->phrase = __pyx_v_phrase;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":56
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":57
  *     def __cinit__(self, phrase=None, phrase_location=None, suffix_link=None):
  *         self.phrase = phrase
  *         self.phrase_location = phrase_location             # <<<<<<<<<<<<<<
@@ -36935,7 +36893,7 @@ static int __pyx_pf_3_sa_16ExtendedTrieNode___cinit__(struct __pyx_obj_3_sa_Exte
   __Pyx_DECREF(__pyx_v_self->phrase_location);
   __pyx_v_self->phrase_location = __pyx_v_phrase_location;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":57
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":58
  *         self.phrase = phrase
  *         self.phrase_location = phrase_location
  *         self.suffix_link = suffix_link             # <<<<<<<<<<<<<<
@@ -36964,7 +36922,7 @@ static PyObject *__pyx_pw_3_sa_16ExtendedTrieNode_6phrase_1__get__(PyObject *__p
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":50
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":51
  * 
  * cdef class ExtendedTrieNode(TrieNode):
  *     cdef public phrase             # <<<<<<<<<<<<<<
@@ -37051,7 +37009,7 @@ static PyObject *__pyx_pw_3_sa_16ExtendedTrieNode_15phrase_location_1__get__(PyO
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":51
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":52
  * cdef class ExtendedTrieNode(TrieNode):
  *     cdef public phrase
  *     cdef public phrase_location             # <<<<<<<<<<<<<<
@@ -37138,7 +37096,7 @@ static PyObject *__pyx_pw_3_sa_16ExtendedTrieNode_11suffix_link_1__get__(PyObjec
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":52
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":53
  *     cdef public phrase
  *     cdef public phrase_location
  *     cdef public suffix_link             # <<<<<<<<<<<<<<
@@ -37242,7 +37200,7 @@ static int __pyx_pw_3_sa_9TrieTable_1__cinit__(PyObject *__pyx_v_self, PyObject
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -37255,7 +37213,7 @@ static int __pyx_pw_3_sa_9TrieTable_1__cinit__(PyObject *__pyx_v_self, PyObject
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.TrieTable.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -37266,7 +37224,7 @@ static int __pyx_pw_3_sa_9TrieTable_1__cinit__(PyObject *__pyx_v_self, PyObject
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":64
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":65
  *     cdef public int count
  *     cdef public root
  *     def __cinit__(self, extended=False):             # <<<<<<<<<<<<<<
@@ -37285,7 +37243,7 @@ static int __pyx_pf_3_sa_9TrieTable___cinit__(struct __pyx_obj_3_sa_TrieTable *_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__cinit__", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":65
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":66
  *     cdef public root
  *     def __cinit__(self, extended=False):
  *         self.count = 0             # <<<<<<<<<<<<<<
@@ -37294,34 +37252,34 @@ static int __pyx_pf_3_sa_9TrieTable___cinit__(struct __pyx_obj_3_sa_TrieTable *_
  */
   __pyx_v_self->count = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":66
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":67
  *     def __cinit__(self, extended=False):
  *         self.count = 0
  *         self.extended = extended             # <<<<<<<<<<<<<<
  *         if extended:
  *             self.root = ExtendedTrieNode()
  */
-  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_extended); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_extended); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_v_self->extended = __pyx_t_1;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":67
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":68
  *         self.count = 0
  *         self.extended = extended
  *         if extended:             # <<<<<<<<<<<<<<
  *             self.root = ExtendedTrieNode()
  *         else:
  */
-  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_extended); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_extended); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 68; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   if (__pyx_t_2) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":68
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":69
  *         self.extended = extended
  *         if extended:
  *             self.root = ExtendedTrieNode()             # <<<<<<<<<<<<<<
  *         else:
  *             self.root = TrieNode()
  */
-    __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_ExtendedTrieNode)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 68; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_ExtendedTrieNode)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_GIVEREF(__pyx_t_3);
     __Pyx_GOTREF(__pyx_v_self->root);
@@ -37332,14 +37290,14 @@ static int __pyx_pf_3_sa_9TrieTable___cinit__(struct __pyx_obj_3_sa_TrieTable *_
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":70
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":71
  *             self.root = ExtendedTrieNode()
  *         else:
  *             self.root = TrieNode()             # <<<<<<<<<<<<<<
  * 
  * # linked list structure for storing matches in BaselineRuleFactory
  */
-    __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_TrieNode)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_TrieNode)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_GIVEREF(__pyx_t_3);
     __Pyx_GOTREF(__pyx_v_self->root);
@@ -37371,7 +37329,7 @@ static PyObject *__pyx_pw_3_sa_9TrieTable_8extended_1__get__(PyObject *__pyx_v_s
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":61
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":62
  * 
  * cdef class TrieTable:
  *     cdef public int extended             # <<<<<<<<<<<<<<
@@ -37388,7 +37346,7 @@ static PyObject *__pyx_pf_3_sa_9TrieTable_8extended___get__(struct __pyx_obj_3_s
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->extended); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->extended); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -37425,7 +37383,7 @@ static int __pyx_pf_3_sa_9TrieTable_8extended_2__set__(struct __pyx_obj_3_sa_Tri
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__set__", 0);
-  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_value); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_value); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_v_self->extended = __pyx_t_1;
 
   __pyx_r = 0;
@@ -37449,7 +37407,7 @@ static PyObject *__pyx_pw_3_sa_9TrieTable_5count_1__get__(PyObject *__pyx_v_self
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":62
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":63
  * cdef class TrieTable:
  *     cdef public int extended
  *     cdef public int count             # <<<<<<<<<<<<<<
@@ -37466,7 +37424,7 @@ static PyObject *__pyx_pf_3_sa_9TrieTable_5count___get__(struct __pyx_obj_3_sa_T
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->count); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->count); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -37503,7 +37461,7 @@ static int __pyx_pf_3_sa_9TrieTable_5count_2__set__(struct __pyx_obj_3_sa_TrieTa
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__set__", 0);
-  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_value); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_value); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_v_self->count = __pyx_t_1;
 
   __pyx_r = 0;
@@ -37527,7 +37485,7 @@ static PyObject *__pyx_pw_3_sa_9TrieTable_4root_1__get__(PyObject *__pyx_v_self)
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":63
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":64
  *     cdef public int extended
  *     cdef public int count
  *     cdef public root             # <<<<<<<<<<<<<<
@@ -37603,7 +37561,7 @@ static int __pyx_pf_3_sa_9TrieTable_4root_4__del__(struct __pyx_obj_3_sa_TrieTab
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":90
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":91
  * 
  *     # returns true if sent_id is contained
  *     cdef int contains(self, int sent_id):             # <<<<<<<<<<<<<<
@@ -37616,7 +37574,7 @@ static int __pyx_f_3_sa_14PhraseLocation_contains(CYTHON_UNUSED struct __pyx_obj
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("contains", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":91
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":92
  *     # returns true if sent_id is contained
  *     cdef int contains(self, int sent_id):
  *         return 1             # <<<<<<<<<<<<<<
@@ -37648,7 +37606,7 @@ static int __pyx_pw_3_sa_14PhraseLocation_1__cinit__(PyObject *__pyx_v_self, PyO
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__sa_low,&__pyx_n_s__sa_high,&__pyx_n_s__arr_low,&__pyx_n_s__arr_high,&__pyx_n_s__arr,&__pyx_n_s__num_subpatterns,0};
     PyObject* values[6] = {0,0,0,0,0,0};
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":94
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":95
  * 
  *     def __cinit__(self, int sa_low=-1, int sa_high=-1, int arr_low=-1, int arr_high=-1,
  *             arr=None, int num_subpatterns=1):             # <<<<<<<<<<<<<<
@@ -37703,7 +37661,7 @@ static int __pyx_pw_3_sa_14PhraseLocation_1__cinit__(PyObject *__pyx_v_self, PyO
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -37718,35 +37676,35 @@ static int __pyx_pw_3_sa_14PhraseLocation_1__cinit__(PyObject *__pyx_v_self, PyO
       }
     }
     if (values[0]) {
-      __pyx_v_sa_low = __Pyx_PyInt_AsInt(values[0]); if (unlikely((__pyx_v_sa_low == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_sa_low = __Pyx_PyInt_AsInt(values[0]); if (unlikely((__pyx_v_sa_low == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
       __pyx_v_sa_low = ((int)-1);
     }
     if (values[1]) {
-      __pyx_v_sa_high = __Pyx_PyInt_AsInt(values[1]); if (unlikely((__pyx_v_sa_high == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_sa_high = __Pyx_PyInt_AsInt(values[1]); if (unlikely((__pyx_v_sa_high == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
       __pyx_v_sa_high = ((int)-1);
     }
     if (values[2]) {
-      __pyx_v_arr_low = __Pyx_PyInt_AsInt(values[2]); if (unlikely((__pyx_v_arr_low == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_arr_low = __Pyx_PyInt_AsInt(values[2]); if (unlikely((__pyx_v_arr_low == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
       __pyx_v_arr_low = ((int)-1);
     }
     if (values[3]) {
-      __pyx_v_arr_high = __Pyx_PyInt_AsInt(values[3]); if (unlikely((__pyx_v_arr_high == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_arr_high = __Pyx_PyInt_AsInt(values[3]); if (unlikely((__pyx_v_arr_high == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
       __pyx_v_arr_high = ((int)-1);
     }
     __pyx_v_arr = values[4];
     if (values[5]) {
-      __pyx_v_num_subpatterns = __Pyx_PyInt_AsInt(values[5]); if (unlikely((__pyx_v_num_subpatterns == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_num_subpatterns = __Pyx_PyInt_AsInt(values[5]); if (unlikely((__pyx_v_num_subpatterns == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
       __pyx_v_num_subpatterns = ((int)1);
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 0, 6, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 0, 6, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.PhraseLocation.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -37757,7 +37715,7 @@ static int __pyx_pw_3_sa_14PhraseLocation_1__cinit__(PyObject *__pyx_v_self, PyO
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":93
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":94
  *         return 1
  * 
  *     def __cinit__(self, int sa_low=-1, int sa_high=-1, int arr_low=-1, int arr_high=-1,             # <<<<<<<<<<<<<<
@@ -37773,7 +37731,7 @@ static int __pyx_pf_3_sa_14PhraseLocation___cinit__(struct __pyx_obj_3_sa_Phrase
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__cinit__", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":95
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":96
  *     def __cinit__(self, int sa_low=-1, int sa_high=-1, int arr_low=-1, int arr_high=-1,
  *             arr=None, int num_subpatterns=1):
  *         self.sa_low = sa_low             # <<<<<<<<<<<<<<
@@ -37782,7 +37740,7 @@ static int __pyx_pf_3_sa_14PhraseLocation___cinit__(struct __pyx_obj_3_sa_Phrase
  */
   __pyx_v_self->sa_low = __pyx_v_sa_low;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":96
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":97
  *             arr=None, int num_subpatterns=1):
  *         self.sa_low = sa_low
  *         self.sa_high = sa_high             # <<<<<<<<<<<<<<
@@ -37791,7 +37749,7 @@ static int __pyx_pf_3_sa_14PhraseLocation___cinit__(struct __pyx_obj_3_sa_Phrase
  */
   __pyx_v_self->sa_high = __pyx_v_sa_high;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":97
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":98
  *         self.sa_low = sa_low
  *         self.sa_high = sa_high
  *         self.arr_low = arr_low             # <<<<<<<<<<<<<<
@@ -37800,7 +37758,7 @@ static int __pyx_pf_3_sa_14PhraseLocation___cinit__(struct __pyx_obj_3_sa_Phrase
  */
   __pyx_v_self->arr_low = __pyx_v_arr_low;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":98
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":99
  *         self.sa_high = sa_high
  *         self.arr_low = arr_low
  *         self.arr_high = arr_high             # <<<<<<<<<<<<<<
@@ -37809,21 +37767,21 @@ static int __pyx_pf_3_sa_14PhraseLocation___cinit__(struct __pyx_obj_3_sa_Phrase
  */
   __pyx_v_self->arr_high = __pyx_v_arr_high;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":99
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":100
  *         self.arr_low = arr_low
  *         self.arr_high = arr_high
  *         self.arr = arr             # <<<<<<<<<<<<<<
  *         self.num_subpatterns = num_subpatterns
  * 
  */
-  if (!(likely(((__pyx_v_arr) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_arr, __pyx_ptype_3_sa_IntList))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (!(likely(((__pyx_v_arr) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_arr, __pyx_ptype_3_sa_IntList))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_INCREF(__pyx_v_arr);
   __Pyx_GIVEREF(__pyx_v_arr);
   __Pyx_GOTREF(__pyx_v_self->arr);
   __Pyx_DECREF(((PyObject *)__pyx_v_self->arr));
   __pyx_v_self->arr = ((struct __pyx_obj_3_sa_IntList *)__pyx_v_arr);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":100
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":101
  *         self.arr_high = arr_high
  *         self.arr = arr
  *         self.num_subpatterns = num_subpatterns             # <<<<<<<<<<<<<<
@@ -37870,11 +37828,11 @@ static int __pyx_pw_3_sa_7Sampler_1__cinit__(PyObject *__pyx_v_self, PyObject *_
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__fsarray)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 2, 2, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 2, 2, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -37882,18 +37840,18 @@ static int __pyx_pw_3_sa_7Sampler_1__cinit__(PyObject *__pyx_v_self, PyObject *_
       values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
-    __pyx_v_sample_size = __Pyx_PyInt_AsInt(values[0]); if (unlikely((__pyx_v_sample_size == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_sample_size = __Pyx_PyInt_AsInt(values[0]); if (unlikely((__pyx_v_sample_size == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     __pyx_v_fsarray = ((struct __pyx_obj_3_sa_SuffixArray *)values[1]);
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.Sampler.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return -1;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_fsarray), __pyx_ptype_3_sa_SuffixArray, 1, "fsarray", 0))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_fsarray), __pyx_ptype_3_sa_SuffixArray, 1, "fsarray", 0))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_r = __pyx_pf_3_sa_7Sampler___cinit__(((struct __pyx_obj_3_sa_Sampler *)__pyx_v_self), __pyx_v_sample_size, __pyx_v_fsarray);
   goto __pyx_L0;
   __pyx_L1_error:;
@@ -37903,7 +37861,7 @@ static int __pyx_pw_3_sa_7Sampler_1__cinit__(PyObject *__pyx_v_self, PyObject *_
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":110
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":111
  *     cdef IntList sa
  * 
  *     def __cinit__(self, int sample_size, SuffixArray fsarray):             # <<<<<<<<<<<<<<
@@ -37923,7 +37881,7 @@ static int __pyx_pf_3_sa_7Sampler___cinit__(struct __pyx_obj_3_sa_Sampler *__pyx
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__cinit__", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":111
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":112
  * 
  *     def __cinit__(self, int sample_size, SuffixArray fsarray):
  *         self.sample_size = sample_size             # <<<<<<<<<<<<<<
@@ -37932,7 +37890,7 @@ static int __pyx_pf_3_sa_7Sampler___cinit__(struct __pyx_obj_3_sa_Sampler *__pyx
  */
   __pyx_v_self->sample_size = __pyx_v_sample_size;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":112
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":113
  *     def __cinit__(self, int sample_size, SuffixArray fsarray):
  *         self.sample_size = sample_size
  *         self.sa = fsarray.sa             # <<<<<<<<<<<<<<
@@ -37945,7 +37903,7 @@ static int __pyx_pf_3_sa_7Sampler___cinit__(struct __pyx_obj_3_sa_Sampler *__pyx
   __Pyx_DECREF(((PyObject *)__pyx_v_self->sa));
   __pyx_v_self->sa = __pyx_v_fsarray->sa;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":113
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":114
  *         self.sample_size = sample_size
  *         self.sa = fsarray.sa
  *         if sample_size > 0:             # <<<<<<<<<<<<<<
@@ -37955,21 +37913,21 @@ static int __pyx_pf_3_sa_7Sampler___cinit__(struct __pyx_obj_3_sa_Sampler *__pyx
   __pyx_t_1 = (__pyx_v_sample_size > 0);
   if (__pyx_t_1) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":114
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":115
  *         self.sa = fsarray.sa
  *         if sample_size > 0:
  *             logger.info("Sampling strategy: uniform, max sample size = %d", sample_size)             # <<<<<<<<<<<<<<
  *         else:
  *             logger.info("Sampling strategy: no sampling")
  */
-    __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_3 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__info); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__info); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_2 = PyInt_FromLong(__pyx_v_sample_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyInt_FromLong(__pyx_v_sample_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_INCREF(((PyObject *)__pyx_kp_s_100));
     PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_kp_s_100));
@@ -37977,7 +37935,7 @@ static int __pyx_pf_3_sa_7Sampler___cinit__(struct __pyx_obj_3_sa_Sampler *__pyx
     PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_2);
     __Pyx_GIVEREF(__pyx_t_2);
     __pyx_t_2 = 0;
-    __pyx_t_2 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
@@ -37986,19 +37944,19 @@ static int __pyx_pf_3_sa_7Sampler___cinit__(struct __pyx_obj_3_sa_Sampler *__pyx
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":116
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":117
  *             logger.info("Sampling strategy: uniform, max sample size = %d", sample_size)
  *         else:
  *             logger.info("Sampling strategy: no sampling")             # <<<<<<<<<<<<<<
  * 
  *     def sample(self, PhraseLocation phrase_location):
  */
-    __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_4 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__info); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__info); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_2 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_k_tuple_102), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_k_tuple_102), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __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;
@@ -38025,7 +37983,7 @@ static PyObject *__pyx_pw_3_sa_7Sampler_3sample(PyObject *__pyx_v_self, PyObject
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("sample (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_phrase_location), __pyx_ptype_3_sa_PhraseLocation, 1, "phrase_location", 0))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_phrase_location), __pyx_ptype_3_sa_PhraseLocation, 1, "phrase_location", 0))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_r = __pyx_pf_3_sa_7Sampler_2sample(((struct __pyx_obj_3_sa_Sampler *)__pyx_v_self), ((struct __pyx_obj_3_sa_PhraseLocation *)__pyx_v_phrase_location));
   goto __pyx_L0;
   __pyx_L1_error:;
@@ -38035,7 +37993,7 @@ static PyObject *__pyx_pw_3_sa_7Sampler_3sample(PyObject *__pyx_v_self, PyObject
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":118
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":119
  *             logger.info("Sampling strategy: no sampling")
  * 
  *     def sample(self, PhraseLocation phrase_location):             # <<<<<<<<<<<<<<
@@ -38062,19 +38020,19 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("sample", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":131
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":132
  *         cdef int num_locations, val, j
  * 
  *         sample = IntList()             # <<<<<<<<<<<<<<
  *         if phrase_location.arr is None:
  *             num_locations = phrase_location.sa_high - phrase_location.sa_low
  */
-  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_sample = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":132
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":133
  * 
  *         sample = IntList()
  *         if phrase_location.arr is None:             # <<<<<<<<<<<<<<
@@ -38084,7 +38042,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
   __pyx_t_2 = (((PyObject *)__pyx_v_phrase_location->arr) == Py_None);
   if (__pyx_t_2) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":133
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":134
  *         sample = IntList()
  *         if phrase_location.arr is None:
  *             num_locations = phrase_location.sa_high - phrase_location.sa_low             # <<<<<<<<<<<<<<
@@ -38093,7 +38051,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
  */
     __pyx_v_num_locations = (__pyx_v_phrase_location->sa_high - __pyx_v_phrase_location->sa_low);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":134
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":135
  *         if phrase_location.arr is None:
  *             num_locations = phrase_location.sa_high - phrase_location.sa_low
  *             if self.sample_size == -1 or num_locations <= self.sample_size:             # <<<<<<<<<<<<<<
@@ -38109,7 +38067,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
     }
     if (__pyx_t_4) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":135
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":136
  *             num_locations = phrase_location.sa_high - phrase_location.sa_low
  *             if self.sample_size == -1 or num_locations <= self.sample_size:
  *                 sample._extend_arr(self.sa.arr + phrase_location.sa_low, num_locations)             # <<<<<<<<<<<<<<
@@ -38121,7 +38079,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
     }
     /*else*/ {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":137
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":138
  *                 sample._extend_arr(self.sa.arr + phrase_location.sa_low, num_locations)
  *             else:
  *                 stepsize = float(num_locations)/float(self.sample_size)             # <<<<<<<<<<<<<<
@@ -38130,11 +38088,11 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
  */
       if (unlikely(((double)__pyx_v_self->sample_size) == 0)) {
         PyErr_Format(PyExc_ZeroDivisionError, "float division");
-        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       }
       __pyx_v_stepsize = (((double)__pyx_v_num_locations) / ((double)__pyx_v_self->sample_size));
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":138
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":139
  *             else:
  *                 stepsize = float(num_locations)/float(self.sample_size)
  *                 i = phrase_location.sa_low             # <<<<<<<<<<<<<<
@@ -38143,7 +38101,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
  */
       __pyx_v_i = __pyx_v_phrase_location->sa_low;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":139
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":140
  *                 stepsize = float(num_locations)/float(self.sample_size)
  *                 i = phrase_location.sa_low
  *                 while i < phrase_location.sa_high and sample.len < self.sample_size:             # <<<<<<<<<<<<<<
@@ -38160,7 +38118,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
         }
         if (!__pyx_t_3) break;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":142
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":143
  *                     '''Note: int(i) not guaranteed to have the desired
  *                     effect, according to the python documentation'''
  *                     if fmod(i,1.0) > 0.5:             # <<<<<<<<<<<<<<
@@ -38170,7 +38128,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
         __pyx_t_3 = (fmod(__pyx_v_i, 1.0) > 0.5);
         if (__pyx_t_3) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":143
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":144
  *                     effect, according to the python documentation'''
  *                     if fmod(i,1.0) > 0.5:
  *                         val = int(ceil(i))             # <<<<<<<<<<<<<<
@@ -38182,7 +38140,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
         }
         /*else*/ {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":145
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":146
  *                         val = int(ceil(i))
  *                     else:
  *                         val = int(floor(i))             # <<<<<<<<<<<<<<
@@ -38193,7 +38151,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
         }
         __pyx_L7:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":146
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":147
  *                     else:
  *                         val = int(floor(i))
  *                     sample._append(self.sa.arr[val])             # <<<<<<<<<<<<<<
@@ -38202,7 +38160,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
  */
         ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_sample->__pyx_vtab)->_append(__pyx_v_sample, (__pyx_v_self->sa->arr[__pyx_v_val]));
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":147
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":148
  *                         val = int(floor(i))
  *                     sample._append(self.sa.arr[val])
  *                     i = i + stepsize             # <<<<<<<<<<<<<<
@@ -38217,7 +38175,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":149
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":150
  *                     i = i + stepsize
  *         else:
  *             num_locations = (phrase_location.arr_high - phrase_location.arr_low) / phrase_location.num_subpatterns             # <<<<<<<<<<<<<<
@@ -38227,15 +38185,15 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
     __pyx_t_5 = (__pyx_v_phrase_location->arr_high - __pyx_v_phrase_location->arr_low);
     if (unlikely(__pyx_v_phrase_location->num_subpatterns == 0)) {
       PyErr_Format(PyExc_ZeroDivisionError, "integer division or modulo by zero");
-      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     }
     else if (sizeof(int) == sizeof(long) && unlikely(__pyx_v_phrase_location->num_subpatterns == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_t_5))) {
       PyErr_Format(PyExc_OverflowError, "value too large to perform division");
-      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     }
     __pyx_v_num_locations = __Pyx_div_int(__pyx_t_5, __pyx_v_phrase_location->num_subpatterns);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":150
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":151
  *         else:
  *             num_locations = (phrase_location.arr_high - phrase_location.arr_low) / phrase_location.num_subpatterns
  *             if self.sample_size == -1 or num_locations <= self.sample_size:             # <<<<<<<<<<<<<<
@@ -38251,7 +38209,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
     }
     if (__pyx_t_2) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":151
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":152
  *             num_locations = (phrase_location.arr_high - phrase_location.arr_low) / phrase_location.num_subpatterns
  *             if self.sample_size == -1 or num_locations <= self.sample_size:
  *                 sample = phrase_location.arr             # <<<<<<<<<<<<<<
@@ -38265,7 +38223,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
     }
     /*else*/ {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":153
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":154
  *                 sample = phrase_location.arr
  *             else:
  *                 stepsize = float(num_locations)/float(self.sample_size)             # <<<<<<<<<<<<<<
@@ -38274,11 +38232,11 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
  */
       if (unlikely(((double)__pyx_v_self->sample_size) == 0)) {
         PyErr_Format(PyExc_ZeroDivisionError, "float division");
-        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       }
       __pyx_v_stepsize = (((double)__pyx_v_num_locations) / ((double)__pyx_v_self->sample_size));
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":154
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":155
  *             else:
  *                 stepsize = float(num_locations)/float(self.sample_size)
  *                 i = phrase_location.arr_low             # <<<<<<<<<<<<<<
@@ -38287,7 +38245,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
  */
       __pyx_v_i = __pyx_v_phrase_location->arr_low;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":155
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":156
  *                 stepsize = float(num_locations)/float(self.sample_size)
  *                 i = phrase_location.arr_low
  *                 while i < num_locations and sample.len < self.sample_size * phrase_location.num_subpatterns:             # <<<<<<<<<<<<<<
@@ -38304,7 +38262,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
         }
         if (!__pyx_t_4) break;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":158
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":159
  *                     '''Note: int(i) not guaranteed to have the desired
  *                     effect, according to the python documentation'''
  *                     if fmod(i,1.0) > 0.5:             # <<<<<<<<<<<<<<
@@ -38314,7 +38272,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
         __pyx_t_4 = (fmod(__pyx_v_i, 1.0) > 0.5);
         if (__pyx_t_4) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":159
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":160
  *                     effect, according to the python documentation'''
  *                     if fmod(i,1.0) > 0.5:
  *                         val = int(ceil(i))             # <<<<<<<<<<<<<<
@@ -38326,7 +38284,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
         }
         /*else*/ {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":161
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":162
  *                         val = int(ceil(i))
  *                     else:
  *                         val = int(floor(i))             # <<<<<<<<<<<<<<
@@ -38337,7 +38295,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
         }
         __pyx_L11:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":162
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":163
  *                     else:
  *                         val = int(floor(i))
  *                     j = phrase_location.arr_low + (val*phrase_location.num_subpatterns)             # <<<<<<<<<<<<<<
@@ -38346,7 +38304,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
  */
         __pyx_v_j = (__pyx_v_phrase_location->arr_low + (__pyx_v_val * __pyx_v_phrase_location->num_subpatterns));
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":163
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":164
  *                         val = int(floor(i))
  *                     j = phrase_location.arr_low + (val*phrase_location.num_subpatterns)
  *                     sample._extend_arr(phrase_location.arr.arr + j, phrase_location.num_subpatterns)             # <<<<<<<<<<<<<<
@@ -38355,7 +38313,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
  */
         ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_sample->__pyx_vtab)->_extend_arr(__pyx_v_sample, (__pyx_v_phrase_location->arr->arr + __pyx_v_j), __pyx_v_phrase_location->num_subpatterns);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":164
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":165
  *                     j = phrase_location.arr_low + (val*phrase_location.num_subpatterns)
  *                     sample._extend_arr(phrase_location.arr.arr + j, phrase_location.num_subpatterns)
  *                     i = i + stepsize             # <<<<<<<<<<<<<<
@@ -38369,7 +38327,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":165
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":166
  *                     sample._extend_arr(phrase_location.arr.arr + j, phrase_location.num_subpatterns)
  *                     i = i + stepsize
  *         return sample             # <<<<<<<<<<<<<<
@@ -38394,7 +38352,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":177
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":178
  * 
  * 
  * cdef void assign_matching(Matching* m, int* arr, int start, int step, int* sent_id_arr):             # <<<<<<<<<<<<<<
@@ -38406,7 +38364,7 @@ static void __pyx_f_3_sa_assign_matching(struct __pyx_t_3_sa_Matching *__pyx_v_m
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("assign_matching", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":178
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":179
  * 
  * cdef void assign_matching(Matching* m, int* arr, int start, int step, int* sent_id_arr):
  *     m.arr = arr             # <<<<<<<<<<<<<<
@@ -38415,7 +38373,7 @@ static void __pyx_f_3_sa_assign_matching(struct __pyx_t_3_sa_Matching *__pyx_v_m
  */
   __pyx_v_m->arr = __pyx_v_arr;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":179
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":180
  * cdef void assign_matching(Matching* m, int* arr, int start, int step, int* sent_id_arr):
  *     m.arr = arr
  *     m.start = start             # <<<<<<<<<<<<<<
@@ -38424,7 +38382,7 @@ static void __pyx_f_3_sa_assign_matching(struct __pyx_t_3_sa_Matching *__pyx_v_m
  */
   __pyx_v_m->start = __pyx_v_start;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":180
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":181
  *     m.arr = arr
  *     m.start = start
  *     m.end = start + step             # <<<<<<<<<<<<<<
@@ -38433,7 +38391,7 @@ static void __pyx_f_3_sa_assign_matching(struct __pyx_t_3_sa_Matching *__pyx_v_m
  */
   __pyx_v_m->end = (__pyx_v_start + __pyx_v_step);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":181
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":182
  *     m.start = start
  *     m.end = start + step
  *     m.sent_id = sent_id_arr[arr[start]]             # <<<<<<<<<<<<<<
@@ -38442,7 +38400,7 @@ static void __pyx_f_3_sa_assign_matching(struct __pyx_t_3_sa_Matching *__pyx_v_m
  */
   __pyx_v_m->sent_id = (__pyx_v_sent_id_arr[(__pyx_v_arr[__pyx_v_start])]);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":182
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":183
  *     m.end = start + step
  *     m.sent_id = sent_id_arr[arr[start]]
  *     m.size = step             # <<<<<<<<<<<<<<
@@ -38454,7 +38412,7 @@ static void __pyx_f_3_sa_assign_matching(struct __pyx_t_3_sa_Matching *__pyx_v_m
   __Pyx_RefNannyFinishContext();
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":185
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":186
  * 
  * 
  * cdef int* append_combined_matching(int* arr, Matching* loc1, Matching* loc2,             # <<<<<<<<<<<<<<
@@ -38471,7 +38429,7 @@ static int *__pyx_f_3_sa_append_combined_matching(int *__pyx_v_arr, struct __pyx
   int __pyx_t_2;
   __Pyx_RefNannySetupContext("append_combined_matching", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":189
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":190
  *     cdef int i, new_len
  * 
  *     new_len = result_len[0] + num_subpatterns             # <<<<<<<<<<<<<<
@@ -38480,7 +38438,7 @@ static int *__pyx_f_3_sa_append_combined_matching(int *__pyx_v_arr, struct __pyx
  */
   __pyx_v_new_len = ((__pyx_v_result_len[0]) + __pyx_v_num_subpatterns);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":190
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":191
  * 
  *     new_len = result_len[0] + num_subpatterns
  *     arr = <int*> realloc(arr, new_len*sizeof(int))             # <<<<<<<<<<<<<<
@@ -38489,7 +38447,7 @@ static int *__pyx_f_3_sa_append_combined_matching(int *__pyx_v_arr, struct __pyx
  */
   __pyx_v_arr = ((int *)realloc(__pyx_v_arr, (__pyx_v_new_len * (sizeof(int)))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":192
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":193
  *     arr = <int*> realloc(arr, new_len*sizeof(int))
  * 
  *     for i from 0 <= i < loc1.size:             # <<<<<<<<<<<<<<
@@ -38499,7 +38457,7 @@ static int *__pyx_f_3_sa_append_combined_matching(int *__pyx_v_arr, struct __pyx
   __pyx_t_1 = __pyx_v_loc1->size;
   for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_1; __pyx_v_i++) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":193
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":194
  * 
  *     for i from 0 <= i < loc1.size:
  *         arr[result_len[0]+i] = loc1.arr[loc1.start+i]             # <<<<<<<<<<<<<<
@@ -38509,7 +38467,7 @@ static int *__pyx_f_3_sa_append_combined_matching(int *__pyx_v_arr, struct __pyx
     (__pyx_v_arr[((__pyx_v_result_len[0]) + __pyx_v_i)]) = (__pyx_v_loc1->arr[(__pyx_v_loc1->start + __pyx_v_i)]);
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":194
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":195
  *     for i from 0 <= i < loc1.size:
  *         arr[result_len[0]+i] = loc1.arr[loc1.start+i]
  *     if num_subpatterns > loc1.size:             # <<<<<<<<<<<<<<
@@ -38519,7 +38477,7 @@ static int *__pyx_f_3_sa_append_combined_matching(int *__pyx_v_arr, struct __pyx
   __pyx_t_2 = (__pyx_v_num_subpatterns > __pyx_v_loc1->size);
   if (__pyx_t_2) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":195
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":196
  *         arr[result_len[0]+i] = loc1.arr[loc1.start+i]
  *     if num_subpatterns > loc1.size:
  *         arr[new_len-1] = loc2.arr[loc2.end-1]             # <<<<<<<<<<<<<<
@@ -38531,7 +38489,7 @@ static int *__pyx_f_3_sa_append_combined_matching(int *__pyx_v_arr, struct __pyx
   }
   __pyx_L5:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":196
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":197
  *     if num_subpatterns > loc1.size:
  *         arr[new_len-1] = loc2.arr[loc2.end-1]
  *     result_len[0] = new_len             # <<<<<<<<<<<<<<
@@ -38540,7 +38498,7 @@ static int *__pyx_f_3_sa_append_combined_matching(int *__pyx_v_arr, struct __pyx
  */
   (__pyx_v_result_len[0]) = __pyx_v_new_len;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":197
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":198
  *         arr[new_len-1] = loc2.arr[loc2.end-1]
  *     result_len[0] = new_len
  *     return arr             # <<<<<<<<<<<<<<
@@ -38556,7 +38514,7 @@ static int *__pyx_f_3_sa_append_combined_matching(int *__pyx_v_arr, struct __pyx
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":200
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":201
  * 
  * 
  * cdef int* extend_arr(int* arr, int* arr_len, int* appendix, int appendix_len):             # <<<<<<<<<<<<<<
@@ -38570,7 +38528,7 @@ static int *__pyx_f_3_sa_extend_arr(int *__pyx_v_arr, int *__pyx_v_arr_len, int
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("extend_arr", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":203
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":204
  *     cdef int new_len
  * 
  *     new_len = arr_len[0] + appendix_len             # <<<<<<<<<<<<<<
@@ -38579,7 +38537,7 @@ static int *__pyx_f_3_sa_extend_arr(int *__pyx_v_arr, int *__pyx_v_arr_len, int
  */
   __pyx_v_new_len = ((__pyx_v_arr_len[0]) + __pyx_v_appendix_len);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":204
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":205
  * 
  *     new_len = arr_len[0] + appendix_len
  *     arr = <int*> realloc(arr, new_len*sizeof(int))             # <<<<<<<<<<<<<<
@@ -38588,7 +38546,7 @@ static int *__pyx_f_3_sa_extend_arr(int *__pyx_v_arr, int *__pyx_v_arr_len, int
  */
   __pyx_v_arr = ((int *)realloc(__pyx_v_arr, (__pyx_v_new_len * (sizeof(int)))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":205
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":206
  *     new_len = arr_len[0] + appendix_len
  *     arr = <int*> realloc(arr, new_len*sizeof(int))
  *     memcpy(arr+arr_len[0], appendix, appendix_len*sizeof(int))             # <<<<<<<<<<<<<<
@@ -38597,7 +38555,7 @@ static int *__pyx_f_3_sa_extend_arr(int *__pyx_v_arr, int *__pyx_v_arr_len, int
  */
   memcpy((__pyx_v_arr + (__pyx_v_arr_len[0])), __pyx_v_appendix, (__pyx_v_appendix_len * (sizeof(int))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":206
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":207
  *     arr = <int*> realloc(arr, new_len*sizeof(int))
  *     memcpy(arr+arr_len[0], appendix, appendix_len*sizeof(int))
  *     arr_len[0] = new_len             # <<<<<<<<<<<<<<
@@ -38606,7 +38564,7 @@ static int *__pyx_f_3_sa_extend_arr(int *__pyx_v_arr, int *__pyx_v_arr_len, int
  */
   (__pyx_v_arr_len[0]) = __pyx_v_new_len;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":207
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":208
  *     memcpy(arr+arr_len[0], appendix, appendix_len*sizeof(int))
  *     arr_len[0] = new_len
  *     return arr             # <<<<<<<<<<<<<<
@@ -38622,7 +38580,7 @@ static int *__pyx_f_3_sa_extend_arr(int *__pyx_v_arr, int *__pyx_v_arr_len, int
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":209
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":210
  *     return arr
  * 
  * cdef int median(int low, int high, int step):             # <<<<<<<<<<<<<<
@@ -38639,7 +38597,7 @@ static int __pyx_f_3_sa_median(int __pyx_v_low, int __pyx_v_high, int __pyx_v_st
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("median", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":210
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":211
  * 
  * cdef int median(int low, int high, int step):
  *     return low + (((high - low)/step)/2)*step             # <<<<<<<<<<<<<<
@@ -38649,11 +38607,11 @@ static int __pyx_f_3_sa_median(int __pyx_v_low, int __pyx_v_high, int __pyx_v_st
   __pyx_t_1 = (__pyx_v_high - __pyx_v_low);
   if (unlikely(__pyx_v_step == 0)) {
     PyErr_Format(PyExc_ZeroDivisionError, "integer division or modulo by zero");
-    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 211; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   else if (sizeof(int) == sizeof(long) && unlikely(__pyx_v_step == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_t_1))) {
     PyErr_Format(PyExc_OverflowError, "value too large to perform division");
-    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 211; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __pyx_r = (__pyx_v_low + (__Pyx_div_long(__Pyx_div_int(__pyx_t_1, __pyx_v_step), 2) * __pyx_v_step));
   goto __pyx_L0;
@@ -38668,7 +38626,7 @@ static int __pyx_f_3_sa_median(int __pyx_v_low, int __pyx_v_high, int __pyx_v_st
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":213
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":214
  * 
  * 
  * cdef void find_comparable_matchings(int low, int high, int* arr, int step, int loc, int* loc_minus, int* loc_plus):             # <<<<<<<<<<<<<<
@@ -38683,7 +38641,7 @@ static void __pyx_f_3_sa_find_comparable_matchings(int __pyx_v_low, int __pyx_v_
   int __pyx_t_3;
   __Pyx_RefNannySetupContext("find_comparable_matchings", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":217
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":218
  *     # in which all matchings have the same first index as the one
  *     # starting at loc
  *     loc_plus[0] = loc + step             # <<<<<<<<<<<<<<
@@ -38692,7 +38650,7 @@ static void __pyx_f_3_sa_find_comparable_matchings(int __pyx_v_low, int __pyx_v_
  */
   (__pyx_v_loc_plus[0]) = (__pyx_v_loc + __pyx_v_step);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":218
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":219
  *     # starting at loc
  *     loc_plus[0] = loc + step
  *     while loc_plus[0] < high and arr[loc_plus[0]] == arr[loc]:             # <<<<<<<<<<<<<<
@@ -38709,7 +38667,7 @@ static void __pyx_f_3_sa_find_comparable_matchings(int __pyx_v_low, int __pyx_v_
     }
     if (!__pyx_t_3) break;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":219
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":220
  *     loc_plus[0] = loc + step
  *     while loc_plus[0] < high and arr[loc_plus[0]] == arr[loc]:
  *         loc_plus[0] = loc_plus[0] + step             # <<<<<<<<<<<<<<
@@ -38719,7 +38677,7 @@ static void __pyx_f_3_sa_find_comparable_matchings(int __pyx_v_low, int __pyx_v_
     (__pyx_v_loc_plus[0]) = ((__pyx_v_loc_plus[0]) + __pyx_v_step);
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":220
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":221
  *     while loc_plus[0] < high and arr[loc_plus[0]] == arr[loc]:
  *         loc_plus[0] = loc_plus[0] + step
  *     loc_minus[0] = loc             # <<<<<<<<<<<<<<
@@ -38728,7 +38686,7 @@ static void __pyx_f_3_sa_find_comparable_matchings(int __pyx_v_low, int __pyx_v_
  */
   (__pyx_v_loc_minus[0]) = __pyx_v_loc;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":221
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":222
  *         loc_plus[0] = loc_plus[0] + step
  *     loc_minus[0] = loc
  *     while loc_minus[0]-step >= low and arr[loc_minus[0]-step] == arr[loc]:             # <<<<<<<<<<<<<<
@@ -38745,7 +38703,7 @@ static void __pyx_f_3_sa_find_comparable_matchings(int __pyx_v_low, int __pyx_v_
     }
     if (!__pyx_t_2) break;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":222
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":223
  *     loc_minus[0] = loc
  *     while loc_minus[0]-step >= low and arr[loc_minus[0]-step] == arr[loc]:
  *         loc_minus[0] = loc_minus[0] - step             # <<<<<<<<<<<<<<
@@ -38789,7 +38747,7 @@ static int __pyx_pw_3_sa_23HieroCachingRuleFactory_1__cinit__(PyObject *__pyx_v_
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__alignment,&__pyx_n_s__by_slack_factor,&__pyx_n_s__category,&__pyx_n_s__max_chunks,&__pyx_n_s__max_initial_size,&__pyx_n_s__max_length,&__pyx_n_s__max_nonterminals,&__pyx_n_s__max_target_chunks,&__pyx_n_s__max_target_length,&__pyx_n_s__min_gap_size,&__pyx_n_s__precompute_file,&__pyx_n_s_70,&__pyx_n_s__precompute_rank,&__pyx_n_s_103,&__pyx_n_s_104,&__pyx_n_s_71,&__pyx_n_s__train_min_gap_size,&__pyx_n_s__tight_phrases,&__pyx_n_s__use_baeza_yates,&__pyx_n_s__use_collocations,&__pyx_n_s__use_index,0};
     PyObject* values[21] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":291
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":293
  *             char* category="[X]",
  *             # maximum number of contiguous chunks of terminal symbols in RHS of a rule. If None, defaults to max_nonterminals+1
  *             max_chunks=None,             # <<<<<<<<<<<<<<
@@ -38798,7 +38756,7 @@ static int __pyx_pw_3_sa_23HieroCachingRuleFactory_1__cinit__(PyObject *__pyx_v_
  */
     values[3] = ((PyObject *)Py_None);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":299
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":301
  *             unsigned max_nonterminals=2,
  *             # maximum number of contiguous chunks of terminal symbols in target-side RHS of a rule. If None, defaults to max_nonterminals+1
  *             max_target_chunks=None,             # <<<<<<<<<<<<<<
@@ -38807,7 +38765,7 @@ static int __pyx_pw_3_sa_23HieroCachingRuleFactory_1__cinit__(PyObject *__pyx_v_
  */
     values[7] = ((PyObject *)Py_None);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":301
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":303
  *             max_target_chunks=None,
  *             # maximum number of target side symbols (both T and NT) allowed in a rule. If None, defaults to max_initial_size
  *             max_target_length=None,             # <<<<<<<<<<<<<<
@@ -38816,7 +38774,7 @@ static int __pyx_pw_3_sa_23HieroCachingRuleFactory_1__cinit__(PyObject *__pyx_v_
  */
     values[8] = ((PyObject *)Py_None);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":305
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":307
  *             unsigned min_gap_size=2,
  *             # filename of file containing precomputed collocations
  *             precompute_file=None,             # <<<<<<<<<<<<<<
@@ -38959,7 +38917,7 @@ static int __pyx_pw_3_sa_23HieroCachingRuleFactory_1__cinit__(PyObject *__pyx_v_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -38990,10 +38948,10 @@ static int __pyx_pw_3_sa_23HieroCachingRuleFactory_1__cinit__(PyObject *__pyx_v_
     }
     __pyx_v_alignment = ((struct __pyx_obj_3_sa_Alignment *)values[0]);
     if (values[1]) {
-      __pyx_v_by_slack_factor = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_by_slack_factor == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_by_slack_factor = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_by_slack_factor == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":287
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":289
  *             Alignment alignment,
  *             # parameter for double-binary search; doesn't seem to matter much
  *             float by_slack_factor=1.0,             # <<<<<<<<<<<<<<
@@ -39003,49 +38961,49 @@ static int __pyx_pw_3_sa_23HieroCachingRuleFactory_1__cinit__(PyObject *__pyx_v_
       __pyx_v_by_slack_factor = ((float)1.0);
     }
     if (values[2]) {
-      __pyx_v_category = PyBytes_AsString(values[2]); if (unlikely((!__pyx_v_category) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_category = PyBytes_AsString(values[2]); if (unlikely((!__pyx_v_category) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 291; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
       __pyx_v_category = ((char *)__pyx_k_105);
     }
     __pyx_v_max_chunks = values[3];
     if (values[4]) {
-      __pyx_v_max_initial_size = __Pyx_PyInt_AsUnsignedInt(values[4]); if (unlikely((__pyx_v_max_initial_size == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_max_initial_size = __Pyx_PyInt_AsUnsignedInt(values[4]); if (unlikely((__pyx_v_max_initial_size == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 295; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
       __pyx_v_max_initial_size = ((unsigned int)10);
     }
     if (values[5]) {
-      __pyx_v_max_length = __Pyx_PyInt_AsUnsignedInt(values[5]); if (unlikely((__pyx_v_max_length == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 295; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_max_length = __Pyx_PyInt_AsUnsignedInt(values[5]); if (unlikely((__pyx_v_max_length == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
       __pyx_v_max_length = ((unsigned int)5);
     }
     if (values[6]) {
-      __pyx_v_max_nonterminals = __Pyx_PyInt_AsUnsignedInt(values[6]); if (unlikely((__pyx_v_max_nonterminals == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_max_nonterminals = __Pyx_PyInt_AsUnsignedInt(values[6]); if (unlikely((__pyx_v_max_nonterminals == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
       __pyx_v_max_nonterminals = ((unsigned int)2);
     }
     __pyx_v_max_target_chunks = values[7];
     __pyx_v_max_target_length = values[8];
     if (values[9]) {
-      __pyx_v_min_gap_size = __Pyx_PyInt_AsUnsignedInt(values[9]); if (unlikely((__pyx_v_min_gap_size == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 303; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_min_gap_size = __Pyx_PyInt_AsUnsignedInt(values[9]); if (unlikely((__pyx_v_min_gap_size == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
       __pyx_v_min_gap_size = ((unsigned int)2);
     }
     __pyx_v_precompute_file = values[10];
     if (values[11]) {
-      __pyx_v_precompute_secondary_rank = __Pyx_PyInt_AsUnsignedInt(values[11]); if (unlikely((__pyx_v_precompute_secondary_rank == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 307; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_precompute_secondary_rank = __Pyx_PyInt_AsUnsignedInt(values[11]); if (unlikely((__pyx_v_precompute_secondary_rank == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
       __pyx_v_precompute_secondary_rank = ((unsigned int)20);
     }
     if (values[12]) {
-      __pyx_v_precompute_rank = __Pyx_PyInt_AsUnsignedInt(values[12]); if (unlikely((__pyx_v_precompute_rank == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_precompute_rank = __Pyx_PyInt_AsUnsignedInt(values[12]); if (unlikely((__pyx_v_precompute_rank == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
       __pyx_v_precompute_rank = ((unsigned int)100);
     }
     if (values[13]) {
-      __pyx_v_require_aligned_terminal = __Pyx_PyObject_IsTrue(values[13]); if (unlikely((__pyx_v_require_aligned_terminal == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_require_aligned_terminal = __Pyx_PyObject_IsTrue(values[13]); if (unlikely((__pyx_v_require_aligned_terminal == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 313; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":311
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":313
  *             unsigned precompute_rank=100,
  *             # require extracted rules to have at least one aligned word
  *             bint require_aligned_terminal=True,             # <<<<<<<<<<<<<<
@@ -39055,10 +39013,10 @@ static int __pyx_pw_3_sa_23HieroCachingRuleFactory_1__cinit__(PyObject *__pyx_v_
       __pyx_v_require_aligned_terminal = ((int)1);
     }
     if (values[14]) {
-      __pyx_v_require_aligned_chunks = __Pyx_PyObject_IsTrue(values[14]); if (unlikely((__pyx_v_require_aligned_chunks == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 313; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_require_aligned_chunks = __Pyx_PyObject_IsTrue(values[14]); if (unlikely((__pyx_v_require_aligned_chunks == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":313
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":315
  *             bint require_aligned_terminal=True,
  *             # require each contiguous chunk of extracted rules to have at least one aligned word
  *             bint require_aligned_chunks=False,             # <<<<<<<<<<<<<<
@@ -39068,20 +39026,20 @@ static int __pyx_pw_3_sa_23HieroCachingRuleFactory_1__cinit__(PyObject *__pyx_v_
       __pyx_v_require_aligned_chunks = ((int)0);
     }
     if (values[15]) {
-      __pyx_v_train_max_initial_size = __Pyx_PyInt_AsUnsignedInt(values[15]); if (unlikely((__pyx_v_train_max_initial_size == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_train_max_initial_size = __Pyx_PyInt_AsUnsignedInt(values[15]); if (unlikely((__pyx_v_train_max_initial_size == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
       __pyx_v_train_max_initial_size = ((unsigned int)10);
     }
     if (values[16]) {
-      __pyx_v_train_min_gap_size = __Pyx_PyInt_AsUnsignedInt(values[16]); if (unlikely((__pyx_v_train_min_gap_size == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_train_min_gap_size = __Pyx_PyInt_AsUnsignedInt(values[16]); if (unlikely((__pyx_v_train_min_gap_size == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 319; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
       __pyx_v_train_min_gap_size = ((unsigned int)2);
     }
     if (values[17]) {
-      __pyx_v_tight_phrases = __Pyx_PyObject_IsTrue(values[17]); if (unlikely((__pyx_v_tight_phrases == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 319; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_tight_phrases = __Pyx_PyObject_IsTrue(values[17]); if (unlikely((__pyx_v_tight_phrases == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":319
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":321
  *             unsigned train_min_gap_size=2,
  *             # False if phrases should be loose (better but slower), True otherwise
  *             bint tight_phrases=True,             # <<<<<<<<<<<<<<
@@ -39091,10 +39049,10 @@ static int __pyx_pw_3_sa_23HieroCachingRuleFactory_1__cinit__(PyObject *__pyx_v_
       __pyx_v_tight_phrases = ((int)1);
     }
     if (values[18]) {
-      __pyx_v_use_baeza_yates = __Pyx_PyObject_IsTrue(values[18]); if (unlikely((__pyx_v_use_baeza_yates == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_use_baeza_yates = __Pyx_PyObject_IsTrue(values[18]); if (unlikely((__pyx_v_use_baeza_yates == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":321
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":323
  *             bint tight_phrases=True,
  *             # True to require use of double-binary alg, false otherwise
  *             bint use_baeza_yates=True,             # <<<<<<<<<<<<<<
@@ -39104,10 +39062,10 @@ static int __pyx_pw_3_sa_23HieroCachingRuleFactory_1__cinit__(PyObject *__pyx_v_
       __pyx_v_use_baeza_yates = ((int)1);
     }
     if (values[19]) {
-      __pyx_v_use_collocations = __Pyx_PyObject_IsTrue(values[19]); if (unlikely((__pyx_v_use_collocations == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_use_collocations = __Pyx_PyObject_IsTrue(values[19]); if (unlikely((__pyx_v_use_collocations == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":323
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":325
  *             bint use_baeza_yates=True,
  *             # True to enable used of precomputed collocations
  *             bint use_collocations=True,             # <<<<<<<<<<<<<<
@@ -39117,10 +39075,10 @@ static int __pyx_pw_3_sa_23HieroCachingRuleFactory_1__cinit__(PyObject *__pyx_v_
       __pyx_v_use_collocations = ((int)1);
     }
     if (values[20]) {
-      __pyx_v_use_index = __Pyx_PyObject_IsTrue(values[20]); if (unlikely((__pyx_v_use_index == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_use_index = __Pyx_PyObject_IsTrue(values[20]); if (unlikely((__pyx_v_use_index == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":325
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":327
  *             bint use_collocations=True,
  *             # True to enable use of precomputed inverted indices
  *             bint use_index=True):             # <<<<<<<<<<<<<<
@@ -39132,13 +39090,13 @@ static int __pyx_pw_3_sa_23HieroCachingRuleFactory_1__cinit__(PyObject *__pyx_v_
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 1, 21, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 1, 21, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return -1;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_alignment), __pyx_ptype_3_sa_Alignment, 1, "alignment", 0))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_alignment), __pyx_ptype_3_sa_Alignment, 1, "alignment", 0))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_r = __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(((struct __pyx_obj_3_sa_HieroCachingRuleFactory *)__pyx_v_self), __pyx_v_alignment, __pyx_v_by_slack_factor, __pyx_v_category, __pyx_v_max_chunks, __pyx_v_max_initial_size, __pyx_v_max_length, __pyx_v_max_nonterminals, __pyx_v_max_target_chunks, __pyx_v_max_target_length, __pyx_v_min_gap_size, __pyx_v_precompute_file, __pyx_v_precompute_secondary_rank, __pyx_v_precompute_rank, __pyx_v_require_aligned_terminal, __pyx_v_require_aligned_chunks, __pyx_v_train_max_initial_size, __pyx_v_train_min_gap_size, __pyx_v_tight_phrases, __pyx_v_use_baeza_yates, __pyx_v_use_collocations, __pyx_v_use_index);
   goto __pyx_L0;
   __pyx_L1_error:;
@@ -39160,7 +39118,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_9__cinit___lambda1(PyOb
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":398
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":403
  *         self.phrases_f = defaultdict(int)
  *         self.phrases_e = defaultdict(int)
  *         self.phrases_fe = defaultdict(lambda: defaultdict(int))             # <<<<<<<<<<<<<<
@@ -39179,14 +39137,14 @@ static PyObject *__pyx_lambda_funcdef_lambda1(CYTHON_UNUSED PyObject *__pyx_self
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("lambda1", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_INCREF(((PyObject *)((PyObject*)(&PyInt_Type))));
   PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)((PyObject*)(&PyInt_Type))));
   __Pyx_GIVEREF(((PyObject *)((PyObject*)(&PyInt_Type))));
-  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
@@ -39220,7 +39178,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_9__cinit___1lambda2(PyO
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":399
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":404
  *         self.phrases_e = defaultdict(int)
  *         self.phrases_fe = defaultdict(lambda: defaultdict(int))
  *         self.phrases_al = defaultdict(lambda: defaultdict(tuple))             # <<<<<<<<<<<<<<
@@ -39239,14 +39197,14 @@ static PyObject *__pyx_lambda_funcdef_lambda2(CYTHON_UNUSED PyObject *__pyx_self
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("lambda2", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 399; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 399; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_INCREF(((PyObject *)((PyObject*)(&PyTuple_Type))));
   PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)((PyObject*)(&PyTuple_Type))));
   __Pyx_GIVEREF(((PyObject *)((PyObject*)(&PyTuple_Type))));
-  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 399; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
@@ -39280,7 +39238,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_9__cinit___2lambda3(PyO
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":404
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":409
  *         self.bilex_f = defaultdict(int)
  *         self.bilex_e = defaultdict(int)
  *         self.bilex_fe = defaultdict(lambda: defaultdict(int))             # <<<<<<<<<<<<<<
@@ -39299,14 +39257,14 @@ static PyObject *__pyx_lambda_funcdef_lambda3(CYTHON_UNUSED PyObject *__pyx_self
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("lambda3", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_INCREF(((PyObject *)((PyObject*)(&PyInt_Type))));
   PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)((PyObject*)(&PyInt_Type))));
   __Pyx_GIVEREF(((PyObject *)((PyObject*)(&PyInt_Type))));
-  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
@@ -39328,7 +39286,7 @@ static PyObject *__pyx_lambda_funcdef_lambda3(CYTHON_UNUSED PyObject *__pyx_self
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":283
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":285
  *     cdef bilex_fe
  * 
  *     def __cinit__(self,             # <<<<<<<<<<<<<<
@@ -39349,21 +39307,21 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__cinit__", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":331
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":333
  *         respectively.    This is because Chiang's model does not require
  *         them to be the same, therefore we don't either.'''
  *         self.rules = TrieTable(True) # cache             # <<<<<<<<<<<<<<
  *         self.rules.root = ExtendedTrieNode(phrase_location=PhraseLocation())
  *         if alignment is None:
  */
-  __pyx_t_1 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 333; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 333; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_1);
   __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_TrieTable)), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_TrieTable)), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 333; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
   __Pyx_GIVEREF(__pyx_t_1);
@@ -39372,20 +39330,20 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __pyx_v_self->rules = ((struct __pyx_obj_3_sa_TrieTable *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":332
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":334
  *         them to be the same, therefore we don't either.'''
  *         self.rules = TrieTable(True) # cache
  *         self.rules.root = ExtendedTrieNode(phrase_location=PhraseLocation())             # <<<<<<<<<<<<<<
  *         if alignment is None:
  *             raise Exception("Must specify an alignment object")
  */
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 332; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_PhraseLocation)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 332; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_PhraseLocation)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__phrase_location), __pyx_t_2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 332; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__phrase_location), __pyx_t_2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_ExtendedTrieNode)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 332; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_ExtendedTrieNode)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
   __Pyx_GIVEREF(__pyx_t_2);
@@ -39394,7 +39352,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __pyx_v_self->rules->root = __pyx_t_2;
   __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":333
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":335
  *         self.rules = TrieTable(True) # cache
  *         self.rules.root = ExtendedTrieNode(phrase_location=PhraseLocation())
  *         if alignment is None:             # <<<<<<<<<<<<<<
@@ -39404,23 +39362,23 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __pyx_t_3 = (((PyObject *)__pyx_v_alignment) == Py_None);
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":334
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":336
  *         self.rules.root = ExtendedTrieNode(phrase_location=PhraseLocation())
  *         if alignment is None:
  *             raise Exception("Must specify an alignment object")             # <<<<<<<<<<<<<<
  *         self.alignment = alignment
  * 
  */
-    __pyx_t_2 = PyObject_Call(__pyx_builtin_Exception, ((PyObject *)__pyx_k_tuple_107), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyObject_Call(__pyx_builtin_Exception, ((PyObject *)__pyx_k_tuple_107), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 336; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 336; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     goto __pyx_L3;
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":335
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":337
  *         if alignment is None:
  *             raise Exception("Must specify an alignment object")
  *         self.alignment = alignment             # <<<<<<<<<<<<<<
@@ -39433,7 +39391,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __Pyx_DECREF(((PyObject *)__pyx_v_self->alignment));
   __pyx_v_self->alignment = __pyx_v_alignment;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":339
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":341
  *         # grammar parameters and settings
  *         # NOTE: setting max_nonterminals > 2 is not currently supported in Hiero
  *         self.max_length = max_length             # <<<<<<<<<<<<<<
@@ -39442,7 +39400,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   __pyx_v_self->max_length = __pyx_v_max_length;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":340
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":342
  *         # NOTE: setting max_nonterminals > 2 is not currently supported in Hiero
  *         self.max_length = max_length
  *         self.max_nonterminals = max_nonterminals             # <<<<<<<<<<<<<<
@@ -39451,7 +39409,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   __pyx_v_self->max_nonterminals = __pyx_v_max_nonterminals;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":341
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":343
  *         self.max_length = max_length
  *         self.max_nonterminals = max_nonterminals
  *         self.max_initial_size = max_initial_size             # <<<<<<<<<<<<<<
@@ -39460,7 +39418,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   __pyx_v_self->max_initial_size = __pyx_v_max_initial_size;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":342
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":344
  *         self.max_nonterminals = max_nonterminals
  *         self.max_initial_size = max_initial_size
  *         self.train_max_initial_size = train_max_initial_size             # <<<<<<<<<<<<<<
@@ -39469,7 +39427,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   __pyx_v_self->train_max_initial_size = __pyx_v_train_max_initial_size;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":343
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":345
  *         self.max_initial_size = max_initial_size
  *         self.train_max_initial_size = train_max_initial_size
  *         self.min_gap_size = min_gap_size             # <<<<<<<<<<<<<<
@@ -39478,7 +39436,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   __pyx_v_self->min_gap_size = __pyx_v_min_gap_size;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":344
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":346
  *         self.train_max_initial_size = train_max_initial_size
  *         self.min_gap_size = min_gap_size
  *         self.train_min_gap_size = train_min_gap_size             # <<<<<<<<<<<<<<
@@ -39487,7 +39445,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   __pyx_v_self->train_min_gap_size = __pyx_v_train_min_gap_size;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":345
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":347
  *         self.min_gap_size = min_gap_size
  *         self.train_min_gap_size = train_min_gap_size
  *         self.category = sym_fromstring(category, False)             # <<<<<<<<<<<<<<
@@ -39496,7 +39454,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   __pyx_v_self->category = __pyx_f_3_sa_sym_fromstring(__pyx_v_category, 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":347
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":349
  *         self.category = sym_fromstring(category, False)
  * 
  *         if max_chunks is None:             # <<<<<<<<<<<<<<
@@ -39506,7 +39464,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __pyx_t_3 = (__pyx_v_max_chunks == Py_None);
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":348
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":350
  * 
  *         if max_chunks is None:
  *             self.max_chunks = self.max_nonterminals + 1             # <<<<<<<<<<<<<<
@@ -39518,19 +39476,19 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":350
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":352
  *             self.max_chunks = self.max_nonterminals + 1
  *         else:
  *             self.max_chunks = max_chunks             # <<<<<<<<<<<<<<
  * 
  *         if max_target_chunks is None:
  */
-    __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_v_max_chunks); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_v_max_chunks); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __pyx_v_self->max_chunks = __pyx_t_4;
   }
   __pyx_L4:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":352
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":354
  *             self.max_chunks = max_chunks
  * 
  *         if max_target_chunks is None:             # <<<<<<<<<<<<<<
@@ -39540,7 +39498,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __pyx_t_3 = (__pyx_v_max_target_chunks == Py_None);
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":353
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":355
  * 
  *         if max_target_chunks is None:
  *             self.max_target_chunks = self.max_nonterminals + 1             # <<<<<<<<<<<<<<
@@ -39552,19 +39510,19 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":355
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":357
  *             self.max_target_chunks = self.max_nonterminals + 1
  *         else:
  *             self.max_target_chunks = max_target_chunks             # <<<<<<<<<<<<<<
  * 
  *         if max_target_length is None:
  */
-    __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_v_max_target_chunks); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 355; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_v_max_target_chunks); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __pyx_v_self->max_target_chunks = __pyx_t_4;
   }
   __pyx_L5:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":357
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":359
  *             self.max_target_chunks = max_target_chunks
  * 
  *         if max_target_length is None:             # <<<<<<<<<<<<<<
@@ -39574,7 +39532,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __pyx_t_3 = (__pyx_v_max_target_length == Py_None);
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":358
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":360
  * 
  *         if max_target_length is None:
  *             self.max_target_length = max_initial_size             # <<<<<<<<<<<<<<
@@ -39586,26 +39544,26 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":360
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":362
  *             self.max_target_length = max_initial_size
  *         else:
  *             self.max_target_length = max_target_length             # <<<<<<<<<<<<<<
  * 
  *         # algorithmic parameters and settings
  */
-    __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_v_max_target_length); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_v_max_target_length); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 362; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __pyx_v_self->max_target_length = __pyx_t_4;
   }
   __pyx_L6:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":363
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":365
  * 
  *         # algorithmic parameters and settings
  *         self.precomputed_collocations = {}             # <<<<<<<<<<<<<<
  *         self.precomputed_index = {}
  *         self.use_index = use_index
  */
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 365; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_2));
   __Pyx_GIVEREF(((PyObject *)__pyx_t_2));
   __Pyx_GOTREF(__pyx_v_self->precomputed_collocations);
@@ -39613,14 +39571,14 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __pyx_v_self->precomputed_collocations = ((PyObject *)__pyx_t_2);
   __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":364
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":366
  *         # algorithmic parameters and settings
  *         self.precomputed_collocations = {}
  *         self.precomputed_index = {}             # <<<<<<<<<<<<<<
  *         self.use_index = use_index
  *         self.use_collocations = use_collocations
  */
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 364; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 366; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_2));
   __Pyx_GIVEREF(((PyObject *)__pyx_t_2));
   __Pyx_GOTREF(__pyx_v_self->precomputed_index);
@@ -39628,7 +39586,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __pyx_v_self->precomputed_index = ((PyObject *)__pyx_t_2);
   __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":365
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":367
  *         self.precomputed_collocations = {}
  *         self.precomputed_index = {}
  *         self.use_index = use_index             # <<<<<<<<<<<<<<
@@ -39637,7 +39595,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   __pyx_v_self->use_index = __pyx_v_use_index;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":366
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":368
  *         self.precomputed_index = {}
  *         self.use_index = use_index
  *         self.use_collocations = use_collocations             # <<<<<<<<<<<<<<
@@ -39646,14 +39604,14 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   __pyx_v_self->use_collocations = __pyx_v_use_collocations;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":367
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":369
  *         self.use_index = use_index
  *         self.use_collocations = use_collocations
  *         self.max_rank = {}             # <<<<<<<<<<<<<<
  *         self.precompute_file = precompute_file
  *         self.precompute_rank = precompute_rank
  */
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 369; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_2));
   __Pyx_GIVEREF(((PyObject *)__pyx_t_2));
   __Pyx_GOTREF(__pyx_v_self->max_rank);
@@ -39661,7 +39619,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __pyx_v_self->max_rank = ((PyObject *)__pyx_t_2);
   __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":368
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":370
  *         self.use_collocations = use_collocations
  *         self.max_rank = {}
  *         self.precompute_file = precompute_file             # <<<<<<<<<<<<<<
@@ -39674,7 +39632,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __Pyx_DECREF(__pyx_v_self->precompute_file);
   __pyx_v_self->precompute_file = __pyx_v_precompute_file;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":369
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":371
  *         self.max_rank = {}
  *         self.precompute_file = precompute_file
  *         self.precompute_rank = precompute_rank             # <<<<<<<<<<<<<<
@@ -39683,7 +39641,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   __pyx_v_self->precompute_rank = __pyx_v_precompute_rank;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":370
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":372
  *         self.precompute_file = precompute_file
  *         self.precompute_rank = precompute_rank
  *         self.precompute_secondary_rank = precompute_secondary_rank             # <<<<<<<<<<<<<<
@@ -39692,7 +39650,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   __pyx_v_self->precompute_secondary_rank = __pyx_v_precompute_secondary_rank;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":371
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":373
  *         self.precompute_rank = precompute_rank
  *         self.precompute_secondary_rank = precompute_secondary_rank
  *         self.use_baeza_yates = use_baeza_yates             # <<<<<<<<<<<<<<
@@ -39701,7 +39659,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   __pyx_v_self->use_baeza_yates = __pyx_v_use_baeza_yates;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":372
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":374
  *         self.precompute_secondary_rank = precompute_secondary_rank
  *         self.use_baeza_yates = use_baeza_yates
  *         self.by_slack_factor = by_slack_factor             # <<<<<<<<<<<<<<
@@ -39710,7 +39668,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   __pyx_v_self->by_slack_factor = __pyx_v_by_slack_factor;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":373
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":375
  *         self.use_baeza_yates = use_baeza_yates
  *         self.by_slack_factor = by_slack_factor
  *         self.tight_phrases = tight_phrases             # <<<<<<<<<<<<<<
@@ -39719,7 +39677,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   __pyx_v_self->tight_phrases = __pyx_v_tight_phrases;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":375
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":377
  *         self.tight_phrases = tight_phrases
  * 
  *         if require_aligned_chunks:             # <<<<<<<<<<<<<<
@@ -39728,7 +39686,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   if (__pyx_v_require_aligned_chunks) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":377
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":379
  *         if require_aligned_chunks:
  *             # one condition is a stronger version of the other.
  *             self.require_aligned_chunks = self.require_aligned_terminal = True             # <<<<<<<<<<<<<<
@@ -39740,7 +39698,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
     goto __pyx_L7;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":378
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":380
  *             # one condition is a stronger version of the other.
  *             self.require_aligned_chunks = self.require_aligned_terminal = True
  *         elif require_aligned_terminal:             # <<<<<<<<<<<<<<
@@ -39749,7 +39707,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   if (__pyx_v_require_aligned_terminal) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":379
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":381
  *             self.require_aligned_chunks = self.require_aligned_terminal = True
  *         elif require_aligned_terminal:
  *             self.require_aligned_chunks = False             # <<<<<<<<<<<<<<
@@ -39758,7 +39716,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
     __pyx_v_self->require_aligned_chunks = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":380
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":382
  *         elif require_aligned_terminal:
  *             self.require_aligned_chunks = False
  *             self.require_aligned_terminal = True             # <<<<<<<<<<<<<<
@@ -39770,7 +39728,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":382
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":384
  *             self.require_aligned_terminal = True
  *         else:
  *             self.require_aligned_chunks = self.require_aligned_terminal = False             # <<<<<<<<<<<<<<
@@ -39782,7 +39740,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   }
   __pyx_L7:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":385
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":387
  * 
  *         # diagnostics
  *         self.prev_norm_prefix = ()             # <<<<<<<<<<<<<<
@@ -39795,17 +39753,17 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __Pyx_DECREF(__pyx_v_self->prev_norm_prefix);
   __pyx_v_self->prev_norm_prefix = ((PyObject *)__pyx_empty_tuple);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":387
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":389
  *         self.prev_norm_prefix = ()
  * 
  *         self.findexes = IntList(initial_len=10)             # <<<<<<<<<<<<<<
  *         self.findexes1 = IntList(initial_len=10)
  * 
  */
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 389; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_2));
-  if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__initial_len), __pyx_int_10) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_2)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__initial_len), __pyx_int_10) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 389; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_2)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 389; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
   __Pyx_GIVEREF(__pyx_t_1);
@@ -39814,17 +39772,17 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __pyx_v_self->findexes = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":388
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":390
  * 
  *         self.findexes = IntList(initial_len=10)
  *         self.findexes1 = IntList(initial_len=10)             # <<<<<<<<<<<<<<
  * 
  *         # Online stats
  */
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 388; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 390; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__initial_len), __pyx_int_10) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 388; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 388; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__initial_len), __pyx_int_10) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 390; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 390; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
   __Pyx_GIVEREF(__pyx_t_2);
@@ -39833,188 +39791,212 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __pyx_v_self->findexes1 = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_2);
   __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":393
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":395
  * 
  *         # True after data is added
  *         self.online = False             # <<<<<<<<<<<<<<
  * 
- *         # Phrase counts
+ *         # Keep track of everything that can be sampled:
  */
   __pyx_v_self->online = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":396
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":398
+ * 
+ *         # Keep track of everything that can be sampled:
+ *         self.samples_f = defaultdict(int)             # <<<<<<<<<<<<<<
  * 
  *         # Phrase counts
- *         self.phrases_f = defaultdict(int)             # <<<<<<<<<<<<<<
- *         self.phrases_e = defaultdict(int)
- *         self.phrases_fe = defaultdict(lambda: defaultdict(int))
  */
-  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(((PyObject *)((PyObject*)(&PyInt_Type))));
   PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)((PyObject*)(&PyInt_Type))));
   __Pyx_GIVEREF(((PyObject *)((PyObject*)(&PyInt_Type))));
-  __pyx_t_5 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
   __Pyx_GIVEREF(__pyx_t_5);
-  __Pyx_GOTREF(__pyx_v_self->phrases_f);
-  __Pyx_DECREF(__pyx_v_self->phrases_f);
-  __pyx_v_self->phrases_f = __pyx_t_5;
+  __Pyx_GOTREF(__pyx_v_self->samples_f);
+  __Pyx_DECREF(__pyx_v_self->samples_f);
+  __pyx_v_self->samples_f = __pyx_t_5;
   __pyx_t_5 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":397
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":401
+ * 
  *         # Phrase counts
- *         self.phrases_f = defaultdict(int)
- *         self.phrases_e = defaultdict(int)             # <<<<<<<<<<<<<<
+ *         self.phrases_f = defaultdict(int)             # <<<<<<<<<<<<<<
+ *         self.phrases_e = defaultdict(int)
  *         self.phrases_fe = defaultdict(lambda: defaultdict(int))
- *         self.phrases_al = defaultdict(lambda: defaultdict(tuple))
  */
-  __pyx_t_5 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 401; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 401; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(((PyObject *)((PyObject*)(&PyInt_Type))));
   PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)((PyObject*)(&PyInt_Type))));
   __Pyx_GIVEREF(((PyObject *)((PyObject*)(&PyInt_Type))));
-  __pyx_t_2 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 401; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
   __Pyx_GIVEREF(__pyx_t_2);
+  __Pyx_GOTREF(__pyx_v_self->phrases_f);
+  __Pyx_DECREF(__pyx_v_self->phrases_f);
+  __pyx_v_self->phrases_f = __pyx_t_2;
+  __pyx_t_2 = 0;
+
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":402
+ *         # Phrase counts
+ *         self.phrases_f = defaultdict(int)
+ *         self.phrases_e = defaultdict(int)             # <<<<<<<<<<<<<<
+ *         self.phrases_fe = defaultdict(lambda: defaultdict(int))
+ *         self.phrases_al = defaultdict(lambda: defaultdict(tuple))
+ */
+  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 402; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 402; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_INCREF(((PyObject *)((PyObject*)(&PyInt_Type))));
+  PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)((PyObject*)(&PyInt_Type))));
+  __Pyx_GIVEREF(((PyObject *)((PyObject*)(&PyInt_Type))));
+  __pyx_t_5 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 402; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __Pyx_GIVEREF(__pyx_t_5);
   __Pyx_GOTREF(__pyx_v_self->phrases_e);
   __Pyx_DECREF(__pyx_v_self->phrases_e);
-  __pyx_v_self->phrases_e = __pyx_t_2;
-  __pyx_t_2 = 0;
+  __pyx_v_self->phrases_e = __pyx_t_5;
+  __pyx_t_5 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":398
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":403
  *         self.phrases_f = defaultdict(int)
  *         self.phrases_e = defaultdict(int)
  *         self.phrases_fe = defaultdict(lambda: defaultdict(int))             # <<<<<<<<<<<<<<
  *         self.phrases_al = defaultdict(lambda: defaultdict(tuple))
  * 
  */
-  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_1 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_9__cinit___lambda1, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_5);
-  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1);
+  __pyx_t_1 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_9__cinit___lambda1, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_1);
   __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
   __Pyx_GIVEREF(__pyx_t_1);
   __Pyx_GOTREF(__pyx_v_self->phrases_fe);
   __Pyx_DECREF(__pyx_v_self->phrases_fe);
   __pyx_v_self->phrases_fe = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":399
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":404
  *         self.phrases_e = defaultdict(int)
  *         self.phrases_fe = defaultdict(lambda: defaultdict(int))
  *         self.phrases_al = defaultdict(lambda: defaultdict(tuple))             # <<<<<<<<<<<<<<
  * 
  *         # Bilexical counts
  */
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 399; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_5 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_9__cinit___1lambda2, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 399; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 399; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_9__cinit___1lambda2, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
-  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_5);
-  __Pyx_GIVEREF(__pyx_t_5);
-  __pyx_t_5 = 0;
-  __pyx_t_5 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 399; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
-  __Pyx_GIVEREF(__pyx_t_5);
+  __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
+  __Pyx_GIVEREF(__pyx_t_2);
   __Pyx_GOTREF(__pyx_v_self->phrases_al);
   __Pyx_DECREF(__pyx_v_self->phrases_al);
-  __pyx_v_self->phrases_al = __pyx_t_5;
-  __pyx_t_5 = 0;
+  __pyx_v_self->phrases_al = __pyx_t_2;
+  __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":402
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":407
  * 
  *         # Bilexical counts
  *         self.bilex_f = defaultdict(int)             # <<<<<<<<<<<<<<
  *         self.bilex_e = defaultdict(int)
  *         self.bilex_fe = defaultdict(lambda: defaultdict(int))
  */
-  __pyx_t_5 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 402; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 402; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
   __Pyx_INCREF(((PyObject *)((PyObject*)(&PyInt_Type))));
-  PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)((PyObject*)(&PyInt_Type))));
+  PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)((PyObject*)(&PyInt_Type))));
   __Pyx_GIVEREF(((PyObject *)((PyObject*)(&PyInt_Type))));
-  __pyx_t_1 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 402; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
   __Pyx_GIVEREF(__pyx_t_1);
   __Pyx_GOTREF(__pyx_v_self->bilex_f);
   __Pyx_DECREF(__pyx_v_self->bilex_f);
   __pyx_v_self->bilex_f = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":403
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":408
  *         # Bilexical counts
  *         self.bilex_f = defaultdict(int)
  *         self.bilex_e = defaultdict(int)             # <<<<<<<<<<<<<<
  *         self.bilex_fe = defaultdict(lambda: defaultdict(int))
  * 
  */
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
   __Pyx_INCREF(((PyObject *)((PyObject*)(&PyInt_Type))));
-  PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)((PyObject*)(&PyInt_Type))));
+  PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)((PyObject*)(&PyInt_Type))));
   __Pyx_GIVEREF(((PyObject *)((PyObject*)(&PyInt_Type))));
-  __pyx_t_5 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
-  __Pyx_GIVEREF(__pyx_t_5);
+  __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
+  __Pyx_GIVEREF(__pyx_t_2);
   __Pyx_GOTREF(__pyx_v_self->bilex_e);
   __Pyx_DECREF(__pyx_v_self->bilex_e);
-  __pyx_v_self->bilex_e = __pyx_t_5;
-  __pyx_t_5 = 0;
+  __pyx_v_self->bilex_e = __pyx_t_2;
+  __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":404
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":409
  *         self.bilex_f = defaultdict(int)
  *         self.bilex_e = defaultdict(int)
  *         self.bilex_fe = defaultdict(lambda: defaultdict(int))             # <<<<<<<<<<<<<<
  * 
  *     def configure(self, SuffixArray fsarray, DataArray edarray,
  */
-  __pyx_t_5 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_2 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_9__cinit___2lambda3, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_9__cinit___2lambda3, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
-  __Pyx_GIVEREF(__pyx_t_2);
-  __pyx_t_2 = 0;
-  __pyx_t_2 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  __pyx_t_5 = 0;
+  __pyx_t_5 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-  __Pyx_GIVEREF(__pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_5);
   __Pyx_GOTREF(__pyx_v_self->bilex_fe);
   __Pyx_DECREF(__pyx_v_self->bilex_fe);
-  __pyx_v_self->bilex_fe = __pyx_t_2;
-  __pyx_t_2 = 0;
+  __pyx_v_self->bilex_fe = __pyx_t_5;
+  __pyx_t_5 = 0;
 
   __pyx_r = 0;
   goto __pyx_L0;
@@ -40062,21 +40044,21 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_3configure(PyObject *__
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__edarray)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("configure", 1, 4, 4, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("configure", 1, 4, 4, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__sampler)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("configure", 1, 4, 4, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("configure", 1, 4, 4, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  3:
         if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__scorer)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("configure", 1, 4, 4, 3); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("configure", 1, 4, 4, 3); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "configure") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "configure") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
       goto __pyx_L5_argtuple_error;
@@ -40093,16 +40075,16 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_3configure(PyObject *__
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("configure", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("configure", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.configure", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_fsarray), __pyx_ptype_3_sa_SuffixArray, 1, "fsarray", 0))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_edarray), __pyx_ptype_3_sa_DataArray, 1, "edarray", 0))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_sampler), __pyx_ptype_3_sa_Sampler, 1, "sampler", 0))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_scorer), __pyx_ptype_3_sa_Scorer, 1, "scorer", 0))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_fsarray), __pyx_ptype_3_sa_SuffixArray, 1, "fsarray", 0))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_edarray), __pyx_ptype_3_sa_DataArray, 1, "edarray", 0))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_sampler), __pyx_ptype_3_sa_Sampler, 1, "sampler", 0))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_scorer), __pyx_ptype_3_sa_Scorer, 1, "scorer", 0))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_r = __pyx_pf_3_sa_23HieroCachingRuleFactory_2configure(((struct __pyx_obj_3_sa_HieroCachingRuleFactory *)__pyx_v_self), __pyx_v_fsarray, __pyx_v_edarray, __pyx_v_sampler, __pyx_v_scorer);
   goto __pyx_L0;
   __pyx_L1_error:;
@@ -40112,7 +40094,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_3configure(PyObject *__
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":406
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":411
  *         self.bilex_fe = defaultdict(lambda: defaultdict(int))
  * 
  *     def configure(self, SuffixArray fsarray, DataArray edarray,             # <<<<<<<<<<<<<<
@@ -40130,7 +40112,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_2configure(struct __pyx
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("configure", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":411
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":416
  *         Here we also use it to precompute the most expensive intersections
  *         in the corpus quickly.'''
  *         self.fsa = fsarray             # <<<<<<<<<<<<<<
@@ -40143,7 +40125,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_2configure(struct __pyx
   __Pyx_DECREF(((PyObject *)__pyx_v_self->fsa));
   __pyx_v_self->fsa = __pyx_v_fsarray;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":412
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":417
  *         in the corpus quickly.'''
  *         self.fsa = fsarray
  *         self.fda = fsarray.darray             # <<<<<<<<<<<<<<
@@ -40156,7 +40138,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_2configure(struct __pyx
   __Pyx_DECREF(((PyObject *)__pyx_v_self->fda));
   __pyx_v_self->fda = __pyx_v_fsarray->darray;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":413
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":418
  *         self.fsa = fsarray
  *         self.fda = fsarray.darray
  *         self.eda = edarray             # <<<<<<<<<<<<<<
@@ -40169,7 +40151,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_2configure(struct __pyx
   __Pyx_DECREF(((PyObject *)__pyx_v_self->eda));
   __pyx_v_self->eda = __pyx_v_edarray;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":414
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":419
  *         self.fda = fsarray.darray
  *         self.eda = edarray
  *         self.fid2symid = self.set_idmap(self.fda)             # <<<<<<<<<<<<<<
@@ -40178,17 +40160,17 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_2configure(struct __pyx
  */
   __pyx_t_1 = ((PyObject *)__pyx_v_self->fda);
   __Pyx_INCREF(__pyx_t_1);
-  __pyx_t_2 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->set_idmap(__pyx_v_self, ((struct __pyx_obj_3_sa_DataArray *)__pyx_t_1)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 414; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->set_idmap(__pyx_v_self, ((struct __pyx_obj_3_sa_DataArray *)__pyx_t_1)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_3_sa_IntList))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 414; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_3_sa_IntList))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GIVEREF(__pyx_t_2);
   __Pyx_GOTREF(__pyx_v_self->fid2symid);
   __Pyx_DECREF(((PyObject *)__pyx_v_self->fid2symid));
   __pyx_v_self->fid2symid = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_2);
   __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":415
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":420
  *         self.eda = edarray
  *         self.fid2symid = self.set_idmap(self.fda)
  *         self.eid2symid = self.set_idmap(self.eda)             # <<<<<<<<<<<<<<
@@ -40197,31 +40179,31 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_2configure(struct __pyx
  */
   __pyx_t_2 = ((PyObject *)__pyx_v_self->eda);
   __Pyx_INCREF(__pyx_t_2);
-  __pyx_t_1 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->set_idmap(__pyx_v_self, ((struct __pyx_obj_3_sa_DataArray *)__pyx_t_2)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 415; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->set_idmap(__pyx_v_self, ((struct __pyx_obj_3_sa_DataArray *)__pyx_t_2)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_3_sa_IntList))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 415; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_3_sa_IntList))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GIVEREF(__pyx_t_1);
   __Pyx_GOTREF(__pyx_v_self->eid2symid);
   __Pyx_DECREF(((PyObject *)__pyx_v_self->eid2symid));
   __pyx_v_self->eid2symid = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":416
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":421
  *         self.fid2symid = self.set_idmap(self.fda)
  *         self.eid2symid = self.set_idmap(self.eda)
  *         self.precompute()             # <<<<<<<<<<<<<<
  *         self.sampler = sampler
  *         self.scorer = scorer
  */
-  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__precompute); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 416; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__precompute); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 421; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 416; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 421; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":417
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":422
  *         self.eid2symid = self.set_idmap(self.eda)
  *         self.precompute()
  *         self.sampler = sampler             # <<<<<<<<<<<<<<
@@ -40234,7 +40216,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_2configure(struct __pyx
   __Pyx_DECREF(((PyObject *)__pyx_v_self->sampler));
   __pyx_v_self->sampler = __pyx_v_sampler;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":418
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":423
  *         self.precompute()
  *         self.sampler = sampler
  *         self.scorer = scorer             # <<<<<<<<<<<<<<
@@ -40260,7 +40242,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_2configure(struct __pyx
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":420
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":425
  *         self.scorer = scorer
  * 
  *     cdef set_idmap(self, DataArray darray):             # <<<<<<<<<<<<<<
@@ -40285,7 +40267,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_set_idmap(CYTHON_UNUSED
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("set_idmap", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":424
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":429
  *         cdef IntList idmap
  * 
  *         N = len(darray.id2word)             # <<<<<<<<<<<<<<
@@ -40294,30 +40276,30 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_set_idmap(CYTHON_UNUSED
  */
   __pyx_t_1 = __pyx_v_darray->id2word;
   __Pyx_INCREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_v_N = __pyx_t_2;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":425
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":430
  * 
  *         N = len(darray.id2word)
  *         idmap = IntList(initial_len=N)             # <<<<<<<<<<<<<<
  *         for word_id from 0 <= word_id < N:
  *             new_word_id = sym_fromstring(darray.id2word[word_id], True)
  */
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 430; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  __pyx_t_3 = PyInt_FromLong(__pyx_v_N); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyInt_FromLong(__pyx_v_N); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 430; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__initial_len), __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__initial_len), __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 430; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 430; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
   __pyx_v_idmap = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_3);
   __pyx_t_3 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":426
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":431
  *         N = len(darray.id2word)
  *         idmap = IntList(initial_len=N)
  *         for word_id from 0 <= word_id < N:             # <<<<<<<<<<<<<<
@@ -40327,20 +40309,20 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_set_idmap(CYTHON_UNUSED
   __pyx_t_4 = __pyx_v_N;
   for (__pyx_v_word_id = 0; __pyx_v_word_id < __pyx_t_4; __pyx_v_word_id++) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":427
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":432
  *         idmap = IntList(initial_len=N)
  *         for word_id from 0 <= word_id < N:
  *             new_word_id = sym_fromstring(darray.id2word[word_id], True)             # <<<<<<<<<<<<<<
  *             idmap.arr[word_id] = new_word_id
  *         return idmap
  */
-    __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_darray->id2word, __pyx_v_word_id, sizeof(int), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 427; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_darray->id2word, __pyx_v_word_id, sizeof(int), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 432; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_5 = PyBytes_AsString(__pyx_t_3); if (unlikely((!__pyx_t_5) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 427; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyBytes_AsString(__pyx_t_3); if (unlikely((!__pyx_t_5) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 432; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __pyx_v_new_word_id = __pyx_f_3_sa_sym_fromstring(__pyx_t_5, 1);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":428
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":433
  *         for word_id from 0 <= word_id < N:
  *             new_word_id = sym_fromstring(darray.id2word[word_id], True)
  *             idmap.arr[word_id] = new_word_id             # <<<<<<<<<<<<<<
@@ -40350,7 +40332,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_set_idmap(CYTHON_UNUSED
     (__pyx_v_idmap->arr[__pyx_v_word_id]) = __pyx_v_new_word_id;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":429
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":434
  *             new_word_id = sym_fromstring(darray.id2word[word_id], True)
  *             idmap.arr[word_id] = new_word_id
  *         return idmap             # <<<<<<<<<<<<<<
@@ -40387,7 +40369,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_5pattern2phrase(PyObjec
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":432
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":437
  * 
  * 
  *     def pattern2phrase(self, pattern):             # <<<<<<<<<<<<<<
@@ -40415,7 +40397,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_4pattern2phrase(struct
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("pattern2phrase", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":434
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":439
  *     def pattern2phrase(self, pattern):
  *         # pattern is a tuple, which we must convert to a hiero Phrase
  *         result = ()             # <<<<<<<<<<<<<<
@@ -40425,7 +40407,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_4pattern2phrase(struct
   __Pyx_INCREF(((PyObject *)__pyx_empty_tuple));
   __pyx_v_result = __pyx_empty_tuple;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":435
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":440
  *         # pattern is a tuple, which we must convert to a hiero Phrase
  *         result = ()
  *         arity = 0             # <<<<<<<<<<<<<<
@@ -40435,7 +40417,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_4pattern2phrase(struct
   __Pyx_INCREF(__pyx_int_0);
   __pyx_v_arity = __pyx_int_0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":436
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":441
  *         result = ()
  *         arity = 0
  *         for word_id in pattern:             # <<<<<<<<<<<<<<
@@ -40446,7 +40428,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_4pattern2phrase(struct
     __pyx_t_1 = __pyx_v_pattern; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
     __pyx_t_3 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_pattern); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 436; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_pattern); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -40454,23 +40436,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_4pattern2phrase(struct
     if (!__pyx_t_3 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 436; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 436; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_3 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 436; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 436; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_4 = __pyx_t_3(__pyx_t_1);
       if (unlikely(!__pyx_t_4)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 436; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -40480,74 +40462,74 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_4pattern2phrase(struct
     __pyx_v_word_id = __pyx_t_4;
     __pyx_t_4 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":437
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":442
  *         arity = 0
  *         for word_id in pattern:
  *             if word_id == -1:             # <<<<<<<<<<<<<<
  *                 arity = arity + 1
  *                 new_id = sym_setindex(self.category, arity)
  */
-    __pyx_t_4 = PyObject_RichCompare(__pyx_v_word_id, __pyx_int_neg_1, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 437; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 437; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_RichCompare(__pyx_v_word_id, __pyx_int_neg_1, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 442; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 442; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     if (__pyx_t_5) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":438
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":443
  *         for word_id in pattern:
  *             if word_id == -1:
  *                 arity = arity + 1             # <<<<<<<<<<<<<<
  *                 new_id = sym_setindex(self.category, arity)
  *             else:
  */
-      __pyx_t_4 = PyNumber_Add(__pyx_v_arity, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 438; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyNumber_Add(__pyx_v_arity, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_v_arity);
       __pyx_v_arity = __pyx_t_4;
       __pyx_t_4 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":439
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":444
  *             if word_id == -1:
  *                 arity = arity + 1
  *                 new_id = sym_setindex(self.category, arity)             # <<<<<<<<<<<<<<
  *             else:
  *                 new_id = sym_fromstring(self.fda.id2word[word_id], True)
  */
-      __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_arity); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 439; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_arity); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_v_new_id = __pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_t_6);
       goto __pyx_L5;
     }
     /*else*/ {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":441
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":446
  *                 new_id = sym_setindex(self.category, arity)
  *             else:
  *                 new_id = sym_fromstring(self.fda.id2word[word_id], True)             # <<<<<<<<<<<<<<
  *             result = result + (new_id,)
  *         return Phrase(result)
  */
-      __pyx_t_4 = PyObject_GetItem(__pyx_v_self->fda->id2word, __pyx_v_word_id); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_GetItem(__pyx_v_self->fda->id2word, __pyx_v_word_id); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_7 = PyBytes_AsString(__pyx_t_4); if (unlikely((!__pyx_t_7) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyBytes_AsString(__pyx_t_4); if (unlikely((!__pyx_t_7) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __pyx_v_new_id = __pyx_f_3_sa_sym_fromstring(__pyx_t_7, 1);
     }
     __pyx_L5:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":442
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":447
  *             else:
  *                 new_id = sym_fromstring(self.fda.id2word[word_id], True)
  *             result = result + (new_id,)             # <<<<<<<<<<<<<<
  *         return Phrase(result)
  * 
  */
-    __pyx_t_4 = PyInt_FromLong(__pyx_v_new_id); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 442; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyInt_FromLong(__pyx_v_new_id); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 442; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
     PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_4);
     __Pyx_GIVEREF(__pyx_t_4);
     __pyx_t_4 = 0;
-    __pyx_t_4 = PyNumber_Add(((PyObject *)__pyx_v_result), ((PyObject *)__pyx_t_8)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 442; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyNumber_Add(((PyObject *)__pyx_v_result), ((PyObject *)__pyx_t_8)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(((PyObject *)__pyx_t_4));
     __Pyx_DECREF(((PyObject *)__pyx_t_8)); __pyx_t_8 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_v_result));
@@ -40556,7 +40538,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_4pattern2phrase(struct
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":443
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":448
  *                 new_id = sym_fromstring(self.fda.id2word[word_id], True)
  *             result = result + (new_id,)
  *         return Phrase(result)             # <<<<<<<<<<<<<<
@@ -40564,12 +40546,12 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_4pattern2phrase(struct
  *     def pattern2phrase_plus(self, pattern):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 448; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(((PyObject *)__pyx_v_result));
   PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_v_result));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_result));
-  __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 448; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_4;
@@ -40604,7 +40586,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_7pattern2phrase_plus(Py
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":445
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":450
  *         return Phrase(result)
  * 
  *     def pattern2phrase_plus(self, pattern):             # <<<<<<<<<<<<<<
@@ -40634,19 +40616,19 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_6pattern2phrase_plus(st
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("pattern2phrase_plus", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":448
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":453
  *         # returns a list containing both the pattern, and pattern
  *         # suffixed/prefixed with the NT category.
  *         patterns = []             # <<<<<<<<<<<<<<
  *         result = ()
  *         arity = 0
  */
-  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 448; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 453; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_patterns = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":449
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":454
  *         # suffixed/prefixed with the NT category.
  *         patterns = []
  *         result = ()             # <<<<<<<<<<<<<<
@@ -40656,7 +40638,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_6pattern2phrase_plus(st
   __Pyx_INCREF(((PyObject *)__pyx_empty_tuple));
   __pyx_v_result = __pyx_empty_tuple;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":450
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":455
  *         patterns = []
  *         result = ()
  *         arity = 0             # <<<<<<<<<<<<<<
@@ -40666,7 +40648,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_6pattern2phrase_plus(st
   __Pyx_INCREF(__pyx_int_0);
   __pyx_v_arity = __pyx_int_0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":451
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":456
  *         result = ()
  *         arity = 0
  *         for word_id in pattern:             # <<<<<<<<<<<<<<
@@ -40677,7 +40659,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_6pattern2phrase_plus(st
     __pyx_t_1 = __pyx_v_pattern; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
     __pyx_t_3 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_pattern); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 451; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_pattern); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -40685,23 +40667,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_6pattern2phrase_plus(st
     if (!__pyx_t_3 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 451; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 451; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_3 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 451; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 451; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_4 = __pyx_t_3(__pyx_t_1);
       if (unlikely(!__pyx_t_4)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 451; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -40711,74 +40693,74 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_6pattern2phrase_plus(st
     __pyx_v_word_id = __pyx_t_4;
     __pyx_t_4 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":452
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":457
  *         arity = 0
  *         for word_id in pattern:
  *             if word_id == -1:             # <<<<<<<<<<<<<<
  *                 arity = arity + 1
  *                 new_id = sym_setindex(self.category, arity)
  */
-    __pyx_t_4 = PyObject_RichCompare(__pyx_v_word_id, __pyx_int_neg_1, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 452; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 452; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_RichCompare(__pyx_v_word_id, __pyx_int_neg_1, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     if (__pyx_t_5) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":453
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":458
  *         for word_id in pattern:
  *             if word_id == -1:
  *                 arity = arity + 1             # <<<<<<<<<<<<<<
  *                 new_id = sym_setindex(self.category, arity)
  *             else:
  */
-      __pyx_t_4 = PyNumber_Add(__pyx_v_arity, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 453; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyNumber_Add(__pyx_v_arity, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 458; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_v_arity);
       __pyx_v_arity = __pyx_t_4;
       __pyx_t_4 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":454
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":459
  *             if word_id == -1:
  *                 arity = arity + 1
  *                 new_id = sym_setindex(self.category, arity)             # <<<<<<<<<<<<<<
  *             else:
  *                 new_id = sym_fromstring(self.fda.id2word[word_id], True)
  */
-      __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_arity); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 454; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_arity); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_v_new_id = __pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_t_6);
       goto __pyx_L5;
     }
     /*else*/ {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":456
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":461
  *                 new_id = sym_setindex(self.category, arity)
  *             else:
  *                 new_id = sym_fromstring(self.fda.id2word[word_id], True)             # <<<<<<<<<<<<<<
  *             result = result + (new_id,)
  *         patterns.append(Phrase(result))
  */
-      __pyx_t_4 = PyObject_GetItem(__pyx_v_self->fda->id2word, __pyx_v_word_id); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_GetItem(__pyx_v_self->fda->id2word, __pyx_v_word_id); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 461; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_7 = PyBytes_AsString(__pyx_t_4); if (unlikely((!__pyx_t_7) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyBytes_AsString(__pyx_t_4); if (unlikely((!__pyx_t_7) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 461; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __pyx_v_new_id = __pyx_f_3_sa_sym_fromstring(__pyx_t_7, 1);
     }
     __pyx_L5:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":457
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":462
  *             else:
  *                 new_id = sym_fromstring(self.fda.id2word[word_id], True)
  *             result = result + (new_id,)             # <<<<<<<<<<<<<<
  *         patterns.append(Phrase(result))
  *         patterns.append(Phrase(result + (sym_setindex(self.category, 1),)))
  */
-    __pyx_t_4 = PyInt_FromLong(__pyx_v_new_id); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyInt_FromLong(__pyx_v_new_id); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
     PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_4);
     __Pyx_GIVEREF(__pyx_t_4);
     __pyx_t_4 = 0;
-    __pyx_t_4 = PyNumber_Add(((PyObject *)__pyx_v_result), ((PyObject *)__pyx_t_8)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyNumber_Add(((PyObject *)__pyx_v_result), ((PyObject *)__pyx_t_8)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(((PyObject *)__pyx_t_4));
     __Pyx_DECREF(((PyObject *)__pyx_t_8)); __pyx_t_8 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_v_result));
@@ -40787,81 +40769,81 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_6pattern2phrase_plus(st
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":458
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":463
  *                 new_id = sym_fromstring(self.fda.id2word[word_id], True)
  *             result = result + (new_id,)
  *         patterns.append(Phrase(result))             # <<<<<<<<<<<<<<
  *         patterns.append(Phrase(result + (sym_setindex(self.category, 1),)))
  *         patterns.append(Phrase((sym_setindex(self.category, 1),) + result))
  */
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 458; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(((PyObject *)__pyx_v_result));
   PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_v_result));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_result));
-  __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 458; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-  __pyx_t_9 = PyList_Append(__pyx_v_patterns, __pyx_t_4); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 458; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_9 = PyList_Append(__pyx_v_patterns, __pyx_t_4); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":459
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":464
  *             result = result + (new_id,)
  *         patterns.append(Phrase(result))
  *         patterns.append(Phrase(result + (sym_setindex(self.category, 1),)))             # <<<<<<<<<<<<<<
  *         patterns.append(Phrase((sym_setindex(self.category, 1),) + result))
  *         return patterns
  */
-  __pyx_t_4 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, 1)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, 1)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_4);
   __Pyx_GIVEREF(__pyx_t_4);
   __pyx_t_4 = 0;
-  __pyx_t_4 = PyNumber_Add(((PyObject *)__pyx_v_result), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyNumber_Add(((PyObject *)__pyx_v_result), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_4));
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_t_4));
   __Pyx_GIVEREF(((PyObject *)__pyx_t_4));
   __pyx_t_4 = 0;
-  __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-  __pyx_t_9 = PyList_Append(__pyx_v_patterns, __pyx_t_4); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_9 = PyList_Append(__pyx_v_patterns, __pyx_t_4); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":460
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":465
  *         patterns.append(Phrase(result))
  *         patterns.append(Phrase(result + (sym_setindex(self.category, 1),)))
  *         patterns.append(Phrase((sym_setindex(self.category, 1),) + result))             # <<<<<<<<<<<<<<
  *         return patterns
  * 
  */
-  __pyx_t_4 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, 1)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, 1)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_4);
   __Pyx_GIVEREF(__pyx_t_4);
   __pyx_t_4 = 0;
-  __pyx_t_4 = PyNumber_Add(((PyObject *)__pyx_t_1), ((PyObject *)__pyx_v_result)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyNumber_Add(((PyObject *)__pyx_t_1), ((PyObject *)__pyx_v_result)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_4));
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_t_4));
   __Pyx_GIVEREF(((PyObject *)__pyx_t_4));
   __pyx_t_4 = 0;
-  __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-  __pyx_t_9 = PyList_Append(__pyx_v_patterns, __pyx_t_4); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_9 = PyList_Append(__pyx_v_patterns, __pyx_t_4); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":461
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":466
  *         patterns.append(Phrase(result + (sym_setindex(self.category, 1),)))
  *         patterns.append(Phrase((sym_setindex(self.category, 1),) + result))
  *         return patterns             # <<<<<<<<<<<<<<
@@ -40902,7 +40884,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_9precompute(PyObject *_
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":463
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":468
  *         return patterns
  * 
  *     def precompute(self):             # <<<<<<<<<<<<<<
@@ -40936,7 +40918,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("precompute", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":466
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":471
  *         cdef Precomputation pre
  * 
  *         if self.precompute_file is not None:             # <<<<<<<<<<<<<<
@@ -40946,31 +40928,31 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
   __pyx_t_1 = (__pyx_v_self->precompute_file != Py_None);
   if (__pyx_t_1) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":467
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":472
  * 
  *         if self.precompute_file is not None:
  *             start_time = monitor_cpu()             # <<<<<<<<<<<<<<
  *             logger.info("Reading precomputed data from file %s... ", self.precompute_file)
  *             pre = Precomputation(from_binary=self.precompute_file)
  */
-    __pyx_t_2 = PyFloat_FromDouble(__pyx_f_3_sa_monitor_cpu()); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyFloat_FromDouble(__pyx_f_3_sa_monitor_cpu()); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 472; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_v_start_time = __pyx_t_2;
     __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":468
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":473
  *         if self.precompute_file is not None:
  *             start_time = monitor_cpu()
  *             logger.info("Reading precomputed data from file %s... ", self.precompute_file)             # <<<<<<<<<<<<<<
  *             pre = Precomputation(from_binary=self.precompute_file)
  *             # check parameters of precomputation -- some are critical and some are not
  */
-    __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 473; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_3 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__info); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__info); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 473; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 473; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_INCREF(((PyObject *)__pyx_kp_s_108));
     PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_kp_s_108));
@@ -40978,29 +40960,29 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
     __Pyx_INCREF(__pyx_v_self->precompute_file);
     PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_self->precompute_file);
     __Pyx_GIVEREF(__pyx_v_self->precompute_file);
-    __pyx_t_4 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 473; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":469
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":474
  *             start_time = monitor_cpu()
  *             logger.info("Reading precomputed data from file %s... ", self.precompute_file)
  *             pre = Precomputation(from_binary=self.precompute_file)             # <<<<<<<<<<<<<<
  *             # check parameters of precomputation -- some are critical and some are not
  *             if pre.max_nonterminals != self.max_nonterminals:
  */
-    __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(((PyObject *)__pyx_t_4));
-    if (PyDict_SetItem(__pyx_t_4, ((PyObject *)__pyx_n_s__from_binary), __pyx_v_self->precompute_file) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Precomputation)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_4)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyDict_SetItem(__pyx_t_4, ((PyObject *)__pyx_n_s__from_binary), __pyx_v_self->precompute_file) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Precomputation)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_4)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
     __pyx_v_pre = ((struct __pyx_obj_3_sa_Precomputation *)__pyx_t_2);
     __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":471
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":476
  *             pre = Precomputation(from_binary=self.precompute_file)
  *             # check parameters of precomputation -- some are critical and some are not
  *             if pre.max_nonterminals != self.max_nonterminals:             # <<<<<<<<<<<<<<
@@ -41010,23 +40992,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
     __pyx_t_1 = (__pyx_v_pre->max_nonterminals != __pyx_v_self->max_nonterminals);
     if (__pyx_t_1) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":472
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":477
  *             # check parameters of precomputation -- some are critical and some are not
  *             if pre.max_nonterminals != self.max_nonterminals:
  *                 logger.warn("Precomputation done with max nonterminals %d, decoder uses %d", pre.max_nonterminals, self.max_nonterminals)             # <<<<<<<<<<<<<<
  *             if pre.max_length != self.max_length:
  *                 logger.warn("Precomputation done with max terminals %d, decoder uses %d", pre.max_length, self.max_length)
  */
-      __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 472; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_4 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__warn); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 472; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__warn); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_2 = PyInt_FromLong(__pyx_v_pre->max_nonterminals); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 472; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyInt_FromLong(__pyx_v_pre->max_nonterminals); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_3 = PyInt_FromLong(__pyx_v_self->max_nonterminals); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 472; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyInt_FromLong(__pyx_v_self->max_nonterminals); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 472; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_INCREF(((PyObject *)__pyx_kp_s_109));
       PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)__pyx_kp_s_109));
@@ -41037,7 +41019,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
       __Pyx_GIVEREF(__pyx_t_3);
       __pyx_t_2 = 0;
       __pyx_t_3 = 0;
-      __pyx_t_3 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 472; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
@@ -41046,7 +41028,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
     }
     __pyx_L4:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":473
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":478
  *             if pre.max_nonterminals != self.max_nonterminals:
  *                 logger.warn("Precomputation done with max nonterminals %d, decoder uses %d", pre.max_nonterminals, self.max_nonterminals)
  *             if pre.max_length != self.max_length:             # <<<<<<<<<<<<<<
@@ -41056,23 +41038,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
     __pyx_t_1 = (__pyx_v_pre->max_length != __pyx_v_self->max_length);
     if (__pyx_t_1) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":474
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":479
  *                 logger.warn("Precomputation done with max nonterminals %d, decoder uses %d", pre.max_nonterminals, self.max_nonterminals)
  *             if pre.max_length != self.max_length:
  *                 logger.warn("Precomputation done with max terminals %d, decoder uses %d", pre.max_length, self.max_length)             # <<<<<<<<<<<<<<
  *             if pre.train_max_initial_size != self.train_max_initial_size:
  *                 raise Exception("Precomputation done with max initial size %d, decoder uses %d" % (pre.train_max_initial_size, self.train_max_initial_size))
  */
-      __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 479; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_5 = PyObject_GetAttr(__pyx_t_3, __pyx_n_s__warn); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyObject_GetAttr(__pyx_t_3, __pyx_n_s__warn); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 479; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_3 = PyInt_FromLong(__pyx_v_pre->max_length); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyInt_FromLong(__pyx_v_pre->max_length); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 479; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_4 = PyInt_FromLong(__pyx_v_self->max_length); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyInt_FromLong(__pyx_v_self->max_length); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 479; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 479; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_INCREF(((PyObject *)__pyx_kp_s_110));
       PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_kp_s_110));
@@ -41083,7 +41065,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
       __Pyx_GIVEREF(__pyx_t_4);
       __pyx_t_3 = 0;
       __pyx_t_4 = 0;
-      __pyx_t_4 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 479; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
@@ -41092,7 +41074,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
     }
     __pyx_L5:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":475
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":480
  *             if pre.max_length != self.max_length:
  *                 logger.warn("Precomputation done with max terminals %d, decoder uses %d", pre.max_length, self.max_length)
  *             if pre.train_max_initial_size != self.train_max_initial_size:             # <<<<<<<<<<<<<<
@@ -41102,18 +41084,18 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
     __pyx_t_1 = (__pyx_v_pre->train_max_initial_size != __pyx_v_self->train_max_initial_size);
     if (__pyx_t_1) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":476
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":481
  *                 logger.warn("Precomputation done with max terminals %d, decoder uses %d", pre.max_length, self.max_length)
  *             if pre.train_max_initial_size != self.train_max_initial_size:
  *                 raise Exception("Precomputation done with max initial size %d, decoder uses %d" % (pre.train_max_initial_size, self.train_max_initial_size))             # <<<<<<<<<<<<<<
  *             if pre.train_min_gap_size != self.train_min_gap_size:
  *                 raise Exception("Precomputation done with min gap size %d, decoder uses %d" % (pre.train_min_gap_size, self.train_min_gap_size))
  */
-      __pyx_t_4 = PyInt_FromLong(__pyx_v_pre->train_max_initial_size); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 476; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyInt_FromLong(__pyx_v_pre->train_max_initial_size); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_2 = PyInt_FromLong(__pyx_v_self->train_max_initial_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 476; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyInt_FromLong(__pyx_v_self->train_max_initial_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 476; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
       PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4);
       __Pyx_GIVEREF(__pyx_t_4);
@@ -41121,25 +41103,25 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
       __Pyx_GIVEREF(__pyx_t_2);
       __pyx_t_4 = 0;
       __pyx_t_2 = 0;
-      __pyx_t_2 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_111), ((PyObject *)__pyx_t_5)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 476; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_111), ((PyObject *)__pyx_t_5)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(((PyObject *)__pyx_t_2));
       __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
-      __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 476; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
       PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)__pyx_t_2));
       __Pyx_GIVEREF(((PyObject *)__pyx_t_2));
       __pyx_t_2 = 0;
-      __pyx_t_2 = PyObject_Call(__pyx_builtin_Exception, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 476; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_Call(__pyx_builtin_Exception, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
       __Pyx_Raise(__pyx_t_2, 0, 0, 0);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 476; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       goto __pyx_L6;
     }
     __pyx_L6:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":477
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":482
  *             if pre.train_max_initial_size != self.train_max_initial_size:
  *                 raise Exception("Precomputation done with max initial size %d, decoder uses %d" % (pre.train_max_initial_size, self.train_max_initial_size))
  *             if pre.train_min_gap_size != self.train_min_gap_size:             # <<<<<<<<<<<<<<
@@ -41149,18 +41131,18 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
     __pyx_t_1 = (__pyx_v_pre->train_min_gap_size != __pyx_v_self->train_min_gap_size);
     if (__pyx_t_1) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":478
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":483
  *                 raise Exception("Precomputation done with max initial size %d, decoder uses %d" % (pre.train_max_initial_size, self.train_max_initial_size))
  *             if pre.train_min_gap_size != self.train_min_gap_size:
  *                 raise Exception("Precomputation done with min gap size %d, decoder uses %d" % (pre.train_min_gap_size, self.train_min_gap_size))             # <<<<<<<<<<<<<<
  *             if self.use_index:
  *                 logger.info("Converting %d hash keys on precomputed inverted index... ", len(pre.precomputed_index))
  */
-      __pyx_t_2 = PyInt_FromLong(__pyx_v_pre->train_min_gap_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyInt_FromLong(__pyx_v_pre->train_min_gap_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 483; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_5 = PyInt_FromLong(__pyx_v_self->train_min_gap_size); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyInt_FromLong(__pyx_v_self->train_min_gap_size); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 483; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 483; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
       __Pyx_GIVEREF(__pyx_t_2);
@@ -41168,25 +41150,25 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
       __Pyx_GIVEREF(__pyx_t_5);
       __pyx_t_2 = 0;
       __pyx_t_5 = 0;
-      __pyx_t_5 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_112), ((PyObject *)__pyx_t_4)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_112), ((PyObject *)__pyx_t_4)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 483; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(((PyObject *)__pyx_t_5));
       __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
-      __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 483; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_t_5));
       __Pyx_GIVEREF(((PyObject *)__pyx_t_5));
       __pyx_t_5 = 0;
-      __pyx_t_5 = PyObject_Call(__pyx_builtin_Exception, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyObject_Call(__pyx_builtin_Exception, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 483; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
       __Pyx_Raise(__pyx_t_5, 0, 0, 0);
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 483; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       goto __pyx_L7;
     }
     __pyx_L7:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":479
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":484
  *             if pre.train_min_gap_size != self.train_min_gap_size:
  *                 raise Exception("Precomputation done with min gap size %d, decoder uses %d" % (pre.train_min_gap_size, self.train_min_gap_size))
  *             if self.use_index:             # <<<<<<<<<<<<<<
@@ -41195,25 +41177,25 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
  */
     if (__pyx_v_self->use_index) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":480
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":485
  *                 raise Exception("Precomputation done with min gap size %d, decoder uses %d" % (pre.train_min_gap_size, self.train_min_gap_size))
  *             if self.use_index:
  *                 logger.info("Converting %d hash keys on precomputed inverted index... ", len(pre.precomputed_index))             # <<<<<<<<<<<<<<
  *                 for pattern, arr in pre.precomputed_index.iteritems():
  *                     phrases = self.pattern2phrase_plus(pattern)
  */
-      __pyx_t_5 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_4 = PyObject_GetAttr(__pyx_t_5, __pyx_n_s__info); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_GetAttr(__pyx_t_5, __pyx_n_s__info); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       __pyx_t_5 = __pyx_v_pre->precomputed_index;
       __Pyx_INCREF(__pyx_t_5);
-      __pyx_t_6 = PyObject_Length(__pyx_t_5); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PyObject_Length(__pyx_t_5); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      __pyx_t_5 = PyInt_FromSsize_t(__pyx_t_6); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyInt_FromSsize_t(__pyx_t_6); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_INCREF(((PyObject *)__pyx_kp_s_113));
       PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_kp_s_113));
@@ -41221,13 +41203,13 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
       PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_5);
       __Pyx_GIVEREF(__pyx_t_5);
       __pyx_t_5 = 0;
-      __pyx_t_5 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":481
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":486
  *             if self.use_index:
  *                 logger.info("Converting %d hash keys on precomputed inverted index... ", len(pre.precomputed_index))
  *                 for pattern, arr in pre.precomputed_index.iteritems():             # <<<<<<<<<<<<<<
@@ -41237,9 +41219,9 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
       __pyx_t_6 = 0;
       if (unlikely(__pyx_v_pre->precomputed_index == Py_None)) {
         PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "iteritems");
-        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 486; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       }
-      __pyx_t_2 = __Pyx_dict_iterator(__pyx_v_pre->precomputed_index, 0, ((PyObject *)__pyx_n_s__iteritems), (&__pyx_t_7), (&__pyx_t_8)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_dict_iterator(__pyx_v_pre->precomputed_index, 0, ((PyObject *)__pyx_n_s__iteritems), (&__pyx_t_7), (&__pyx_t_8)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 486; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_XDECREF(__pyx_t_5);
       __pyx_t_5 = __pyx_t_2;
@@ -41247,7 +41229,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
       while (1) {
         __pyx_t_9 = __Pyx_dict_iter_next(__pyx_t_5, __pyx_t_7, &__pyx_t_6, &__pyx_t_2, &__pyx_t_4, NULL, __pyx_t_8);
         if (unlikely(__pyx_t_9 == 0)) break;
-        if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 486; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_XDECREF(__pyx_v_pattern);
@@ -41257,21 +41239,21 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
         __pyx_v_arr = __pyx_t_4;
         __pyx_t_4 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":482
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":487
  *                 logger.info("Converting %d hash keys on precomputed inverted index... ", len(pre.precomputed_index))
  *                 for pattern, arr in pre.precomputed_index.iteritems():
  *                     phrases = self.pattern2phrase_plus(pattern)             # <<<<<<<<<<<<<<
  *                     for phrase in phrases:
  *                         self.precomputed_index[phrase] = arr
  */
-        __pyx_t_4 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__pattern2phrase_plus); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 482; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__pattern2phrase_plus); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_4);
-        __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 482; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_INCREF(__pyx_v_pattern);
         PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_pattern);
         __Pyx_GIVEREF(__pyx_v_pattern);
-        __pyx_t_3 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 482; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
         __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
@@ -41279,7 +41261,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
         __pyx_v_phrases = __pyx_t_3;
         __pyx_t_3 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":483
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":488
  *                 for pattern, arr in pre.precomputed_index.iteritems():
  *                     phrases = self.pattern2phrase_plus(pattern)
  *                     for phrase in phrases:             # <<<<<<<<<<<<<<
@@ -41290,7 +41272,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
           __pyx_t_3 = __pyx_v_phrases; __Pyx_INCREF(__pyx_t_3); __pyx_t_10 = 0;
           __pyx_t_11 = NULL;
         } else {
-          __pyx_t_10 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_phrases); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 483; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_10 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_phrases); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 488; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_3);
           __pyx_t_11 = Py_TYPE(__pyx_t_3)->tp_iternext;
         }
@@ -41298,23 +41280,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
           if (!__pyx_t_11 && PyList_CheckExact(__pyx_t_3)) {
             if (__pyx_t_10 >= PyList_GET_SIZE(__pyx_t_3)) break;
             #if CYTHON_COMPILING_IN_CPYTHON
-            __pyx_t_2 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_10); __Pyx_INCREF(__pyx_t_2); __pyx_t_10++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 483; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_2 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_10); __Pyx_INCREF(__pyx_t_2); __pyx_t_10++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 488; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             #else
-            __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_10); __pyx_t_10++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 483; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_10); __pyx_t_10++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 488; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             #endif
           } else if (!__pyx_t_11 && PyTuple_CheckExact(__pyx_t_3)) {
             if (__pyx_t_10 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
             #if CYTHON_COMPILING_IN_CPYTHON
-            __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_10); __Pyx_INCREF(__pyx_t_2); __pyx_t_10++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 483; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_10); __Pyx_INCREF(__pyx_t_2); __pyx_t_10++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 488; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             #else
-            __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_10); __pyx_t_10++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 483; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_10); __pyx_t_10++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 488; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             #endif
           } else {
             __pyx_t_2 = __pyx_t_11(__pyx_t_3);
             if (unlikely(!__pyx_t_2)) {
               if (PyErr_Occurred()) {
                 if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-                else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 483; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 488; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               }
               break;
             }
@@ -41324,14 +41306,14 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
           __pyx_v_phrase = __pyx_t_2;
           __pyx_t_2 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":484
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":489
  *                     phrases = self.pattern2phrase_plus(pattern)
  *                     for phrase in phrases:
  *                         self.precomputed_index[phrase] = arr             # <<<<<<<<<<<<<<
  *             if self.use_collocations:
  *                 logger.info("Converting %d hash keys on precomputed collocations... ", len(pre.precomputed_collocations))
  */
-          if (PyObject_SetItem(__pyx_v_self->precomputed_index, __pyx_v_phrase, __pyx_v_arr) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 484; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          if (PyObject_SetItem(__pyx_v_self->precomputed_index, __pyx_v_phrase, __pyx_v_arr) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 489; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
       }
@@ -41340,7 +41322,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
     }
     __pyx_L8:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":485
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":490
  *                     for phrase in phrases:
  *                         self.precomputed_index[phrase] = arr
  *             if self.use_collocations:             # <<<<<<<<<<<<<<
@@ -41349,25 +41331,25 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
  */
     if (__pyx_v_self->use_collocations) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":486
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":491
  *                         self.precomputed_index[phrase] = arr
  *             if self.use_collocations:
  *                 logger.info("Converting %d hash keys on precomputed collocations... ", len(pre.precomputed_collocations))             # <<<<<<<<<<<<<<
  *                 for pattern, arr in pre.precomputed_collocations.iteritems():
  *                     phrase = self.pattern2phrase(pattern)
  */
-      __pyx_t_5 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 486; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 491; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_3 = PyObject_GetAttr(__pyx_t_5, __pyx_n_s__info); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 486; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyObject_GetAttr(__pyx_t_5, __pyx_n_s__info); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 491; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       __pyx_t_5 = __pyx_v_pre->precomputed_collocations;
       __Pyx_INCREF(__pyx_t_5);
-      __pyx_t_7 = PyObject_Length(__pyx_t_5); if (unlikely(__pyx_t_7 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 486; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyObject_Length(__pyx_t_5); if (unlikely(__pyx_t_7 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 491; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      __pyx_t_5 = PyInt_FromSsize_t(__pyx_t_7); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 486; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyInt_FromSsize_t(__pyx_t_7); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 491; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 486; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 491; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_INCREF(((PyObject *)__pyx_kp_s_114));
       PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_kp_s_114));
@@ -41375,13 +41357,13 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
       PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_5);
       __Pyx_GIVEREF(__pyx_t_5);
       __pyx_t_5 = 0;
-      __pyx_t_5 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 486; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 491; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":487
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":492
  *             if self.use_collocations:
  *                 logger.info("Converting %d hash keys on precomputed collocations... ", len(pre.precomputed_collocations))
  *                 for pattern, arr in pre.precomputed_collocations.iteritems():             # <<<<<<<<<<<<<<
@@ -41391,9 +41373,9 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
       __pyx_t_7 = 0;
       if (unlikely(__pyx_v_pre->precomputed_collocations == Py_None)) {
         PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "iteritems");
-        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 492; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       }
-      __pyx_t_2 = __Pyx_dict_iterator(__pyx_v_pre->precomputed_collocations, 0, ((PyObject *)__pyx_n_s__iteritems), (&__pyx_t_6), (&__pyx_t_8)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_dict_iterator(__pyx_v_pre->precomputed_collocations, 0, ((PyObject *)__pyx_n_s__iteritems), (&__pyx_t_6), (&__pyx_t_8)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 492; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_XDECREF(__pyx_t_5);
       __pyx_t_5 = __pyx_t_2;
@@ -41401,7 +41383,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
       while (1) {
         __pyx_t_9 = __Pyx_dict_iter_next(__pyx_t_5, __pyx_t_6, &__pyx_t_7, &__pyx_t_2, &__pyx_t_3, NULL, __pyx_t_8);
         if (unlikely(__pyx_t_9 == 0)) break;
-        if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 492; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_XDECREF(__pyx_v_pattern);
@@ -41411,21 +41393,21 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
         __pyx_v_arr = __pyx_t_3;
         __pyx_t_3 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":488
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":493
  *                 logger.info("Converting %d hash keys on precomputed collocations... ", len(pre.precomputed_collocations))
  *                 for pattern, arr in pre.precomputed_collocations.iteritems():
  *                     phrase = self.pattern2phrase(pattern)             # <<<<<<<<<<<<<<
  *                     self.precomputed_collocations[phrase] = arr
  *             stop_time = monitor_cpu()
  */
-        __pyx_t_3 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__pattern2phrase); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 488; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__pattern2phrase); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 493; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_3);
-        __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 488; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 493; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_INCREF(__pyx_v_pattern);
         PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_pattern);
         __Pyx_GIVEREF(__pyx_v_pattern);
-        __pyx_t_4 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 488; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 493; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
@@ -41433,47 +41415,47 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
         __pyx_v_phrase = __pyx_t_4;
         __pyx_t_4 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":489
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":494
  *                 for pattern, arr in pre.precomputed_collocations.iteritems():
  *                     phrase = self.pattern2phrase(pattern)
  *                     self.precomputed_collocations[phrase] = arr             # <<<<<<<<<<<<<<
  *             stop_time = monitor_cpu()
  *             logger.info("Processing precomputations took %f seconds", stop_time - start_time)
  */
-        if (PyObject_SetItem(__pyx_v_self->precomputed_collocations, __pyx_v_phrase, __pyx_v_arr) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 489; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (PyObject_SetItem(__pyx_v_self->precomputed_collocations, __pyx_v_phrase, __pyx_v_arr) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 494; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       }
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       goto __pyx_L13;
     }
     __pyx_L13:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":490
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":495
  *                     phrase = self.pattern2phrase(pattern)
  *                     self.precomputed_collocations[phrase] = arr
  *             stop_time = monitor_cpu()             # <<<<<<<<<<<<<<
  *             logger.info("Processing precomputations took %f seconds", stop_time - start_time)
  * 
  */
-    __pyx_t_5 = PyFloat_FromDouble(__pyx_f_3_sa_monitor_cpu()); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 490; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyFloat_FromDouble(__pyx_f_3_sa_monitor_cpu()); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 495; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __pyx_v_stop_time = __pyx_t_5;
     __pyx_t_5 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":491
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":496
  *                     self.precomputed_collocations[phrase] = arr
  *             stop_time = monitor_cpu()
  *             logger.info("Processing precomputations took %f seconds", stop_time - start_time)             # <<<<<<<<<<<<<<
  * 
  * 
  */
-    __pyx_t_5 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 491; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_4 = PyObject_GetAttr(__pyx_t_5, __pyx_n_s__info); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 491; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_GetAttr(__pyx_t_5, __pyx_n_s__info); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __pyx_t_5 = PyNumber_Subtract(__pyx_v_stop_time, __pyx_v_start_time); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 491; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyNumber_Subtract(__pyx_v_stop_time, __pyx_v_start_time); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 491; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_INCREF(((PyObject *)__pyx_kp_s_115));
     PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_kp_s_115));
@@ -41481,7 +41463,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
     PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_5);
     __Pyx_GIVEREF(__pyx_t_5);
     __pyx_t_5 = 0;
-    __pyx_t_5 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 491; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
@@ -41523,7 +41505,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_11get_precomputed_collo
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":494
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":499
  * 
  * 
  *     def get_precomputed_collocation(self, phrase):             # <<<<<<<<<<<<<<
@@ -41545,29 +41527,29 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_10get_precomputed_collo
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_precomputed_collocation", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":495
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":500
  * 
  *     def get_precomputed_collocation(self, phrase):
  *         if phrase in self.precomputed_collocations:             # <<<<<<<<<<<<<<
  *             arr = self.precomputed_collocations[phrase]
  *             return PhraseLocation(arr=arr, arr_low=0, arr_high=len(arr), num_subpatterns=phrase.arity()+1)
  */
-  __pyx_t_1 = (__Pyx_PySequence_Contains(__pyx_v_phrase, __pyx_v_self->precomputed_collocations, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 495; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = (__Pyx_PySequence_Contains(__pyx_v_phrase, __pyx_v_self->precomputed_collocations, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 500; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   if (__pyx_t_1) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":496
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":501
  *     def get_precomputed_collocation(self, phrase):
  *         if phrase in self.precomputed_collocations:
  *             arr = self.precomputed_collocations[phrase]             # <<<<<<<<<<<<<<
  *             return PhraseLocation(arr=arr, arr_low=0, arr_high=len(arr), num_subpatterns=phrase.arity()+1)
  *         return None
  */
-    __pyx_t_2 = PyObject_GetItem(__pyx_v_self->precomputed_collocations, __pyx_v_phrase); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyObject_GetItem(__pyx_v_self->precomputed_collocations, __pyx_v_phrase); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 501; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_v_arr = __pyx_t_2;
     __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":497
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":502
  *         if phrase in self.precomputed_collocations:
  *             arr = self.precomputed_collocations[phrase]
  *             return PhraseLocation(arr=arr, arr_low=0, arr_high=len(arr), num_subpatterns=phrase.arity()+1)             # <<<<<<<<<<<<<<
@@ -41575,26 +41557,26 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_10get_precomputed_collo
  * 
  */
     __Pyx_XDECREF(__pyx_r);
-    __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 497; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(((PyObject *)__pyx_t_2));
-    if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__arr), __pyx_v_arr) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 497; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__arr_low), __pyx_int_0) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 497; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_3 = PyObject_Length(__pyx_v_arr); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 497; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_4 = PyInt_FromSsize_t(__pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 497; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__arr), __pyx_v_arr) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__arr_low), __pyx_int_0) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_Length(__pyx_v_arr); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyInt_FromSsize_t(__pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__arr_high), __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 497; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__arr_high), __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = PyObject_GetAttr(__pyx_v_phrase, __pyx_n_s__arity); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 497; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_GetAttr(__pyx_v_phrase, __pyx_n_s__arity); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 497; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = PyNumber_Add(__pyx_t_5, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 497; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyNumber_Add(__pyx_t_5, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__num_subpatterns), __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 497; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__num_subpatterns), __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_PhraseLocation)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_2)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 497; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_PhraseLocation)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_2)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
     __pyx_r = __pyx_t_4;
@@ -41604,7 +41586,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_10get_precomputed_collo
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":498
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":503
  *             arr = self.precomputed_collocations[phrase]
  *             return PhraseLocation(arr=arr, arr_low=0, arr_high=len(arr), num_subpatterns=phrase.arity()+1)
  *         return None             # <<<<<<<<<<<<<<
@@ -41631,7 +41613,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_10get_precomputed_collo
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":501
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":506
  * 
  * 
  *     cdef int* baeza_yates_helper(self, int low1, int high1, int* arr1, int step1,             # <<<<<<<<<<<<<<
@@ -41677,7 +41659,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("baeza_yates_helper", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":514
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":519
  *         cdef Matching loc1, loc2
  * 
  *         result = <int*> malloc(0*sizeof(int*))             # <<<<<<<<<<<<<<
@@ -41686,7 +41668,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   __pyx_v_result = ((int *)malloc((0 * (sizeof(int *)))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":516
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":521
  *         result = <int*> malloc(0*sizeof(int*))
  * 
  *         d_first = 0             # <<<<<<<<<<<<<<
@@ -41695,7 +41677,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   __pyx_v_d_first = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":517
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":522
  * 
  *         d_first = 0
  *         if high1 - low1 > high2 - low2:             # <<<<<<<<<<<<<<
@@ -41705,7 +41687,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   __pyx_t_1 = ((__pyx_v_high1 - __pyx_v_low1) > (__pyx_v_high2 - __pyx_v_low2));
   if (__pyx_t_1) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":518
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":523
  *         d_first = 0
  *         if high1 - low1 > high2 - low2:
  *             d_first = 1             # <<<<<<<<<<<<<<
@@ -41717,7 +41699,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":522
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":527
  *         # First, check to see if we are at any of the recursive base cases
  *         # Case 1: one of the sets is empty
  *         if low1 >= high1 or low2 >= high2:             # <<<<<<<<<<<<<<
@@ -41733,7 +41715,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   }
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":523
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":528
  *         # Case 1: one of the sets is empty
  *         if low1 >= high1 or low2 >= high2:
  *             return result             # <<<<<<<<<<<<<<
@@ -41746,7 +41728,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   }
   __pyx_L4:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":526
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":531
  * 
  *         # Case 2: sets are non-overlapping
  *         assign_matching(&loc1, arr1, high1-step1, step1, self.fda.sent_id.arr)             # <<<<<<<<<<<<<<
@@ -41755,7 +41737,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   __pyx_f_3_sa_assign_matching((&__pyx_v_loc1), __pyx_v_arr1, (__pyx_v_high1 - __pyx_v_step1), __pyx_v_step1, __pyx_v_self->fda->sent_id->arr);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":527
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":532
  *         # Case 2: sets are non-overlapping
  *         assign_matching(&loc1, arr1, high1-step1, step1, self.fda.sent_id.arr)
  *         assign_matching(&loc2, arr2, low2, step2, self.fda.sent_id.arr)             # <<<<<<<<<<<<<<
@@ -41764,7 +41746,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   __pyx_f_3_sa_assign_matching((&__pyx_v_loc2), __pyx_v_arr2, __pyx_v_low2, __pyx_v_step2, __pyx_v_self->fda->sent_id->arr);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":528
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":533
  *         assign_matching(&loc1, arr1, high1-step1, step1, self.fda.sent_id.arr)
  *         assign_matching(&loc2, arr2, low2, step2, self.fda.sent_id.arr)
  *         if self.compare_matchings(&loc1, &loc2, offset_by_one, len_last) == -1:             # <<<<<<<<<<<<<<
@@ -41774,7 +41756,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   __pyx_t_3 = (((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->compare_matchings(__pyx_v_self, (&__pyx_v_loc1), (&__pyx_v_loc2), __pyx_v_offset_by_one, __pyx_v_len_last) == -1);
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":529
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":534
  *         assign_matching(&loc2, arr2, low2, step2, self.fda.sent_id.arr)
  *         if self.compare_matchings(&loc1, &loc2, offset_by_one, len_last) == -1:
  *             return result             # <<<<<<<<<<<<<<
@@ -41787,7 +41769,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   }
   __pyx_L5:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":531
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":536
  *             return result
  * 
  *         assign_matching(&loc1, arr1, low1, step1, self.fda.sent_id.arr)             # <<<<<<<<<<<<<<
@@ -41796,7 +41778,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   __pyx_f_3_sa_assign_matching((&__pyx_v_loc1), __pyx_v_arr1, __pyx_v_low1, __pyx_v_step1, __pyx_v_self->fda->sent_id->arr);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":532
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":537
  * 
  *         assign_matching(&loc1, arr1, low1, step1, self.fda.sent_id.arr)
  *         assign_matching(&loc2, arr2, high2-step2, step2, self.fda.sent_id.arr)             # <<<<<<<<<<<<<<
@@ -41805,7 +41787,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   __pyx_f_3_sa_assign_matching((&__pyx_v_loc2), __pyx_v_arr2, (__pyx_v_high2 - __pyx_v_step2), __pyx_v_step2, __pyx_v_self->fda->sent_id->arr);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":533
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":538
  *         assign_matching(&loc1, arr1, low1, step1, self.fda.sent_id.arr)
  *         assign_matching(&loc2, arr2, high2-step2, step2, self.fda.sent_id.arr)
  *         if self.compare_matchings(&loc1, &loc2, offset_by_one, len_last) == 1:             # <<<<<<<<<<<<<<
@@ -41815,7 +41797,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   __pyx_t_3 = (((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->compare_matchings(__pyx_v_self, (&__pyx_v_loc1), (&__pyx_v_loc2), __pyx_v_offset_by_one, __pyx_v_len_last) == 1);
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":534
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":539
  *         assign_matching(&loc2, arr2, high2-step2, step2, self.fda.sent_id.arr)
  *         if self.compare_matchings(&loc1, &loc2, offset_by_one, len_last) == 1:
  *             return result             # <<<<<<<<<<<<<<
@@ -41828,7 +41810,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   }
   __pyx_L6:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":538
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":543
  *         # Case 3: query set and data set do not meet size mismatch constraints;
  *         # We use mergesort instead in this case
  *         qsetsize = (high1-low1) / step1             # <<<<<<<<<<<<<<
@@ -41838,15 +41820,15 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   __pyx_t_4 = (__pyx_v_high1 - __pyx_v_low1);
   if (unlikely(__pyx_v_step1 == 0)) {
     PyErr_Format(PyExc_ZeroDivisionError, "integer division or modulo by zero");
-    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 538; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 543; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   else if (sizeof(int) == sizeof(long) && unlikely(__pyx_v_step1 == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_t_4))) {
     PyErr_Format(PyExc_OverflowError, "value too large to perform division");
-    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 538; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 543; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __pyx_v_qsetsize = __Pyx_div_int(__pyx_t_4, __pyx_v_step1);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":539
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":544
  *         # We use mergesort instead in this case
  *         qsetsize = (high1-low1) / step1
  *         dsetsize = (high2-low2) / step2             # <<<<<<<<<<<<<<
@@ -41856,15 +41838,15 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   __pyx_t_4 = (__pyx_v_high2 - __pyx_v_low2);
   if (unlikely(__pyx_v_step2 == 0)) {
     PyErr_Format(PyExc_ZeroDivisionError, "integer division or modulo by zero");
-    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 539; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 544; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   else if (sizeof(int) == sizeof(long) && unlikely(__pyx_v_step2 == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_t_4))) {
     PyErr_Format(PyExc_OverflowError, "value too large to perform division");
-    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 539; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 544; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __pyx_v_dsetsize = __Pyx_div_int(__pyx_t_4, __pyx_v_step2);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":540
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":545
  *         qsetsize = (high1-low1) / step1
  *         dsetsize = (high2-low2) / step2
  *         if d_first:             # <<<<<<<<<<<<<<
@@ -41873,7 +41855,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   if (__pyx_v_d_first) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":541
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":546
  *         dsetsize = (high2-low2) / step2
  *         if d_first:
  *             tmp = qsetsize             # <<<<<<<<<<<<<<
@@ -41882,7 +41864,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_v_tmp = __pyx_v_qsetsize;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":542
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":547
  *         if d_first:
  *             tmp = qsetsize
  *             qsetsize = dsetsize             # <<<<<<<<<<<<<<
@@ -41891,7 +41873,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_v_qsetsize = __pyx_v_dsetsize;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":543
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":548
  *             tmp = qsetsize
  *             qsetsize = dsetsize
  *             dsetsize = tmp             # <<<<<<<<<<<<<<
@@ -41903,7 +41885,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   }
   __pyx_L7:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":545
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":550
  *             dsetsize = tmp
  * 
  *         if self.by_slack_factor * qsetsize * log(dsetsize) / log(2) > dsetsize:             # <<<<<<<<<<<<<<
@@ -41914,12 +41896,12 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   __pyx_t_6 = log(2.0);
   if (unlikely(__pyx_t_6 == 0)) {
     PyErr_Format(PyExc_ZeroDivisionError, "float division");
-    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 545; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 550; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __pyx_t_3 = ((__pyx_t_5 / __pyx_t_6) > __pyx_v_dsetsize);
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":546
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":551
  * 
  *         if self.by_slack_factor * qsetsize * log(dsetsize) / log(2) > dsetsize:
  *             free(result)             # <<<<<<<<<<<<<<
@@ -41928,7 +41910,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     free(__pyx_v_result);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":547
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":552
  *         if self.by_slack_factor * qsetsize * log(dsetsize) / log(2) > dsetsize:
  *             free(result)
  *             return self.merge_helper(low1, high1, arr1, step1, low2, high2, arr2, step2, offset_by_one, len_last, num_subpatterns, result_len)             # <<<<<<<<<<<<<<
@@ -41941,7 +41923,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   }
   __pyx_L8:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":551
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":556
  *         # binary search.    There are two flavors, depending on
  *         # whether the queryset or dataset is first
  *         if d_first:             # <<<<<<<<<<<<<<
@@ -41950,7 +41932,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   if (__pyx_v_d_first) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":552
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":557
  *         # whether the queryset or dataset is first
  *         if d_first:
  *             med2 = median(low2, high2, step2)             # <<<<<<<<<<<<<<
@@ -41959,7 +41941,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_v_med2 = __pyx_f_3_sa_median(__pyx_v_low2, __pyx_v_high2, __pyx_v_step2);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":553
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":558
  *         if d_first:
  *             med2 = median(low2, high2, step2)
  *             assign_matching(&loc2, arr2, med2, step2, self.fda.sent_id.arr)             # <<<<<<<<<<<<<<
@@ -41968,7 +41950,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_f_3_sa_assign_matching((&__pyx_v_loc2), __pyx_v_arr2, __pyx_v_med2, __pyx_v_step2, __pyx_v_self->fda->sent_id->arr);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":555
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":560
  *             assign_matching(&loc2, arr2, med2, step2, self.fda.sent_id.arr)
  * 
  *             search_low = low1             # <<<<<<<<<<<<<<
@@ -41977,7 +41959,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_v_search_low = __pyx_v_low1;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":556
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":561
  * 
  *             search_low = low1
  *             search_high = high1             # <<<<<<<<<<<<<<
@@ -41986,7 +41968,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_v_search_high = __pyx_v_high1;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":557
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":562
  *             search_low = low1
  *             search_high = high1
  *             while search_low < search_high:             # <<<<<<<<<<<<<<
@@ -41997,7 +41979,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
       __pyx_t_3 = (__pyx_v_search_low < __pyx_v_search_high);
       if (!__pyx_t_3) break;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":558
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":563
  *             search_high = high1
  *             while search_low < search_high:
  *                 med1 = median(search_low, search_high, step1)             # <<<<<<<<<<<<<<
@@ -42006,7 +41988,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
       __pyx_v_med1 = __pyx_f_3_sa_median(__pyx_v_search_low, __pyx_v_search_high, __pyx_v_step1);
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":559
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":564
  *             while search_low < search_high:
  *                 med1 = median(search_low, search_high, step1)
  *                 find_comparable_matchings(low1, high1, arr1, step1, med1, &med1_minus, &med1_plus)             # <<<<<<<<<<<<<<
@@ -42015,7 +41997,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
       __pyx_f_3_sa_find_comparable_matchings(__pyx_v_low1, __pyx_v_high1, __pyx_v_arr1, __pyx_v_step1, __pyx_v_med1, (&__pyx_v_med1_minus), (&__pyx_v_med1_plus));
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":560
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":565
  *                 med1 = median(search_low, search_high, step1)
  *                 find_comparable_matchings(low1, high1, arr1, step1, med1, &med1_minus, &med1_plus)
  *                 comparison = self.compare_matchings_set(med1_minus, med1_plus, arr1, step1, &loc2, offset_by_one, len_last)             # <<<<<<<<<<<<<<
@@ -42024,7 +42006,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
       __pyx_v_comparison = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->compare_matchings_set(__pyx_v_self, __pyx_v_med1_minus, __pyx_v_med1_plus, __pyx_v_arr1, __pyx_v_step1, (&__pyx_v_loc2), __pyx_v_offset_by_one, __pyx_v_len_last);
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":563
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":568
  *                 if comparison == -1:
  *                     search_low = med1_plus
  *                 elif comparison == 1:             # <<<<<<<<<<<<<<
@@ -42033,7 +42015,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
       switch (__pyx_v_comparison) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":561
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":566
  *                 find_comparable_matchings(low1, high1, arr1, step1, med1, &med1_minus, &med1_plus)
  *                 comparison = self.compare_matchings_set(med1_minus, med1_plus, arr1, step1, &loc2, offset_by_one, len_last)
  *                 if comparison == -1:             # <<<<<<<<<<<<<<
@@ -42042,7 +42024,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
         case -1:
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":562
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":567
  *                 comparison = self.compare_matchings_set(med1_minus, med1_plus, arr1, step1, &loc2, offset_by_one, len_last)
  *                 if comparison == -1:
  *                     search_low = med1_plus             # <<<<<<<<<<<<<<
@@ -42052,7 +42034,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
         __pyx_v_search_low = __pyx_v_med1_plus;
         break;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":563
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":568
  *                 if comparison == -1:
  *                     search_low = med1_plus
  *                 elif comparison == 1:             # <<<<<<<<<<<<<<
@@ -42061,7 +42043,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
         case 1:
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":564
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":569
  *                     search_low = med1_plus
  *                 elif comparison == 1:
  *                     search_high = med1_minus             # <<<<<<<<<<<<<<
@@ -42072,7 +42054,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
         break;
         default:
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":566
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":571
  *                     search_high = med1_minus
  *                 else:
  *                     break             # <<<<<<<<<<<<<<
@@ -42088,7 +42070,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":568
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":573
  *                     break
  *         else:
  *             med1 = median(low1, high1, step1)             # <<<<<<<<<<<<<<
@@ -42097,7 +42079,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_v_med1 = __pyx_f_3_sa_median(__pyx_v_low1, __pyx_v_high1, __pyx_v_step1);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":569
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":574
  *         else:
  *             med1 = median(low1, high1, step1)
  *             find_comparable_matchings(low1, high1, arr1, step1, med1, &med1_minus, &med1_plus)             # <<<<<<<<<<<<<<
@@ -42106,7 +42088,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_f_3_sa_find_comparable_matchings(__pyx_v_low1, __pyx_v_high1, __pyx_v_arr1, __pyx_v_step1, __pyx_v_med1, (&__pyx_v_med1_minus), (&__pyx_v_med1_plus));
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":571
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":576
  *             find_comparable_matchings(low1, high1, arr1, step1, med1, &med1_minus, &med1_plus)
  * 
  *             search_low = low2             # <<<<<<<<<<<<<<
@@ -42115,7 +42097,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_v_search_low = __pyx_v_low2;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":572
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":577
  * 
  *             search_low = low2
  *             search_high = high2             # <<<<<<<<<<<<<<
@@ -42124,7 +42106,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_v_search_high = __pyx_v_high2;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":573
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":578
  *             search_low = low2
  *             search_high = high2
  *             while search_low < search_high:             # <<<<<<<<<<<<<<
@@ -42135,7 +42117,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
       __pyx_t_3 = (__pyx_v_search_low < __pyx_v_search_high);
       if (!__pyx_t_3) break;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":574
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":579
  *             search_high = high2
  *             while search_low < search_high:
  *                 med2 = median(search_low, search_high, step2)             # <<<<<<<<<<<<<<
@@ -42144,7 +42126,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
       __pyx_v_med2 = __pyx_f_3_sa_median(__pyx_v_search_low, __pyx_v_search_high, __pyx_v_step2);
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":575
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":580
  *             while search_low < search_high:
  *                 med2 = median(search_low, search_high, step2)
  *                 assign_matching(&loc2, arr2, med2, step2, self.fda.sent_id.arr)             # <<<<<<<<<<<<<<
@@ -42153,7 +42135,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
       __pyx_f_3_sa_assign_matching((&__pyx_v_loc2), __pyx_v_arr2, __pyx_v_med2, __pyx_v_step2, __pyx_v_self->fda->sent_id->arr);
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":576
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":581
  *                 med2 = median(search_low, search_high, step2)
  *                 assign_matching(&loc2, arr2, med2, step2, self.fda.sent_id.arr)
  *                 comparison = self.compare_matchings_set(med1_minus, med1_plus, arr1, step1, &loc2, offset_by_one, len_last)             # <<<<<<<<<<<<<<
@@ -42162,7 +42144,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
       __pyx_v_comparison = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->compare_matchings_set(__pyx_v_self, __pyx_v_med1_minus, __pyx_v_med1_plus, __pyx_v_arr1, __pyx_v_step1, (&__pyx_v_loc2), __pyx_v_offset_by_one, __pyx_v_len_last);
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":579
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":584
  *                 if comparison == -1:
  *                     search_high = med2
  *                 elif comparison == 1:             # <<<<<<<<<<<<<<
@@ -42171,7 +42153,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
       switch (__pyx_v_comparison) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":577
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":582
  *                 assign_matching(&loc2, arr2, med2, step2, self.fda.sent_id.arr)
  *                 comparison = self.compare_matchings_set(med1_minus, med1_plus, arr1, step1, &loc2, offset_by_one, len_last)
  *                 if comparison == -1:             # <<<<<<<<<<<<<<
@@ -42180,7 +42162,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
         case -1:
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":578
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":583
  *                 comparison = self.compare_matchings_set(med1_minus, med1_plus, arr1, step1, &loc2, offset_by_one, len_last)
  *                 if comparison == -1:
  *                     search_high = med2             # <<<<<<<<<<<<<<
@@ -42190,7 +42172,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
         __pyx_v_search_high = __pyx_v_med2;
         break;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":579
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":584
  *                 if comparison == -1:
  *                     search_high = med2
  *                 elif comparison == 1:             # <<<<<<<<<<<<<<
@@ -42199,7 +42181,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
         case 1:
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":580
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":585
  *                     search_high = med2
  *                 elif comparison == 1:
  *                     search_low = med2 + step2             # <<<<<<<<<<<<<<
@@ -42210,7 +42192,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
         break;
         default:
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":582
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":587
  *                     search_low = med2 + step2
  *                 else:
  *                     break             # <<<<<<<<<<<<<<
@@ -42225,7 +42207,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   }
   __pyx_L9:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":584
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":589
  *                     break
  * 
  *         med_result_len = 0             # <<<<<<<<<<<<<<
@@ -42234,7 +42216,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   __pyx_v_med_result_len = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":585
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":590
  * 
  *         med_result_len = 0
  *         med_result = <int*> malloc(0*sizeof(int*))             # <<<<<<<<<<<<<<
@@ -42243,7 +42225,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   __pyx_v_med_result = ((int *)malloc((0 * (sizeof(int *)))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":586
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":591
  *         med_result_len = 0
  *         med_result = <int*> malloc(0*sizeof(int*))
  *         if search_high > search_low:             # <<<<<<<<<<<<<<
@@ -42253,7 +42235,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   __pyx_t_3 = (__pyx_v_search_high > __pyx_v_search_low);
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":592
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":597
  *             # want to store the bindings for all of those elements.    We can
  *             # subsequently throw all of them away.
  *             med2_minus = med2             # <<<<<<<<<<<<<<
@@ -42262,7 +42244,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_v_med2_minus = __pyx_v_med2;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":593
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":598
  *             # subsequently throw all of them away.
  *             med2_minus = med2
  *             med2_plus = med2 + step2             # <<<<<<<<<<<<<<
@@ -42271,7 +42253,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_v_med2_plus = (__pyx_v_med2 + __pyx_v_step2);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":594
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":599
  *             med2_minus = med2
  *             med2_plus = med2 + step2
  *             i1 = med1_minus             # <<<<<<<<<<<<<<
@@ -42280,7 +42262,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_v_i1 = __pyx_v_med1_minus;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":595
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":600
  *             med2_plus = med2 + step2
  *             i1 = med1_minus
  *             while i1 < med1_plus:             # <<<<<<<<<<<<<<
@@ -42291,7 +42273,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
       __pyx_t_3 = (__pyx_v_i1 < __pyx_v_med1_plus);
       if (!__pyx_t_3) break;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":596
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":601
  *             i1 = med1_minus
  *             while i1 < med1_plus:
  *                 assign_matching(&loc1, arr1, i1, step1, self.fda.sent_id.arr)             # <<<<<<<<<<<<<<
@@ -42300,7 +42282,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
       __pyx_f_3_sa_assign_matching((&__pyx_v_loc1), __pyx_v_arr1, __pyx_v_i1, __pyx_v_step1, __pyx_v_self->fda->sent_id->arr);
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":597
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":602
  *             while i1 < med1_plus:
  *                 assign_matching(&loc1, arr1, i1, step1, self.fda.sent_id.arr)
  *                 while med2_minus-step2 >= low2:             # <<<<<<<<<<<<<<
@@ -42311,7 +42293,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
         __pyx_t_3 = ((__pyx_v_med2_minus - __pyx_v_step2) >= __pyx_v_low2);
         if (!__pyx_t_3) break;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":598
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":603
  *                 assign_matching(&loc1, arr1, i1, step1, self.fda.sent_id.arr)
  *                 while med2_minus-step2 >= low2:
  *                     assign_matching(&loc2, arr2, med2_minus-step2, step2, self.fda.sent_id.arr)             # <<<<<<<<<<<<<<
@@ -42320,7 +42302,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
         __pyx_f_3_sa_assign_matching((&__pyx_v_loc2), __pyx_v_arr2, (__pyx_v_med2_minus - __pyx_v_step2), __pyx_v_step2, __pyx_v_self->fda->sent_id->arr);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":599
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":604
  *                 while med2_minus-step2 >= low2:
  *                     assign_matching(&loc2, arr2, med2_minus-step2, step2, self.fda.sent_id.arr)
  *                     if self.compare_matchings(&loc1, &loc2, offset_by_one, len_last) < 1:             # <<<<<<<<<<<<<<
@@ -42330,7 +42312,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
         __pyx_t_3 = (((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->compare_matchings(__pyx_v_self, (&__pyx_v_loc1), (&__pyx_v_loc2), __pyx_v_offset_by_one, __pyx_v_len_last) < 1);
         if (__pyx_t_3) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":600
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":605
  *                     assign_matching(&loc2, arr2, med2_minus-step2, step2, self.fda.sent_id.arr)
  *                     if self.compare_matchings(&loc1, &loc2, offset_by_one, len_last) < 1:
  *                         med2_minus = med2_minus - step2             # <<<<<<<<<<<<<<
@@ -42342,7 +42324,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
         }
         /*else*/ {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":602
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":607
  *                         med2_minus = med2_minus - step2
  *                     else:
  *                         break             # <<<<<<<<<<<<<<
@@ -42355,7 +42337,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
       }
       __pyx_L18_break:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":603
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":608
  *                     else:
  *                         break
  *                 i2 = med2_minus             # <<<<<<<<<<<<<<
@@ -42364,7 +42346,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
       __pyx_v_i2 = __pyx_v_med2_minus;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":604
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":609
  *                         break
  *                 i2 = med2_minus
  *                 while i2 < high2:             # <<<<<<<<<<<<<<
@@ -42375,7 +42357,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
         __pyx_t_3 = (__pyx_v_i2 < __pyx_v_high2);
         if (!__pyx_t_3) break;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":605
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":610
  *                 i2 = med2_minus
  *                 while i2 < high2:
  *                     assign_matching(&loc2, arr2, i2, step2, self.fda.sent_id.arr)             # <<<<<<<<<<<<<<
@@ -42384,7 +42366,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
         __pyx_f_3_sa_assign_matching((&__pyx_v_loc2), __pyx_v_arr2, __pyx_v_i2, __pyx_v_step2, __pyx_v_self->fda->sent_id->arr);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":606
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":611
  *                 while i2 < high2:
  *                     assign_matching(&loc2, arr2, i2, step2, self.fda.sent_id.arr)
  *                     comparison = self.compare_matchings(&loc1, &loc2, offset_by_one, len_last)             # <<<<<<<<<<<<<<
@@ -42393,7 +42375,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
         __pyx_v_comparison = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->compare_matchings(__pyx_v_self, (&__pyx_v_loc1), (&__pyx_v_loc2), __pyx_v_offset_by_one, __pyx_v_len_last);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":607
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":612
  *                     assign_matching(&loc2, arr2, i2, step2, self.fda.sent_id.arr)
  *                     comparison = self.compare_matchings(&loc1, &loc2, offset_by_one, len_last)
  *                     if comparison == 0:             # <<<<<<<<<<<<<<
@@ -42403,7 +42385,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
         __pyx_t_3 = (__pyx_v_comparison == 0);
         if (__pyx_t_3) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":609
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":614
  *                     if comparison == 0:
  *                         pass
  *                         med_result = append_combined_matching(med_result, &loc1, &loc2, offset_by_one, num_subpatterns, &med_result_len)             # <<<<<<<<<<<<<<
@@ -42415,7 +42397,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
         }
         __pyx_L22:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":610
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":615
  *                         pass
  *                         med_result = append_combined_matching(med_result, &loc1, &loc2, offset_by_one, num_subpatterns, &med_result_len)
  *                     if comparison == -1:             # <<<<<<<<<<<<<<
@@ -42425,7 +42407,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
         __pyx_t_3 = (__pyx_v_comparison == -1);
         if (__pyx_t_3) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":611
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":616
  *                         med_result = append_combined_matching(med_result, &loc1, &loc2, offset_by_one, num_subpatterns, &med_result_len)
  *                     if comparison == -1:
  *                         break             # <<<<<<<<<<<<<<
@@ -42437,7 +42419,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
         }
         __pyx_L23:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":612
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":617
  *                     if comparison == -1:
  *                         break
  *                     i2 = i2 + step2             # <<<<<<<<<<<<<<
@@ -42448,7 +42430,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
       }
       __pyx_L21_break:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":613
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":618
  *                         break
  *                     i2 = i2 + step2
  *                 if i2 > med2_plus:             # <<<<<<<<<<<<<<
@@ -42458,7 +42440,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
       __pyx_t_3 = (__pyx_v_i2 > __pyx_v_med2_plus);
       if (__pyx_t_3) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":614
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":619
  *                     i2 = i2 + step2
  *                 if i2 > med2_plus:
  *                     med2_plus = i2             # <<<<<<<<<<<<<<
@@ -42470,7 +42452,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
       }
       __pyx_L24:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":615
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":620
  *                 if i2 > med2_plus:
  *                     med2_plus = i2
  *                 i1 = i1 + step1             # <<<<<<<<<<<<<<
@@ -42480,7 +42462,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
       __pyx_v_i1 = (__pyx_v_i1 + __pyx_v_step1);
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":617
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":622
  *                 i1 = i1 + step1
  * 
  *             tmp = med1_minus             # <<<<<<<<<<<<<<
@@ -42489,7 +42471,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_v_tmp = __pyx_v_med1_minus;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":618
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":623
  * 
  *             tmp = med1_minus
  *             med1_minus = med1_plus             # <<<<<<<<<<<<<<
@@ -42498,7 +42480,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_v_med1_minus = __pyx_v_med1_plus;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":619
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":624
  *             tmp = med1_minus
  *             med1_minus = med1_plus
  *             med1_plus = tmp             # <<<<<<<<<<<<<<
@@ -42510,7 +42492,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":622
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":627
  *         else:
  *             # No match; need to figure out the point of division in D and Q
  *             med2_minus = med2             # <<<<<<<<<<<<<<
@@ -42519,7 +42501,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_v_med2_minus = __pyx_v_med2;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":623
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":628
  *             # No match; need to figure out the point of division in D and Q
  *             med2_minus = med2
  *             med2_plus = med2             # <<<<<<<<<<<<<<
@@ -42528,7 +42510,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_v_med2_plus = __pyx_v_med2;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":624
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":629
  *             med2_minus = med2
  *             med2_plus = med2
  *             if d_first:             # <<<<<<<<<<<<<<
@@ -42537,7 +42519,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     if (__pyx_v_d_first) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":625
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":630
  *             med2_plus = med2
  *             if d_first:
  *                 med2_minus = med2_minus + step2             # <<<<<<<<<<<<<<
@@ -42546,7 +42528,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
       __pyx_v_med2_minus = (__pyx_v_med2_minus + __pyx_v_step2);
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":626
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":631
  *             if d_first:
  *                 med2_minus = med2_minus + step2
  *                 if comparison == -1:             # <<<<<<<<<<<<<<
@@ -42556,7 +42538,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
       __pyx_t_3 = (__pyx_v_comparison == -1);
       if (__pyx_t_3) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":627
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":632
  *                 med2_minus = med2_minus + step2
  *                 if comparison == -1:
  *                     med1_minus = med1_plus             # <<<<<<<<<<<<<<
@@ -42568,7 +42550,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
       }
       __pyx_L26:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":628
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":633
  *                 if comparison == -1:
  *                     med1_minus = med1_plus
  *                 if comparison == 1:             # <<<<<<<<<<<<<<
@@ -42578,7 +42560,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
       __pyx_t_3 = (__pyx_v_comparison == 1);
       if (__pyx_t_3) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":629
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":634
  *                     med1_minus = med1_plus
  *                 if comparison == 1:
  *                     med1_plus = med1_minus             # <<<<<<<<<<<<<<
@@ -42593,7 +42575,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
     }
     /*else*/ {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":631
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":636
  *                     med1_plus = med1_minus
  *             else:
  *                 tmp = med1_minus             # <<<<<<<<<<<<<<
@@ -42602,7 +42584,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
       __pyx_v_tmp = __pyx_v_med1_minus;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":632
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":637
  *             else:
  *                 tmp = med1_minus
  *                 med1_minus = med1_plus             # <<<<<<<<<<<<<<
@@ -42611,7 +42593,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
       __pyx_v_med1_minus = __pyx_v_med1_plus;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":633
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":638
  *                 tmp = med1_minus
  *                 med1_minus = med1_plus
  *                 med1_plus = tmp             # <<<<<<<<<<<<<<
@@ -42620,7 +42602,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
       __pyx_v_med1_plus = __pyx_v_tmp;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":634
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":639
  *                 med1_minus = med1_plus
  *                 med1_plus = tmp
  *                 if comparison == 1:             # <<<<<<<<<<<<<<
@@ -42630,7 +42612,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
       __pyx_t_3 = (__pyx_v_comparison == 1);
       if (__pyx_t_3) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":635
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":640
  *                 med1_plus = tmp
  *                 if comparison == 1:
  *                     med2_minus = med2_minus + step2             # <<<<<<<<<<<<<<
@@ -42639,7 +42621,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
         __pyx_v_med2_minus = (__pyx_v_med2_minus + __pyx_v_step2);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":636
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":641
  *                 if comparison == 1:
  *                     med2_minus = med2_minus + step2
  *                     med2_plus = med2_plus + step2             # <<<<<<<<<<<<<<
@@ -42655,7 +42637,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   }
   __pyx_L14:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":638
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":643
  *                     med2_plus = med2_plus + step2
  * 
  *         low_result_len = 0             # <<<<<<<<<<<<<<
@@ -42664,7 +42646,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   __pyx_v_low_result_len = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":639
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":644
  * 
  *         low_result_len = 0
  *         low_result = self.baeza_yates_helper(low1, med1_plus, arr1, step1, low2, med2_plus, arr2, step2, offset_by_one, len_last, num_subpatterns, &low_result_len)             # <<<<<<<<<<<<<<
@@ -42673,7 +42655,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   __pyx_v_low_result = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->baeza_yates_helper(__pyx_v_self, __pyx_v_low1, __pyx_v_med1_plus, __pyx_v_arr1, __pyx_v_step1, __pyx_v_low2, __pyx_v_med2_plus, __pyx_v_arr2, __pyx_v_step2, __pyx_v_offset_by_one, __pyx_v_len_last, __pyx_v_num_subpatterns, (&__pyx_v_low_result_len));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":640
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":645
  *         low_result_len = 0
  *         low_result = self.baeza_yates_helper(low1, med1_plus, arr1, step1, low2, med2_plus, arr2, step2, offset_by_one, len_last, num_subpatterns, &low_result_len)
  *         high_result_len = 0             # <<<<<<<<<<<<<<
@@ -42682,7 +42664,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   __pyx_v_high_result_len = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":641
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":646
  *         low_result = self.baeza_yates_helper(low1, med1_plus, arr1, step1, low2, med2_plus, arr2, step2, offset_by_one, len_last, num_subpatterns, &low_result_len)
  *         high_result_len = 0
  *         high_result = self.baeza_yates_helper(med1_minus, high1, arr1, step1, med2_minus, high2, arr2, step2, offset_by_one, len_last, num_subpatterns, &high_result_len)             # <<<<<<<<<<<<<<
@@ -42691,7 +42673,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   __pyx_v_high_result = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->baeza_yates_helper(__pyx_v_self, __pyx_v_med1_minus, __pyx_v_high1, __pyx_v_arr1, __pyx_v_step1, __pyx_v_med2_minus, __pyx_v_high2, __pyx_v_arr2, __pyx_v_step2, __pyx_v_offset_by_one, __pyx_v_len_last, __pyx_v_num_subpatterns, (&__pyx_v_high_result_len));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":643
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":648
  *         high_result = self.baeza_yates_helper(med1_minus, high1, arr1, step1, med2_minus, high2, arr2, step2, offset_by_one, len_last, num_subpatterns, &high_result_len)
  * 
  *         result = extend_arr(result, result_len, low_result, low_result_len)             # <<<<<<<<<<<<<<
@@ -42700,7 +42682,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   __pyx_v_result = __pyx_f_3_sa_extend_arr(__pyx_v_result, __pyx_v_result_len, __pyx_v_low_result, __pyx_v_low_result_len);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":644
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":649
  * 
  *         result = extend_arr(result, result_len, low_result, low_result_len)
  *         result = extend_arr(result, result_len, med_result, med_result_len)             # <<<<<<<<<<<<<<
@@ -42709,7 +42691,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   __pyx_v_result = __pyx_f_3_sa_extend_arr(__pyx_v_result, __pyx_v_result_len, __pyx_v_med_result, __pyx_v_med_result_len);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":645
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":650
  *         result = extend_arr(result, result_len, low_result, low_result_len)
  *         result = extend_arr(result, result_len, med_result, med_result_len)
  *         result = extend_arr(result, result_len, high_result, high_result_len)             # <<<<<<<<<<<<<<
@@ -42718,7 +42700,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   __pyx_v_result = __pyx_f_3_sa_extend_arr(__pyx_v_result, __pyx_v_result_len, __pyx_v_high_result, __pyx_v_high_result_len);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":646
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":651
  *         result = extend_arr(result, result_len, med_result, med_result_len)
  *         result = extend_arr(result, result_len, high_result, high_result_len)
  *         free(low_result)             # <<<<<<<<<<<<<<
@@ -42727,7 +42709,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   free(__pyx_v_low_result);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":647
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":652
  *         result = extend_arr(result, result_len, high_result, high_result_len)
  *         free(low_result)
  *         free(med_result)             # <<<<<<<<<<<<<<
@@ -42736,7 +42718,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   free(__pyx_v_med_result);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":648
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":653
  *         free(low_result)
  *         free(med_result)
  *         free(high_result)             # <<<<<<<<<<<<<<
@@ -42745,7 +42727,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   free(__pyx_v_high_result);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":650
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":655
  *         free(high_result)
  * 
  *         return result             # <<<<<<<<<<<<<<
@@ -42765,7 +42747,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":654
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":659
  * 
  * 
  *     cdef long compare_matchings_set(self, int i1_minus, int i1_plus, int* arr1, int step1,             # <<<<<<<<<<<<<<
@@ -42784,7 +42766,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
   int __pyx_t_1;
   __Pyx_RefNannySetupContext("compare_matchings_set", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":665
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":670
  *         cdef Matching* loc1
  * 
  *         loc1 = &l1_stack             # <<<<<<<<<<<<<<
@@ -42793,7 +42775,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
  */
   __pyx_v_loc1 = (&__pyx_v_l1_stack);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":667
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":672
  *         loc1 = &l1_stack
  * 
  *         i1 = i1_minus             # <<<<<<<<<<<<<<
@@ -42802,7 +42784,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
  */
   __pyx_v_i1 = __pyx_v_i1_minus;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":668
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":673
  * 
  *         i1 = i1_minus
  *         while i1 < i1_plus:             # <<<<<<<<<<<<<<
@@ -42813,7 +42795,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
     __pyx_t_1 = (__pyx_v_i1 < __pyx_v_i1_plus);
     if (!__pyx_t_1) break;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":669
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":674
  *         i1 = i1_minus
  *         while i1 < i1_plus:
  *             assign_matching(loc1, arr1, i1, step1, self.fda.sent_id.arr)             # <<<<<<<<<<<<<<
@@ -42822,7 +42804,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
  */
     __pyx_f_3_sa_assign_matching(__pyx_v_loc1, __pyx_v_arr1, __pyx_v_i1, __pyx_v_step1, __pyx_v_self->fda->sent_id->arr);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":670
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":675
  *         while i1 < i1_plus:
  *             assign_matching(loc1, arr1, i1, step1, self.fda.sent_id.arr)
  *             comparison = self.compare_matchings(loc1, loc2, offset_by_one, len_last)             # <<<<<<<<<<<<<<
@@ -42831,7 +42813,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
  */
     __pyx_v_comparison = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->compare_matchings(__pyx_v_self, __pyx_v_loc1, __pyx_v_loc2, __pyx_v_offset_by_one, __pyx_v_len_last);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":671
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":676
  *             assign_matching(loc1, arr1, i1, step1, self.fda.sent_id.arr)
  *             comparison = self.compare_matchings(loc1, loc2, offset_by_one, len_last)
  *             if comparison == 0:             # <<<<<<<<<<<<<<
@@ -42841,7 +42823,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
     __pyx_t_1 = (__pyx_v_comparison == 0);
     if (__pyx_t_1) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":672
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":677
  *             comparison = self.compare_matchings(loc1, loc2, offset_by_one, len_last)
  *             if comparison == 0:
  *                 prev_comparison = 0             # <<<<<<<<<<<<<<
@@ -42850,7 +42832,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
  */
       __pyx_v_prev_comparison = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":673
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":678
  *             if comparison == 0:
  *                 prev_comparison = 0
  *                 break             # <<<<<<<<<<<<<<
@@ -42861,7 +42843,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
       goto __pyx_L5;
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":674
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":679
  *                 prev_comparison = 0
  *                 break
  *             elif i1 == i1_minus:             # <<<<<<<<<<<<<<
@@ -42871,7 +42853,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
     __pyx_t_1 = (__pyx_v_i1 == __pyx_v_i1_minus);
     if (__pyx_t_1) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":675
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":680
  *                 break
  *             elif i1 == i1_minus:
  *                 prev_comparison = comparison             # <<<<<<<<<<<<<<
@@ -42883,7 +42865,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
     }
     /*else*/ {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":677
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":682
  *                 prev_comparison = comparison
  *             else:
  *                 if comparison != prev_comparison:             # <<<<<<<<<<<<<<
@@ -42893,7 +42875,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
       __pyx_t_1 = (__pyx_v_comparison != __pyx_v_prev_comparison);
       if (__pyx_t_1) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":678
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":683
  *             else:
  *                 if comparison != prev_comparison:
  *                     prev_comparison = 0             # <<<<<<<<<<<<<<
@@ -42902,7 +42884,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
  */
         __pyx_v_prev_comparison = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":679
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":684
  *                 if comparison != prev_comparison:
  *                     prev_comparison = 0
  *                     break             # <<<<<<<<<<<<<<
@@ -42916,7 +42898,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
     }
     __pyx_L5:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":680
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":685
  *                     prev_comparison = 0
  *                     break
  *             i1 = i1 + step1             # <<<<<<<<<<<<<<
@@ -42927,7 +42909,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
   }
   __pyx_L4_break:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":681
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":686
  *                     break
  *             i1 = i1 + step1
  *         return prev_comparison             # <<<<<<<<<<<<<<
@@ -42943,7 +42925,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":684
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":689
  * 
  * 
  *     cdef long compare_matchings(self, Matching* loc1, Matching* loc2, int offset_by_one, int len_last):             # <<<<<<<<<<<<<<
@@ -42961,7 +42943,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
   int __pyx_t_4;
   __Pyx_RefNannySetupContext("compare_matchings", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":687
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":692
  *         cdef int i
  * 
  *         if loc1.sent_id > loc2.sent_id:             # <<<<<<<<<<<<<<
@@ -42971,7 +42953,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
   __pyx_t_1 = (__pyx_v_loc1->sent_id > __pyx_v_loc2->sent_id);
   if (__pyx_t_1) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":688
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":693
  * 
  *         if loc1.sent_id > loc2.sent_id:
  *             return 1             # <<<<<<<<<<<<<<
@@ -42984,7 +42966,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":689
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":694
  *         if loc1.sent_id > loc2.sent_id:
  *             return 1
  *         if loc2.sent_id > loc1.sent_id:             # <<<<<<<<<<<<<<
@@ -42994,7 +42976,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
   __pyx_t_1 = (__pyx_v_loc2->sent_id > __pyx_v_loc1->sent_id);
   if (__pyx_t_1) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":690
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":695
  *             return 1
  *         if loc2.sent_id > loc1.sent_id:
  *             return -1             # <<<<<<<<<<<<<<
@@ -43007,7 +42989,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
   }
   __pyx_L4:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":692
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":697
  *             return -1
  * 
  *         if loc1.size == 1 and loc2.size == 1:             # <<<<<<<<<<<<<<
@@ -43023,7 +43005,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
   }
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":693
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":698
  * 
  *         if loc1.size == 1 and loc2.size == 1:
  *             if loc2.arr[loc2.start] - loc1.arr[loc1.start] <= self.train_min_gap_size:             # <<<<<<<<<<<<<<
@@ -43033,7 +43015,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
     __pyx_t_3 = (((__pyx_v_loc2->arr[__pyx_v_loc2->start]) - (__pyx_v_loc1->arr[__pyx_v_loc1->start])) <= __pyx_v_self->train_min_gap_size);
     if (__pyx_t_3) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":694
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":699
  *         if loc1.size == 1 and loc2.size == 1:
  *             if loc2.arr[loc2.start] - loc1.arr[loc1.start] <= self.train_min_gap_size:
  *                 return 1             # <<<<<<<<<<<<<<
@@ -43048,7 +43030,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
     goto __pyx_L5;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":696
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":701
  *                 return 1
  * 
  *         elif offset_by_one:             # <<<<<<<<<<<<<<
@@ -43057,7 +43039,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
  */
   if (__pyx_v_offset_by_one) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":697
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":702
  * 
  *         elif offset_by_one:
  *             for i from 1 <= i < loc1.size:             # <<<<<<<<<<<<<<
@@ -43067,7 +43049,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
     __pyx_t_4 = __pyx_v_loc1->size;
     for (__pyx_v_i = 1; __pyx_v_i < __pyx_t_4; __pyx_v_i++) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":698
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":703
  *         elif offset_by_one:
  *             for i from 1 <= i < loc1.size:
  *                 if loc1.arr[loc1.start+i] > loc2.arr[loc2.start+i-1]:             # <<<<<<<<<<<<<<
@@ -43077,7 +43059,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
       __pyx_t_3 = ((__pyx_v_loc1->arr[(__pyx_v_loc1->start + __pyx_v_i)]) > (__pyx_v_loc2->arr[((__pyx_v_loc2->start + __pyx_v_i) - 1)]));
       if (__pyx_t_3) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":699
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":704
  *             for i from 1 <= i < loc1.size:
  *                 if loc1.arr[loc1.start+i] > loc2.arr[loc2.start+i-1]:
  *                     return 1             # <<<<<<<<<<<<<<
@@ -43090,7 +43072,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
       }
       __pyx_L9:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":700
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":705
  *                 if loc1.arr[loc1.start+i] > loc2.arr[loc2.start+i-1]:
  *                     return 1
  *                 if loc1.arr[loc1.start+i] < loc2.arr[loc2.start+i-1]:             # <<<<<<<<<<<<<<
@@ -43100,7 +43082,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
       __pyx_t_3 = ((__pyx_v_loc1->arr[(__pyx_v_loc1->start + __pyx_v_i)]) < (__pyx_v_loc2->arr[((__pyx_v_loc2->start + __pyx_v_i) - 1)]));
       if (__pyx_t_3) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":701
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":706
  *                     return 1
  *                 if loc1.arr[loc1.start+i] < loc2.arr[loc2.start+i-1]:
  *                     return -1             # <<<<<<<<<<<<<<
@@ -43117,7 +43099,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":704
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":709
  * 
  *         else:
  *             if loc1.arr[loc1.start]+1 > loc2.arr[loc2.start]:             # <<<<<<<<<<<<<<
@@ -43127,7 +43109,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
     __pyx_t_3 = (((__pyx_v_loc1->arr[__pyx_v_loc1->start]) + 1) > (__pyx_v_loc2->arr[__pyx_v_loc2->start]));
     if (__pyx_t_3) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":705
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":710
  *         else:
  *             if loc1.arr[loc1.start]+1 > loc2.arr[loc2.start]:
  *                 return 1             # <<<<<<<<<<<<<<
@@ -43140,7 +43122,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
     }
     __pyx_L11:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":706
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":711
  *             if loc1.arr[loc1.start]+1 > loc2.arr[loc2.start]:
  *                 return 1
  *             if loc1.arr[loc1.start]+1 < loc2.arr[loc2.start]:             # <<<<<<<<<<<<<<
@@ -43150,7 +43132,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
     __pyx_t_3 = (((__pyx_v_loc1->arr[__pyx_v_loc1->start]) + 1) < (__pyx_v_loc2->arr[__pyx_v_loc2->start]));
     if (__pyx_t_3) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":707
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":712
  *                 return 1
  *             if loc1.arr[loc1.start]+1 < loc2.arr[loc2.start]:
  *                 return -1             # <<<<<<<<<<<<<<
@@ -43163,7 +43145,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
     }
     __pyx_L12:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":709
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":714
  *                 return -1
  * 
  *             for i from 1 <= i < loc1.size:             # <<<<<<<<<<<<<<
@@ -43173,7 +43155,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
     __pyx_t_4 = __pyx_v_loc1->size;
     for (__pyx_v_i = 1; __pyx_v_i < __pyx_t_4; __pyx_v_i++) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":710
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":715
  * 
  *             for i from 1 <= i < loc1.size:
  *                 if loc1.arr[loc1.start+i] > loc2.arr[loc2.start+i]:             # <<<<<<<<<<<<<<
@@ -43183,7 +43165,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
       __pyx_t_3 = ((__pyx_v_loc1->arr[(__pyx_v_loc1->start + __pyx_v_i)]) > (__pyx_v_loc2->arr[(__pyx_v_loc2->start + __pyx_v_i)]));
       if (__pyx_t_3) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":711
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":716
  *             for i from 1 <= i < loc1.size:
  *                 if loc1.arr[loc1.start+i] > loc2.arr[loc2.start+i]:
  *                     return 1             # <<<<<<<<<<<<<<
@@ -43196,7 +43178,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
       }
       __pyx_L15:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":712
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":717
  *                 if loc1.arr[loc1.start+i] > loc2.arr[loc2.start+i]:
  *                     return 1
  *                 if loc1.arr[loc1.start+i] < loc2.arr[loc2.start+i]:             # <<<<<<<<<<<<<<
@@ -43206,7 +43188,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
       __pyx_t_3 = ((__pyx_v_loc1->arr[(__pyx_v_loc1->start + __pyx_v_i)]) < (__pyx_v_loc2->arr[(__pyx_v_loc2->start + __pyx_v_i)]));
       if (__pyx_t_3) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":713
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":718
  *                     return 1
  *                 if loc1.arr[loc1.start+i] < loc2.arr[loc2.start+i]:
  *                     return -1             # <<<<<<<<<<<<<<
@@ -43222,7 +43204,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
   }
   __pyx_L5:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":715
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":720
  *                     return -1
  * 
  *         if loc2.arr[loc2.end-1] + len_last - loc1.arr[loc1.start] > self.train_max_initial_size:             # <<<<<<<<<<<<<<
@@ -43232,7 +43214,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
   __pyx_t_3 = ((((__pyx_v_loc2->arr[(__pyx_v_loc2->end - 1)]) + __pyx_v_len_last) - (__pyx_v_loc1->arr[__pyx_v_loc1->start])) > __pyx_v_self->train_max_initial_size);
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":716
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":721
  * 
  *         if loc2.arr[loc2.end-1] + len_last - loc1.arr[loc1.start] > self.train_max_initial_size:
  *             return -1             # <<<<<<<<<<<<<<
@@ -43245,7 +43227,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
   }
   __pyx_L17:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":717
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":722
  *         if loc2.arr[loc2.end-1] + len_last - loc1.arr[loc1.start] > self.train_max_initial_size:
  *             return -1
  *         return 0             # <<<<<<<<<<<<<<
@@ -43261,7 +43243,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":720
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":725
  * 
  * 
  *     cdef int* merge_helper(self, int low1, int high1, int* arr1, int step1,             # <<<<<<<<<<<<<<
@@ -43285,7 +43267,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
   int __pyx_t_3;
   __Pyx_RefNannySetupContext("merge_helper", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":728
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":733
  *         cdef Matching loc1, loc2
  * 
  *         result_len[0] = 0             # <<<<<<<<<<<<<<
@@ -43294,7 +43276,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
  */
   (__pyx_v_result_len[0]) = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":729
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":734
  * 
  *         result_len[0] = 0
  *         result = <int*> malloc(0*sizeof(int))             # <<<<<<<<<<<<<<
@@ -43303,7 +43285,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
  */
   __pyx_v_result = ((int *)malloc((0 * (sizeof(int)))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":731
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":736
  *         result = <int*> malloc(0*sizeof(int))
  * 
  *         i1 = low1             # <<<<<<<<<<<<<<
@@ -43312,7 +43294,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
  */
   __pyx_v_i1 = __pyx_v_low1;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":732
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":737
  * 
  *         i1 = low1
  *         i2 = low2             # <<<<<<<<<<<<<<
@@ -43321,7 +43303,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
  */
   __pyx_v_i2 = __pyx_v_low2;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":733
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":738
  *         i1 = low1
  *         i2 = low2
  *         while i1 < high1 and i2 < high2:             # <<<<<<<<<<<<<<
@@ -43338,7 +43320,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
     }
     if (!__pyx_t_3) break;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":736
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":741
  * 
  *             # First, pop all unneeded loc2's off the stack
  *             assign_matching(&loc1, arr1, i1, step1, self.fda.sent_id.arr)             # <<<<<<<<<<<<<<
@@ -43347,7 +43329,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
  */
     __pyx_f_3_sa_assign_matching((&__pyx_v_loc1), __pyx_v_arr1, __pyx_v_i1, __pyx_v_step1, __pyx_v_self->fda->sent_id->arr);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":737
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":742
  *             # First, pop all unneeded loc2's off the stack
  *             assign_matching(&loc1, arr1, i1, step1, self.fda.sent_id.arr)
  *             while i2 < high2:             # <<<<<<<<<<<<<<
@@ -43358,7 +43340,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
       __pyx_t_3 = (__pyx_v_i2 < __pyx_v_high2);
       if (!__pyx_t_3) break;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":738
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":743
  *             assign_matching(&loc1, arr1, i1, step1, self.fda.sent_id.arr)
  *             while i2 < high2:
  *                 assign_matching(&loc2, arr2, i2, step2, self.fda.sent_id.arr)             # <<<<<<<<<<<<<<
@@ -43367,7 +43349,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
  */
       __pyx_f_3_sa_assign_matching((&__pyx_v_loc2), __pyx_v_arr2, __pyx_v_i2, __pyx_v_step2, __pyx_v_self->fda->sent_id->arr);
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":739
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":744
  *             while i2 < high2:
  *                 assign_matching(&loc2, arr2, i2, step2, self.fda.sent_id.arr)
  *                 if self.compare_matchings(&loc1, &loc2, offset_by_one, len_last) == 1:             # <<<<<<<<<<<<<<
@@ -43377,7 +43359,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
       __pyx_t_3 = (((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->compare_matchings(__pyx_v_self, (&__pyx_v_loc1), (&__pyx_v_loc2), __pyx_v_offset_by_one, __pyx_v_len_last) == 1);
       if (__pyx_t_3) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":740
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":745
  *                 assign_matching(&loc2, arr2, i2, step2, self.fda.sent_id.arr)
  *                 if self.compare_matchings(&loc1, &loc2, offset_by_one, len_last) == 1:
  *                     i2 = i2 + step2             # <<<<<<<<<<<<<<
@@ -43389,7 +43371,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
       }
       /*else*/ {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":742
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":747
  *                     i2 = i2 + step2
  *                 else:
  *                     break             # <<<<<<<<<<<<<<
@@ -43402,7 +43384,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
     }
     __pyx_L6_break:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":745
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":750
  * 
  *             # Next: process all loc1's with the same starting val
  *             j1 = i1             # <<<<<<<<<<<<<<
@@ -43411,7 +43393,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
  */
     __pyx_v_j1 = __pyx_v_i1;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":746
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":751
  *             # Next: process all loc1's with the same starting val
  *             j1 = i1
  *             while i1 < high1 and arr1[j1] == arr1[i1]:             # <<<<<<<<<<<<<<
@@ -43428,7 +43410,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
       }
       if (!__pyx_t_2) break;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":747
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":752
  *             j1 = i1
  *             while i1 < high1 and arr1[j1] == arr1[i1]:
  *                 assign_matching(&loc1, arr1, i1, step1, self.fda.sent_id.arr)             # <<<<<<<<<<<<<<
@@ -43437,7 +43419,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
  */
       __pyx_f_3_sa_assign_matching((&__pyx_v_loc1), __pyx_v_arr1, __pyx_v_i1, __pyx_v_step1, __pyx_v_self->fda->sent_id->arr);
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":748
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":753
  *             while i1 < high1 and arr1[j1] == arr1[i1]:
  *                 assign_matching(&loc1, arr1, i1, step1, self.fda.sent_id.arr)
  *                 j2 = i2             # <<<<<<<<<<<<<<
@@ -43446,7 +43428,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
  */
       __pyx_v_j2 = __pyx_v_i2;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":749
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":754
  *                 assign_matching(&loc1, arr1, i1, step1, self.fda.sent_id.arr)
  *                 j2 = i2
  *                 while j2 < high2:             # <<<<<<<<<<<<<<
@@ -43457,7 +43439,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
         __pyx_t_2 = (__pyx_v_j2 < __pyx_v_high2);
         if (!__pyx_t_2) break;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":750
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":755
  *                 j2 = i2
  *                 while j2 < high2:
  *                     assign_matching(&loc2, arr2, j2, step2, self.fda.sent_id.arr)             # <<<<<<<<<<<<<<
@@ -43466,7 +43448,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
  */
         __pyx_f_3_sa_assign_matching((&__pyx_v_loc2), __pyx_v_arr2, __pyx_v_j2, __pyx_v_step2, __pyx_v_self->fda->sent_id->arr);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":751
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":756
  *                 while j2 < high2:
  *                     assign_matching(&loc2, arr2, j2, step2, self.fda.sent_id.arr)
  *                     comparison = self.compare_matchings(&loc1, &loc2, offset_by_one, len_last)             # <<<<<<<<<<<<<<
@@ -43475,7 +43457,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
  */
         __pyx_v_comparison = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->compare_matchings(__pyx_v_self, (&__pyx_v_loc1), (&__pyx_v_loc2), __pyx_v_offset_by_one, __pyx_v_len_last);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":752
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":757
  *                     assign_matching(&loc2, arr2, j2, step2, self.fda.sent_id.arr)
  *                     comparison = self.compare_matchings(&loc1, &loc2, offset_by_one, len_last)
  *                     if comparison == 0:             # <<<<<<<<<<<<<<
@@ -43485,7 +43467,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
         __pyx_t_2 = (__pyx_v_comparison == 0);
         if (__pyx_t_2) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":753
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":758
  *                     comparison = self.compare_matchings(&loc1, &loc2, offset_by_one, len_last)
  *                     if comparison == 0:
  *                         result = append_combined_matching(result, &loc1, &loc2, offset_by_one, num_subpatterns, result_len)             # <<<<<<<<<<<<<<
@@ -43497,7 +43479,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
         }
         __pyx_L12:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":754
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":759
  *                     if comparison == 0:
  *                         result = append_combined_matching(result, &loc1, &loc2, offset_by_one, num_subpatterns, result_len)
  *                     if comparison == 1:             # <<<<<<<<<<<<<<
@@ -43510,7 +43492,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
         }
         __pyx_L13:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":756
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":761
  *                     if comparison == 1:
  *                         pass
  *                     if comparison == -1:             # <<<<<<<<<<<<<<
@@ -43520,7 +43502,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
         __pyx_t_2 = (__pyx_v_comparison == -1);
         if (__pyx_t_2) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":757
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":762
  *                         pass
  *                     if comparison == -1:
  *                         break             # <<<<<<<<<<<<<<
@@ -43532,7 +43514,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
         }
         /*else*/ {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":759
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":764
  *                         break
  *                     else:
  *                         j2 = j2 + step2             # <<<<<<<<<<<<<<
@@ -43545,7 +43527,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
       }
       __pyx_L11_break:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":760
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":765
  *                     else:
  *                         j2 = j2 + step2
  *                 i1 = i1 + step1             # <<<<<<<<<<<<<<
@@ -43556,7 +43538,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
     }
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":761
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":766
  *                         j2 = j2 + step2
  *                 i1 = i1 + step1
  *         return result             # <<<<<<<<<<<<<<
@@ -43572,7 +43554,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":764
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":769
  * 
  * 
  *     cdef void sort_phrase_loc(self, IntList arr, PhraseLocation loc, Phrase phrase):             # <<<<<<<<<<<<<<
@@ -43594,26 +43576,26 @@ static void __pyx_f_3_sa_23HieroCachingRuleFactory_sort_phrase_loc(struct __pyx_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("sort_phrase_loc", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":769
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":774
  *         cdef IntList result
  * 
  *         if phrase in self.precomputed_index:             # <<<<<<<<<<<<<<
  *             loc.arr = self.precomputed_index[phrase]
  *         else:
  */
-  __pyx_t_1 = (__Pyx_PySequence_Contains(((PyObject *)__pyx_v_phrase), __pyx_v_self->precomputed_index, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 769; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = (__Pyx_PySequence_Contains(((PyObject *)__pyx_v_phrase), __pyx_v_self->precomputed_index, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 774; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   if (__pyx_t_1) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":770
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":775
  * 
  *         if phrase in self.precomputed_index:
  *             loc.arr = self.precomputed_index[phrase]             # <<<<<<<<<<<<<<
  *         else:
  *             loc.arr = IntList(initial_len=loc.sa_high-loc.sa_low)
  */
-    __pyx_t_2 = PyObject_GetItem(__pyx_v_self->precomputed_index, ((PyObject *)__pyx_v_phrase)); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 770; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyObject_GetItem(__pyx_v_self->precomputed_index, ((PyObject *)__pyx_v_phrase)); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 775; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_3_sa_IntList))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 770; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_3_sa_IntList))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 775; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GIVEREF(__pyx_t_2);
     __Pyx_GOTREF(__pyx_v_loc->arr);
     __Pyx_DECREF(((PyObject *)__pyx_v_loc->arr));
@@ -43623,20 +43605,20 @@ static void __pyx_f_3_sa_23HieroCachingRuleFactory_sort_phrase_loc(struct __pyx_
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":772
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":777
  *             loc.arr = self.precomputed_index[phrase]
  *         else:
  *             loc.arr = IntList(initial_len=loc.sa_high-loc.sa_low)             # <<<<<<<<<<<<<<
  *             veb = VEB(arr.len)
  *             for i from loc.sa_low <= i < loc.sa_high:
  */
-    __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 772; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 777; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(((PyObject *)__pyx_t_2));
-    __pyx_t_3 = PyInt_FromLong((__pyx_v_loc->sa_high - __pyx_v_loc->sa_low)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 772; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyInt_FromLong((__pyx_v_loc->sa_high - __pyx_v_loc->sa_low)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 777; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
-    if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__initial_len), __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 772; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__initial_len), __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 777; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_2)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 772; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_2)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 777; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
     __Pyx_GIVEREF(__pyx_t_3);
@@ -43645,27 +43627,27 @@ static void __pyx_f_3_sa_23HieroCachingRuleFactory_sort_phrase_loc(struct __pyx_
     __pyx_v_loc->arr = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_3);
     __pyx_t_3 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":773
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":778
  *         else:
  *             loc.arr = IntList(initial_len=loc.sa_high-loc.sa_low)
  *             veb = VEB(arr.len)             # <<<<<<<<<<<<<<
  *             for i from loc.sa_low <= i < loc.sa_high:
  *                 veb._insert(arr.arr[i])
  */
-    __pyx_t_3 = PyInt_FromLong(__pyx_v_arr->len); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 773; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyInt_FromLong(__pyx_v_arr->len); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 778; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 773; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 778; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_3);
     __Pyx_GIVEREF(__pyx_t_3);
     __pyx_t_3 = 0;
-    __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_VEB)), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 773; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_VEB)), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 778; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
     __pyx_v_veb = ((struct __pyx_obj_3_sa_VEB *)__pyx_t_3);
     __pyx_t_3 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":774
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":779
  *             loc.arr = IntList(initial_len=loc.sa_high-loc.sa_low)
  *             veb = VEB(arr.len)
  *             for i from loc.sa_low <= i < loc.sa_high:             # <<<<<<<<<<<<<<
@@ -43675,7 +43657,7 @@ static void __pyx_f_3_sa_23HieroCachingRuleFactory_sort_phrase_loc(struct __pyx_
     __pyx_t_4 = __pyx_v_loc->sa_high;
     for (__pyx_v_i = __pyx_v_loc->sa_low; __pyx_v_i < __pyx_t_4; __pyx_v_i++) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":775
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":780
  *             veb = VEB(arr.len)
  *             for i from loc.sa_low <= i < loc.sa_high:
  *                 veb._insert(arr.arr[i])             # <<<<<<<<<<<<<<
@@ -43685,7 +43667,7 @@ static void __pyx_f_3_sa_23HieroCachingRuleFactory_sort_phrase_loc(struct __pyx_
       ((struct __pyx_vtabstruct_3_sa_VEB *)__pyx_v_veb->__pyx_vtab)->_insert(__pyx_v_veb, (__pyx_v_arr->arr[__pyx_v_i]));
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":776
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":781
  *             for i from loc.sa_low <= i < loc.sa_high:
  *                 veb._insert(arr.arr[i])
  *             i = veb.veb.min_val             # <<<<<<<<<<<<<<
@@ -43694,7 +43676,7 @@ static void __pyx_f_3_sa_23HieroCachingRuleFactory_sort_phrase_loc(struct __pyx_
  */
     __pyx_v_i = __pyx_v_veb->veb->min_val;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":777
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":782
  *                 veb._insert(arr.arr[i])
  *             i = veb.veb.min_val
  *             for j from 0 <= j < loc.sa_high-loc.sa_low:             # <<<<<<<<<<<<<<
@@ -43704,7 +43686,7 @@ static void __pyx_f_3_sa_23HieroCachingRuleFactory_sort_phrase_loc(struct __pyx_
     __pyx_t_4 = (__pyx_v_loc->sa_high - __pyx_v_loc->sa_low);
     for (__pyx_v_j = 0; __pyx_v_j < __pyx_t_4; __pyx_v_j++) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":778
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":783
  *             i = veb.veb.min_val
  *             for j from 0 <= j < loc.sa_high-loc.sa_low:
  *                 loc.arr.arr[j] = i             # <<<<<<<<<<<<<<
@@ -43713,7 +43695,7 @@ static void __pyx_f_3_sa_23HieroCachingRuleFactory_sort_phrase_loc(struct __pyx_
  */
       (__pyx_v_loc->arr->arr[__pyx_v_j]) = __pyx_v_i;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":779
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":784
  *             for j from 0 <= j < loc.sa_high-loc.sa_low:
  *                 loc.arr.arr[j] = i
  *                 i = veb._findsucc(i)             # <<<<<<<<<<<<<<
@@ -43725,7 +43707,7 @@ static void __pyx_f_3_sa_23HieroCachingRuleFactory_sort_phrase_loc(struct __pyx_
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":780
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":785
  *                 loc.arr.arr[j] = i
  *                 i = veb._findsucc(i)
  *         loc.arr_low = 0             # <<<<<<<<<<<<<<
@@ -43734,7 +43716,7 @@ static void __pyx_f_3_sa_23HieroCachingRuleFactory_sort_phrase_loc(struct __pyx_
  */
   __pyx_v_loc->arr_low = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":781
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":786
  *                 i = veb._findsucc(i)
  *         loc.arr_low = 0
  *         loc.arr_high = loc.arr.len             # <<<<<<<<<<<<<<
@@ -43753,7 +43735,7 @@ static void __pyx_f_3_sa_23HieroCachingRuleFactory_sort_phrase_loc(struct __pyx_
   __Pyx_RefNannyFinishContext();
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":784
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":789
  * 
  * 
  *     cdef intersect_helper(self, Phrase prefix, Phrase suffix,             # <<<<<<<<<<<<<<
@@ -43790,7 +43772,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("intersect_helper", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":791
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":796
  *         cdef int* result_ptr
  * 
  *         result_len = 0             # <<<<<<<<<<<<<<
@@ -43799,21 +43781,21 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
  */
   __pyx_v_result_len = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":793
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":798
  *         result_len = 0
  * 
  *         if sym_isvar(suffix[0]):             # <<<<<<<<<<<<<<
  *             offset_by_one = 1
  *         else:
  */
-  __pyx_t_1 = __Pyx_GetItemInt(((PyObject *)__pyx_v_suffix), 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 793; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetItemInt(((PyObject *)__pyx_v_suffix), 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 793; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_t_3 = __pyx_f_3_sa_sym_isvar(__pyx_t_2);
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":794
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":799
  * 
  *         if sym_isvar(suffix[0]):
  *             offset_by_one = 1             # <<<<<<<<<<<<<<
@@ -43825,7 +43807,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":796
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":801
  *             offset_by_one = 1
  *         else:
  *             offset_by_one = 0             # <<<<<<<<<<<<<<
@@ -43836,34 +43818,34 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":798
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":803
  *             offset_by_one = 0
  * 
  *         len_last = len(suffix.getchunk(suffix.arity()))             # <<<<<<<<<<<<<<
  * 
  *         if prefix_loc.arr is None:
  */
-  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_suffix), __pyx_n_s__getchunk); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_suffix), __pyx_n_s__getchunk); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_4 = PyObject_GetAttr(((PyObject *)__pyx_v_suffix), __pyx_n_s__arity); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyObject_GetAttr(((PyObject *)__pyx_v_suffix), __pyx_n_s__arity); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
   PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_5);
   __Pyx_GIVEREF(__pyx_t_5);
   __pyx_t_5 = 0;
-  __pyx_t_5 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
-  __pyx_t_6 = PyObject_Length(__pyx_t_5); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_6 = PyObject_Length(__pyx_t_5); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_v_len_last = __pyx_t_6;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":800
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":805
  *         len_last = len(suffix.getchunk(suffix.arity()))
  * 
  *         if prefix_loc.arr is None:             # <<<<<<<<<<<<<<
@@ -43873,7 +43855,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
   __pyx_t_7 = (((PyObject *)__pyx_v_prefix_loc->arr) == Py_None);
   if (__pyx_t_7) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":801
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":806
  * 
  *         if prefix_loc.arr is None:
  *             self.sort_phrase_loc(self.fsa.sa, prefix_loc, prefix)             # <<<<<<<<<<<<<<
@@ -43888,7 +43870,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
   }
   __pyx_L4:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":802
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":807
  *         if prefix_loc.arr is None:
  *             self.sort_phrase_loc(self.fsa.sa, prefix_loc, prefix)
  *         arr1 = prefix_loc.arr             # <<<<<<<<<<<<<<
@@ -43898,7 +43880,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
   __Pyx_INCREF(((PyObject *)__pyx_v_prefix_loc->arr));
   __pyx_v_arr1 = __pyx_v_prefix_loc->arr;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":803
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":808
  *             self.sort_phrase_loc(self.fsa.sa, prefix_loc, prefix)
  *         arr1 = prefix_loc.arr
  *         low1 = prefix_loc.arr_low             # <<<<<<<<<<<<<<
@@ -43907,7 +43889,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
  */
   __pyx_v_low1 = __pyx_v_prefix_loc->arr_low;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":804
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":809
  *         arr1 = prefix_loc.arr
  *         low1 = prefix_loc.arr_low
  *         high1 = prefix_loc.arr_high             # <<<<<<<<<<<<<<
@@ -43916,7 +43898,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
  */
   __pyx_v_high1 = __pyx_v_prefix_loc->arr_high;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":805
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":810
  *         low1 = prefix_loc.arr_low
  *         high1 = prefix_loc.arr_high
  *         step1 = prefix_loc.num_subpatterns             # <<<<<<<<<<<<<<
@@ -43925,7 +43907,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
  */
   __pyx_v_step1 = __pyx_v_prefix_loc->num_subpatterns;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":807
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":812
  *         step1 = prefix_loc.num_subpatterns
  * 
  *         if suffix_loc.arr is None:             # <<<<<<<<<<<<<<
@@ -43935,7 +43917,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
   __pyx_t_7 = (((PyObject *)__pyx_v_suffix_loc->arr) == Py_None);
   if (__pyx_t_7) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":808
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":813
  * 
  *         if suffix_loc.arr is None:
  *             self.sort_phrase_loc(self.fsa.sa, suffix_loc, suffix)             # <<<<<<<<<<<<<<
@@ -43950,7 +43932,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
   }
   __pyx_L5:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":809
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":814
  *         if suffix_loc.arr is None:
  *             self.sort_phrase_loc(self.fsa.sa, suffix_loc, suffix)
  *         arr2 = suffix_loc.arr             # <<<<<<<<<<<<<<
@@ -43960,7 +43942,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
   __Pyx_INCREF(((PyObject *)__pyx_v_suffix_loc->arr));
   __pyx_v_arr2 = __pyx_v_suffix_loc->arr;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":810
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":815
  *             self.sort_phrase_loc(self.fsa.sa, suffix_loc, suffix)
  *         arr2 = suffix_loc.arr
  *         low2 = suffix_loc.arr_low             # <<<<<<<<<<<<<<
@@ -43969,7 +43951,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
  */
   __pyx_v_low2 = __pyx_v_suffix_loc->arr_low;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":811
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":816
  *         arr2 = suffix_loc.arr
  *         low2 = suffix_loc.arr_low
  *         high2 = suffix_loc.arr_high             # <<<<<<<<<<<<<<
@@ -43978,7 +43960,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
  */
   __pyx_v_high2 = __pyx_v_suffix_loc->arr_high;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":812
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":817
  *         low2 = suffix_loc.arr_low
  *         high2 = suffix_loc.arr_high
  *         step2 = suffix_loc.num_subpatterns             # <<<<<<<<<<<<<<
@@ -43987,26 +43969,26 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
  */
   __pyx_v_step2 = __pyx_v_suffix_loc->num_subpatterns;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":814
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":819
  *         step2 = suffix_loc.num_subpatterns
  * 
  *         num_subpatterns = prefix.arity()+1             # <<<<<<<<<<<<<<
  * 
  *         if algorithm == MERGE:
  */
-  __pyx_t_5 = PyObject_GetAttr(((PyObject *)__pyx_v_prefix), __pyx_n_s__arity); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 814; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = PyObject_GetAttr(((PyObject *)__pyx_v_prefix), __pyx_n_s__arity); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 819; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_4 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 814; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 819; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = PyNumber_Add(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 814; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = PyNumber_Add(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 819; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_3 = __Pyx_PyInt_AsInt(__pyx_t_5); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 814; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = __Pyx_PyInt_AsInt(__pyx_t_5); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 819; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_v_num_subpatterns = __pyx_t_3;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":816
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":821
  *         num_subpatterns = prefix.arity()+1
  * 
  *         if algorithm == MERGE:             # <<<<<<<<<<<<<<
@@ -44016,7 +43998,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
   __pyx_t_7 = (__pyx_v_algorithm == __pyx_v_3_sa_MERGE);
   if (__pyx_t_7) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":819
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":824
  *             result_ptr = self.merge_helper(low1, high1, arr1.arr, step1,
  *                                     low2, high2, arr2.arr, step2,
  *                                     offset_by_one, len_last, num_subpatterns, &result_len)             # <<<<<<<<<<<<<<
@@ -44028,7 +44010,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":823
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":828
  *             result_ptr = self.baeza_yates_helper(low1, high1, arr1.arr, step1,
  *                                     low2, high2, arr2.arr, step2,
  *                                     offset_by_one, len_last, num_subpatterns, &result_len)             # <<<<<<<<<<<<<<
@@ -44039,7 +44021,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
   }
   __pyx_L6:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":825
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":830
  *                                     offset_by_one, len_last, num_subpatterns, &result_len)
  * 
  *         if result_len == 0:             # <<<<<<<<<<<<<<
@@ -44049,7 +44031,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
   __pyx_t_7 = (__pyx_v_result_len == 0);
   if (__pyx_t_7) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":826
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":831
  * 
  *         if result_len == 0:
  *             free(result_ptr)             # <<<<<<<<<<<<<<
@@ -44058,7 +44040,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
  */
     free(__pyx_v_result_ptr);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":827
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":832
  *         if result_len == 0:
  *             free(result_ptr)
  *             return None             # <<<<<<<<<<<<<<
@@ -44073,19 +44055,19 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":829
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":834
  *             return None
  *         else:
  *             result = IntList()             # <<<<<<<<<<<<<<
  *             free(result.arr)
  *             result.arr = result_ptr
  */
-    __pyx_t_5 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __pyx_v_result = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_5);
     __pyx_t_5 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":830
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":835
  *         else:
  *             result = IntList()
  *             free(result.arr)             # <<<<<<<<<<<<<<
@@ -44094,7 +44076,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
  */
     free(__pyx_v_result->arr);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":831
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":836
  *             result = IntList()
  *             free(result.arr)
  *             result.arr = result_ptr             # <<<<<<<<<<<<<<
@@ -44103,7 +44085,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
  */
     __pyx_v_result->arr = __pyx_v_result_ptr;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":832
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":837
  *             free(result.arr)
  *             result.arr = result_ptr
  *             result.len = result_len             # <<<<<<<<<<<<<<
@@ -44112,7 +44094,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
  */
     __pyx_v_result->len = __pyx_v_result_len;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":833
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":838
  *             result.arr = result_ptr
  *             result.len = result_len
  *             result.size = result_len             # <<<<<<<<<<<<<<
@@ -44121,7 +44103,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
  */
     __pyx_v_result->size = __pyx_v_result_len;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":834
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":839
  *             result.len = result_len
  *             result.size = result_len
  *             return PhraseLocation(arr_low=0, arr_high=result_len, arr=result, num_subpatterns=num_subpatterns)             # <<<<<<<<<<<<<<
@@ -44129,19 +44111,19 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
  *     cdef loc2str(self, PhraseLocation loc):
  */
     __Pyx_XDECREF(__pyx_r);
-    __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(((PyObject *)__pyx_t_5));
-    if (PyDict_SetItem(__pyx_t_5, ((PyObject *)__pyx_n_s__arr_low), __pyx_int_0) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_4 = PyInt_FromLong(__pyx_v_result_len); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyDict_SetItem(__pyx_t_5, ((PyObject *)__pyx_n_s__arr_low), __pyx_int_0) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyInt_FromLong(__pyx_v_result_len); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    if (PyDict_SetItem(__pyx_t_5, ((PyObject *)__pyx_n_s__arr_high), __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyDict_SetItem(__pyx_t_5, ((PyObject *)__pyx_n_s__arr_high), __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (PyDict_SetItem(__pyx_t_5, ((PyObject *)__pyx_n_s__arr), ((PyObject *)__pyx_v_result)) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_4 = PyInt_FromLong(__pyx_v_num_subpatterns); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyDict_SetItem(__pyx_t_5, ((PyObject *)__pyx_n_s__arr), ((PyObject *)__pyx_v_result)) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyInt_FromLong(__pyx_v_num_subpatterns); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    if (PyDict_SetItem(__pyx_t_5, ((PyObject *)__pyx_n_s__num_subpatterns), __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyDict_SetItem(__pyx_t_5, ((PyObject *)__pyx_n_s__num_subpatterns), __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_PhraseLocation)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_5)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_PhraseLocation)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_5)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
     __pyx_r = __pyx_t_4;
@@ -44167,7 +44149,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":836
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":841
  *             return PhraseLocation(arr_low=0, arr_high=result_len, arr=result, num_subpatterns=num_subpatterns)
  * 
  *     cdef loc2str(self, PhraseLocation loc):             # <<<<<<<<<<<<<<
@@ -44190,7 +44172,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_loc2str(CYTHON_UNUSED st
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("loc2str", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":838
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":843
  *     cdef loc2str(self, PhraseLocation loc):
  *         cdef int i, j
  *         result = "{"             # <<<<<<<<<<<<<<
@@ -44200,7 +44182,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_loc2str(CYTHON_UNUSED st
   __Pyx_INCREF(((PyObject *)__pyx_kp_s_116));
   __pyx_v_result = ((PyObject *)__pyx_kp_s_116);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":839
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":844
  *         cdef int i, j
  *         result = "{"
  *         i = 0             # <<<<<<<<<<<<<<
@@ -44209,7 +44191,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_loc2str(CYTHON_UNUSED st
  */
   __pyx_v_i = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":840
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":845
  *         result = "{"
  *         i = 0
  *         while i < loc.arr_high:             # <<<<<<<<<<<<<<
@@ -44220,20 +44202,20 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_loc2str(CYTHON_UNUSED st
     __pyx_t_1 = (__pyx_v_i < __pyx_v_loc->arr_high);
     if (!__pyx_t_1) break;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":841
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":846
  *         i = 0
  *         while i < loc.arr_high:
  *             result = result + "("             # <<<<<<<<<<<<<<
  *             for j from i <= j < i + loc.num_subpatterns:
  *                 result = result + ("%d " %loc.arr[j])
  */
-    __pyx_t_2 = PyNumber_Add(__pyx_v_result, ((PyObject *)__pyx_kp_s_117)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyNumber_Add(__pyx_v_result, ((PyObject *)__pyx_kp_s_117)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 846; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_v_result);
     __pyx_v_result = __pyx_t_2;
     __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":842
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":847
  *         while i < loc.arr_high:
  *             result = result + "("
  *             for j from i <= j < i + loc.num_subpatterns:             # <<<<<<<<<<<<<<
@@ -44243,19 +44225,19 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_loc2str(CYTHON_UNUSED st
     __pyx_t_3 = (__pyx_v_i + __pyx_v_loc->num_subpatterns);
     for (__pyx_v_j = __pyx_v_i; __pyx_v_j < __pyx_t_3; __pyx_v_j++) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":843
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":848
  *             result = result + "("
  *             for j from i <= j < i + loc.num_subpatterns:
  *                 result = result + ("%d " %loc.arr[j])             # <<<<<<<<<<<<<<
  *             result = result + ")"
  *             i = i + loc.num_subpatterns
  */
-      __pyx_t_2 = __Pyx_GetItemInt(((PyObject *)__pyx_v_loc->arr), __pyx_v_j, sizeof(int), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 843; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(((PyObject *)__pyx_v_loc->arr), __pyx_v_j, sizeof(int), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 848; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_4 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_21), __pyx_t_2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 843; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_21), __pyx_t_2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 848; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(((PyObject *)__pyx_t_4));
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_2 = PyNumber_Add(__pyx_v_result, ((PyObject *)__pyx_t_4)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 843; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_Add(__pyx_v_result, ((PyObject *)__pyx_t_4)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 848; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
       __Pyx_DECREF(__pyx_v_result);
@@ -44263,20 +44245,20 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_loc2str(CYTHON_UNUSED st
       __pyx_t_2 = 0;
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":844
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":849
  *             for j from i <= j < i + loc.num_subpatterns:
  *                 result = result + ("%d " %loc.arr[j])
  *             result = result + ")"             # <<<<<<<<<<<<<<
  *             i = i + loc.num_subpatterns
  *         result = result + "}"
  */
-    __pyx_t_2 = PyNumber_Add(__pyx_v_result, ((PyObject *)__pyx_kp_s_59)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyNumber_Add(__pyx_v_result, ((PyObject *)__pyx_kp_s_59)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 849; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_v_result);
     __pyx_v_result = __pyx_t_2;
     __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":845
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":850
  *                 result = result + ("%d " %loc.arr[j])
  *             result = result + ")"
  *             i = i + loc.num_subpatterns             # <<<<<<<<<<<<<<
@@ -44286,20 +44268,20 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_loc2str(CYTHON_UNUSED st
     __pyx_v_i = (__pyx_v_i + __pyx_v_loc->num_subpatterns);
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":846
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":851
  *             result = result + ")"
  *             i = i + loc.num_subpatterns
  *         result = result + "}"             # <<<<<<<<<<<<<<
  *         return result
  * 
  */
-  __pyx_t_2 = PyNumber_Add(__pyx_v_result, ((PyObject *)__pyx_kp_s_118)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 846; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyNumber_Add(__pyx_v_result, ((PyObject *)__pyx_kp_s_118)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 851; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_v_result);
   __pyx_v_result = __pyx_t_2;
   __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":847
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":852
  *             i = i + loc.num_subpatterns
  *         result = result + "}"
  *         return result             # <<<<<<<<<<<<<<
@@ -44325,7 +44307,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_loc2str(CYTHON_UNUSED st
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":849
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":854
  *         return result
  * 
  *     cdef PhraseLocation intersect(self, prefix_node, suffix_node, Phrase phrase):             # <<<<<<<<<<<<<<
@@ -44351,81 +44333,81 @@ static struct __pyx_obj_3_sa_PhraseLocation *__pyx_f_3_sa_23HieroCachingRuleFact
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("intersect", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":853
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":858
  *         cdef PhraseLocation prefix_loc, suffix_loc, result
  * 
  *         prefix = prefix_node.phrase             # <<<<<<<<<<<<<<
  *         suffix = suffix_node.phrase
  *         prefix_loc = prefix_node.phrase_location
  */
-  __pyx_t_1 = PyObject_GetAttr(__pyx_v_prefix_node, __pyx_n_s__phrase); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_GetAttr(__pyx_v_prefix_node, __pyx_n_s__phrase); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 858; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_3_sa_Phrase))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_3_sa_Phrase))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 858; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_v_prefix = ((struct __pyx_obj_3_sa_Phrase *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":854
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":859
  * 
  *         prefix = prefix_node.phrase
  *         suffix = suffix_node.phrase             # <<<<<<<<<<<<<<
  *         prefix_loc = prefix_node.phrase_location
  *         suffix_loc = suffix_node.phrase_location
  */
-  __pyx_t_1 = PyObject_GetAttr(__pyx_v_suffix_node, __pyx_n_s__phrase); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 854; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_GetAttr(__pyx_v_suffix_node, __pyx_n_s__phrase); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 859; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_3_sa_Phrase))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 854; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_3_sa_Phrase))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 859; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_v_suffix = ((struct __pyx_obj_3_sa_Phrase *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":855
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":860
  *         prefix = prefix_node.phrase
  *         suffix = suffix_node.phrase
  *         prefix_loc = prefix_node.phrase_location             # <<<<<<<<<<<<<<
  *         suffix_loc = suffix_node.phrase_location
  * 
  */
-  __pyx_t_1 = PyObject_GetAttr(__pyx_v_prefix_node, __pyx_n_s__phrase_location); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_GetAttr(__pyx_v_prefix_node, __pyx_n_s__phrase_location); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 860; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_3_sa_PhraseLocation))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_3_sa_PhraseLocation))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 860; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_v_prefix_loc = ((struct __pyx_obj_3_sa_PhraseLocation *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":856
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":861
  *         suffix = suffix_node.phrase
  *         prefix_loc = prefix_node.phrase_location
  *         suffix_loc = suffix_node.phrase_location             # <<<<<<<<<<<<<<
  * 
  *         result = self.get_precomputed_collocation(phrase)
  */
-  __pyx_t_1 = PyObject_GetAttr(__pyx_v_suffix_node, __pyx_n_s__phrase_location); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 856; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_GetAttr(__pyx_v_suffix_node, __pyx_n_s__phrase_location); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_3_sa_PhraseLocation))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 856; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_3_sa_PhraseLocation))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_v_suffix_loc = ((struct __pyx_obj_3_sa_PhraseLocation *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":858
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":863
  *         suffix_loc = suffix_node.phrase_location
  * 
  *         result = self.get_precomputed_collocation(phrase)             # <<<<<<<<<<<<<<
  *         if result is not None:
  *             intersect_method = "precomputed"
  */
-  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s_119); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 858; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s_119); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 863; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 858; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 863; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_INCREF(((PyObject *)__pyx_v_phrase));
   PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_v_phrase));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_phrase));
-  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 858; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 863; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
-  if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_3_sa_PhraseLocation))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 858; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_3_sa_PhraseLocation))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 863; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_v_result = ((struct __pyx_obj_3_sa_PhraseLocation *)__pyx_t_3);
   __pyx_t_3 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":859
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":864
  * 
  *         result = self.get_precomputed_collocation(phrase)
  *         if result is not None:             # <<<<<<<<<<<<<<
@@ -44435,7 +44417,7 @@ static struct __pyx_obj_3_sa_PhraseLocation *__pyx_f_3_sa_23HieroCachingRuleFact
   __pyx_t_4 = (((PyObject *)__pyx_v_result) != Py_None);
   if (__pyx_t_4) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":860
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":865
  *         result = self.get_precomputed_collocation(phrase)
  *         if result is not None:
  *             intersect_method = "precomputed"             # <<<<<<<<<<<<<<
@@ -44448,7 +44430,7 @@ static struct __pyx_obj_3_sa_PhraseLocation *__pyx_f_3_sa_23HieroCachingRuleFact
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":862
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":867
  *             intersect_method = "precomputed"
  * 
  *         if result is None:             # <<<<<<<<<<<<<<
@@ -44458,7 +44440,7 @@ static struct __pyx_obj_3_sa_PhraseLocation *__pyx_f_3_sa_23HieroCachingRuleFact
   __pyx_t_4 = (((PyObject *)__pyx_v_result) == Py_None);
   if (__pyx_t_4) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":863
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":868
  * 
  *         if result is None:
  *             if self.use_baeza_yates:             # <<<<<<<<<<<<<<
@@ -44467,21 +44449,21 @@ static struct __pyx_obj_3_sa_PhraseLocation *__pyx_f_3_sa_23HieroCachingRuleFact
  */
     if (__pyx_v_self->use_baeza_yates) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":864
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":869
  *         if result is None:
  *             if self.use_baeza_yates:
  *                 result = self.intersect_helper(prefix, suffix, prefix_loc, suffix_loc, BAEZA_YATES)             # <<<<<<<<<<<<<<
  *                 intersect_method="double binary"
  *             else:
  */
-      __pyx_t_3 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->intersect_helper(__pyx_v_self, __pyx_v_prefix, __pyx_v_suffix, __pyx_v_prefix_loc, __pyx_v_suffix_loc, __pyx_v_3_sa_BAEZA_YATES); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 864; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->intersect_helper(__pyx_v_self, __pyx_v_prefix, __pyx_v_suffix, __pyx_v_prefix_loc, __pyx_v_suffix_loc, __pyx_v_3_sa_BAEZA_YATES); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 869; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
-      if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_3_sa_PhraseLocation))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 864; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_3_sa_PhraseLocation))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 869; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(((PyObject *)__pyx_v_result));
       __pyx_v_result = ((struct __pyx_obj_3_sa_PhraseLocation *)__pyx_t_3);
       __pyx_t_3 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":865
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":870
  *             if self.use_baeza_yates:
  *                 result = self.intersect_helper(prefix, suffix, prefix_loc, suffix_loc, BAEZA_YATES)
  *                 intersect_method="double binary"             # <<<<<<<<<<<<<<
@@ -44495,21 +44477,21 @@ static struct __pyx_obj_3_sa_PhraseLocation *__pyx_f_3_sa_23HieroCachingRuleFact
     }
     /*else*/ {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":867
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":872
  *                 intersect_method="double binary"
  *             else:
  *                 result = self.intersect_helper(prefix, suffix, prefix_loc, suffix_loc, MERGE)             # <<<<<<<<<<<<<<
  *                 intersect_method="merge"
  *         return result
  */
-      __pyx_t_3 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->intersect_helper(__pyx_v_self, __pyx_v_prefix, __pyx_v_suffix, __pyx_v_prefix_loc, __pyx_v_suffix_loc, __pyx_v_3_sa_MERGE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 867; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->intersect_helper(__pyx_v_self, __pyx_v_prefix, __pyx_v_suffix, __pyx_v_prefix_loc, __pyx_v_suffix_loc, __pyx_v_3_sa_MERGE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 872; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
-      if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_3_sa_PhraseLocation))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 867; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_3_sa_PhraseLocation))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 872; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(((PyObject *)__pyx_v_result));
       __pyx_v_result = ((struct __pyx_obj_3_sa_PhraseLocation *)__pyx_t_3);
       __pyx_t_3 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":868
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":873
  *             else:
  *                 result = self.intersect_helper(prefix, suffix, prefix_loc, suffix_loc, MERGE)
  *                 intersect_method="merge"             # <<<<<<<<<<<<<<
@@ -44525,7 +44507,7 @@ static struct __pyx_obj_3_sa_PhraseLocation *__pyx_f_3_sa_23HieroCachingRuleFact
   }
   __pyx_L4:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":869
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":874
  *                 result = self.intersect_helper(prefix, suffix, prefix_loc, suffix_loc, MERGE)
  *                 intersect_method="merge"
  *         return result             # <<<<<<<<<<<<<<
@@ -44587,16 +44569,16 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_13advance(PyObject *__p
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__res)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("advance", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 871; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("advance", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 876; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__fwords)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("advance", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 871; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("advance", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 876; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "advance") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 871; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "advance") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 876; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
       goto __pyx_L5_argtuple_error;
@@ -44611,7 +44593,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_13advance(PyObject *__p
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("advance", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 871; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("advance", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 876; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.advance", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -44622,7 +44604,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_13advance(PyObject *__p
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":871
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":876
  *         return result
  * 
  *     def advance(self, frontier, res, fwords):             # <<<<<<<<<<<<<<
@@ -44663,19 +44645,19 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("advance", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":873
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":878
  *     def advance(self, frontier, res, fwords):
  *         cdef unsigned na
  *         nf = []             # <<<<<<<<<<<<<<
  *         for (toskip, (i, alt, pathlen)) in frontier:
  *             spanlen = fwords[i][alt][2]
  */
-  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 873; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 878; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_nf = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":874
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":879
  *         cdef unsigned na
  *         nf = []
  *         for (toskip, (i, alt, pathlen)) in frontier:             # <<<<<<<<<<<<<<
@@ -44686,7 +44668,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
     __pyx_t_1 = __pyx_v_frontier; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
     __pyx_t_3 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_frontier); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_frontier); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -44694,23 +44676,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
     if (!__pyx_t_3 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_3 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_4 = __pyx_t_3(__pyx_t_1);
       if (unlikely(!__pyx_t_4)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -44726,7 +44708,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
       if (unlikely(size != 2)) {
         if (size > 2) __Pyx_RaiseTooManyValuesError(2);
         else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       }
       #if CYTHON_COMPILING_IN_CPYTHON
       if (likely(PyTuple_CheckExact(sequence))) {
@@ -44739,14 +44721,14 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
       __Pyx_INCREF(__pyx_t_5);
       __Pyx_INCREF(__pyx_t_6);
       #else
-      __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     } else
     {
       Py_ssize_t index = -1;
-      __pyx_t_7 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __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;
@@ -44754,7 +44736,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
       __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_filename = __pyx_f[8]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_t_8 = NULL;
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       goto __pyx_L6_unpacking_done;
@@ -44762,7 +44744,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       __pyx_t_8 = NULL;
       if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_L6_unpacking_done:;
     }
     __Pyx_XDECREF(__pyx_v_toskip);
@@ -44778,7 +44760,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
       if (unlikely(size != 3)) {
         if (size > 3) __Pyx_RaiseTooManyValuesError(3);
         else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       }
       #if CYTHON_COMPILING_IN_CPYTHON
       if (likely(PyTuple_CheckExact(sequence))) {
@@ -44794,15 +44776,15 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
       __Pyx_INCREF(__pyx_t_9);
       __Pyx_INCREF(__pyx_t_10);
       #else
-      __pyx_t_7 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_9 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_10 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_9 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_10 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     } else
     {
       Py_ssize_t index = -1;
-      __pyx_t_11 = PyObject_GetIter(__pyx_t_6); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_11 = PyObject_GetIter(__pyx_t_6); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_11);
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       __pyx_t_8 = Py_TYPE(__pyx_t_11)->tp_iternext;
@@ -44812,7 +44794,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
       __Pyx_GOTREF(__pyx_t_9);
       index = 2; __pyx_t_10 = __pyx_t_8(__pyx_t_11); if (unlikely(!__pyx_t_10)) goto __pyx_L7_unpacking_failed;
       __Pyx_GOTREF(__pyx_t_10);
-      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_11), 3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_11), 3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_t_8 = NULL;
       __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
       goto __pyx_L8_unpacking_done;
@@ -44820,7 +44802,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
       __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
       __pyx_t_8 = NULL;
       if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_L8_unpacking_done:;
     }
     __Pyx_XDECREF(__pyx_v_i);
@@ -44833,45 +44815,45 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
     __pyx_v_pathlen = __pyx_t_10;
     __pyx_t_10 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":875
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":880
  *         nf = []
  *         for (toskip, (i, alt, pathlen)) in frontier:
  *             spanlen = fwords[i][alt][2]             # <<<<<<<<<<<<<<
  *             if (toskip == 0):
  *                 res.append((i, alt, pathlen))
  */
-    __pyx_t_4 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_i); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 875; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_i); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = PyObject_GetItem(__pyx_t_4, __pyx_v_alt); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 875; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyObject_GetItem(__pyx_t_4, __pyx_v_alt); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_6, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 875; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_6, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_XDECREF(__pyx_v_spanlen);
     __pyx_v_spanlen = __pyx_t_4;
     __pyx_t_4 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":876
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":881
  *         for (toskip, (i, alt, pathlen)) in frontier:
  *             spanlen = fwords[i][alt][2]
  *             if (toskip == 0):             # <<<<<<<<<<<<<<
  *                 res.append((i, alt, pathlen))
  *             ni = i + spanlen
  */
-    __pyx_t_4 = PyObject_RichCompare(__pyx_v_toskip, __pyx_int_0, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 876; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_12 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_12 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 876; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_RichCompare(__pyx_v_toskip, __pyx_int_0, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_12 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_12 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     if (__pyx_t_12) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":877
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":882
  *             spanlen = fwords[i][alt][2]
  *             if (toskip == 0):
  *                 res.append((i, alt, pathlen))             # <<<<<<<<<<<<<<
  *             ni = i + spanlen
  *             if (ni < len(fwords) and (pathlen + 1) < self.max_initial_size):
  */
-      __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 877; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 882; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_INCREF(__pyx_v_i);
       PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_i);
@@ -44882,7 +44864,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
       __Pyx_INCREF(__pyx_v_pathlen);
       PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_v_pathlen);
       __Pyx_GIVEREF(__pyx_v_pathlen);
-      __pyx_t_6 = __Pyx_PyObject_Append(__pyx_v_res, ((PyObject *)__pyx_t_4)); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 877; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyObject_Append(__pyx_v_res, ((PyObject *)__pyx_t_4)); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 882; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_6);
       __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
@@ -44890,42 +44872,42 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
     }
     __pyx_L9:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":878
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":883
  *             if (toskip == 0):
  *                 res.append((i, alt, pathlen))
  *             ni = i + spanlen             # <<<<<<<<<<<<<<
  *             if (ni < len(fwords) and (pathlen + 1) < self.max_initial_size):
  *                 for na in range(len(fwords[ni])):
  */
-    __pyx_t_6 = PyNumber_Add(__pyx_v_i, __pyx_v_spanlen); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 878; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyNumber_Add(__pyx_v_i, __pyx_v_spanlen); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 883; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_XDECREF(__pyx_v_ni);
     __pyx_v_ni = __pyx_t_6;
     __pyx_t_6 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":879
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":884
  *                 res.append((i, alt, pathlen))
  *             ni = i + spanlen
  *             if (ni < len(fwords) and (pathlen + 1) < self.max_initial_size):             # <<<<<<<<<<<<<<
  *                 for na in range(len(fwords[ni])):
  *                     nf.append((toskip - 1, (ni, na, pathlen + 1)))
  */
-    __pyx_t_13 = PyObject_Length(__pyx_v_fwords); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_6 = PyInt_FromSsize_t(__pyx_t_13); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_13 = PyObject_Length(__pyx_v_fwords); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 884; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyInt_FromSsize_t(__pyx_t_13); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 884; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_4 = PyObject_RichCompare(__pyx_v_ni, __pyx_t_6, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_RichCompare(__pyx_v_ni, __pyx_t_6, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 884; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_12 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_12 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_12 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_12 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 884; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     if (__pyx_t_12) {
-      __pyx_t_4 = PyNumber_Add(__pyx_v_pathlen, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyNumber_Add(__pyx_v_pathlen, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 884; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_6 = PyInt_FromLong(__pyx_v_self->max_initial_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PyInt_FromLong(__pyx_v_self->max_initial_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 884; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_6);
-      __pyx_t_5 = PyObject_RichCompare(__pyx_t_4, __pyx_t_6, Py_LT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyObject_RichCompare(__pyx_t_4, __pyx_t_6, Py_LT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 884; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-      __pyx_t_14 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_14 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_14 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_14 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 884; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       __pyx_t_15 = __pyx_t_14;
     } else {
@@ -44933,34 +44915,34 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
     }
     if (__pyx_t_15) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":880
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":885
  *             ni = i + spanlen
  *             if (ni < len(fwords) and (pathlen + 1) < self.max_initial_size):
  *                 for na in range(len(fwords[ni])):             # <<<<<<<<<<<<<<
  *                     nf.append((toskip - 1, (ni, na, pathlen + 1)))
  *         if (len(nf) > 0):
  */
-      __pyx_t_5 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ni); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ni); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_13 = PyObject_Length(__pyx_t_5); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_13 = PyObject_Length(__pyx_t_5); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       for (__pyx_t_16 = 0; __pyx_t_16 < __pyx_t_13; __pyx_t_16+=1) {
         __pyx_v_na = __pyx_t_16;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":881
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":886
  *             if (ni < len(fwords) and (pathlen + 1) < self.max_initial_size):
  *                 for na in range(len(fwords[ni])):
  *                     nf.append((toskip - 1, (ni, na, pathlen + 1)))             # <<<<<<<<<<<<<<
  *         if (len(nf) > 0):
  *             return self.advance(nf, res, fwords)
  */
-        __pyx_t_5 = PyNumber_Subtract(__pyx_v_toskip, __pyx_int_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = PyNumber_Subtract(__pyx_v_toskip, __pyx_int_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_5);
-        __pyx_t_6 = PyLong_FromUnsignedLong(__pyx_v_na); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_6 = PyLong_FromUnsignedLong(__pyx_v_na); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_6);
-        __pyx_t_4 = PyNumber_Add(__pyx_v_pathlen, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyNumber_Add(__pyx_v_pathlen, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_4);
-        __pyx_t_10 = PyTuple_New(3); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_10 = PyTuple_New(3); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_10);
         __Pyx_INCREF(__pyx_v_ni);
         PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_v_ni);
@@ -44971,7 +44953,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
         __Pyx_GIVEREF(__pyx_t_4);
         __pyx_t_6 = 0;
         __pyx_t_4 = 0;
-        __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_4);
         PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_5);
         __Pyx_GIVEREF(__pyx_t_5);
@@ -44979,7 +44961,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
         __Pyx_GIVEREF(((PyObject *)__pyx_t_10));
         __pyx_t_5 = 0;
         __pyx_t_10 = 0;
-        __pyx_t_17 = PyList_Append(__pyx_v_nf, ((PyObject *)__pyx_t_4)); if (unlikely(__pyx_t_17 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_17 = PyList_Append(__pyx_v_nf, ((PyObject *)__pyx_t_4)); if (unlikely(__pyx_t_17 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
       }
       goto __pyx_L10;
@@ -44988,18 +44970,18 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":882
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":887
  *                 for na in range(len(fwords[ni])):
  *                     nf.append((toskip - 1, (ni, na, pathlen + 1)))
  *         if (len(nf) > 0):             # <<<<<<<<<<<<<<
  *             return self.advance(nf, res, fwords)
  *         else:
  */
-  __pyx_t_2 = PyList_GET_SIZE(((PyObject *)__pyx_v_nf)); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 882; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyList_GET_SIZE(((PyObject *)__pyx_v_nf)); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 887; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_t_15 = (__pyx_t_2 > 0);
   if (__pyx_t_15) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":883
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":888
  *                     nf.append((toskip - 1, (ni, na, pathlen + 1)))
  *         if (len(nf) > 0):
  *             return self.advance(nf, res, fwords)             # <<<<<<<<<<<<<<
@@ -45007,9 +44989,9 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
  *             return res
  */
     __Pyx_XDECREF(__pyx_r);
-    __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__advance); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 883; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__advance); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 883; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_INCREF(((PyObject *)__pyx_v_nf));
     PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_v_nf));
@@ -45020,7 +45002,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
     __Pyx_INCREF(__pyx_v_fwords);
     PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_v_fwords);
     __Pyx_GIVEREF(__pyx_v_fwords);
-    __pyx_t_10 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 883; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_10);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
@@ -45031,7 +45013,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":885
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":890
  *             return self.advance(nf, res, fwords)
  *         else:
  *             return res             # <<<<<<<<<<<<<<
@@ -45109,36 +45091,36 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_15get_all_nodes_isteps_
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__i)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("get_all_nodes_isteps_away", 1, 7, 7, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 887; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("get_all_nodes_isteps_away", 1, 7, 7, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 892; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__spanlen)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("get_all_nodes_isteps_away", 1, 7, 7, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 887; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("get_all_nodes_isteps_away", 1, 7, 7, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 892; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  3:
         if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__pathlen)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("get_all_nodes_isteps_away", 1, 7, 7, 3); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 887; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("get_all_nodes_isteps_away", 1, 7, 7, 3); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 892; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  4:
         if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__fwords)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("get_all_nodes_isteps_away", 1, 7, 7, 4); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 887; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("get_all_nodes_isteps_away", 1, 7, 7, 4); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 892; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  5:
         if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__next_states)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("get_all_nodes_isteps_away", 1, 7, 7, 5); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 887; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("get_all_nodes_isteps_away", 1, 7, 7, 5); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 892; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  6:
         if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__reachable_buffer)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("get_all_nodes_isteps_away", 1, 7, 7, 6); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 887; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("get_all_nodes_isteps_away", 1, 7, 7, 6); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 892; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "get_all_nodes_isteps_away") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 887; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "get_all_nodes_isteps_away") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 892; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 7) {
       goto __pyx_L5_argtuple_error;
@@ -45161,7 +45143,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_15get_all_nodes_isteps_
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("get_all_nodes_isteps_away", 1, 7, 7, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 887; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("get_all_nodes_isteps_away", 1, 7, 7, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 892; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.get_all_nodes_isteps_away", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -45172,7 +45154,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_15get_all_nodes_isteps_
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":887
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":892
  *             return res
  * 
  *     def get_all_nodes_isteps_away(self, skip, i, spanlen, pathlen, fwords, next_states, reachable_buffer):             # <<<<<<<<<<<<<<
@@ -45210,41 +45192,41 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_all_nodes_isteps_away", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":889
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":894
  *     def get_all_nodes_isteps_away(self, skip, i, spanlen, pathlen, fwords, next_states, reachable_buffer):
  *         cdef unsigned alt_it
  *         frontier = []             # <<<<<<<<<<<<<<
  *         if (i+spanlen+skip >= len(next_states)):
  *             return frontier
  */
-  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 889; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_frontier = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":890
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":895
  *         cdef unsigned alt_it
  *         frontier = []
  *         if (i+spanlen+skip >= len(next_states)):             # <<<<<<<<<<<<<<
  *             return frontier
  *         key = tuple([i,spanlen])
  */
-  __pyx_t_1 = PyNumber_Add(__pyx_v_i, __pyx_v_spanlen); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 890; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyNumber_Add(__pyx_v_i, __pyx_v_spanlen); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_v_skip); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 890; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_v_skip); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_3 = PyObject_Length(__pyx_v_next_states); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 890; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 890; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Length(__pyx_v_next_states); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_4 = PyObject_RichCompare(__pyx_t_2, __pyx_t_1, Py_GE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 890; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyObject_RichCompare(__pyx_t_2, __pyx_t_1, Py_GE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 890; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   if (__pyx_t_5) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":891
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":896
  *         frontier = []
  *         if (i+spanlen+skip >= len(next_states)):
  *             return frontier             # <<<<<<<<<<<<<<
@@ -45259,14 +45241,14 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":892
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":897
  *         if (i+spanlen+skip >= len(next_states)):
  *             return frontier
  *         key = tuple([i,spanlen])             # <<<<<<<<<<<<<<
  *         reachable = []
  *         if (key in reachable_buffer):
  */
-  __pyx_t_4 = PyList_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 892; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyList_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_INCREF(__pyx_v_i);
   PyList_SET_ITEM(__pyx_t_4, 0, __pyx_v_i);
@@ -45274,42 +45256,42 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
   __Pyx_INCREF(__pyx_v_spanlen);
   PyList_SET_ITEM(__pyx_t_4, 1, __pyx_v_spanlen);
   __Pyx_GIVEREF(__pyx_v_spanlen);
-  __pyx_t_1 = ((PyObject *)PyList_AsTuple(__pyx_t_4)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 892; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = ((PyObject *)PyList_AsTuple(__pyx_t_4)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
   __pyx_v_key = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":893
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":898
  *             return frontier
  *         key = tuple([i,spanlen])
  *         reachable = []             # <<<<<<<<<<<<<<
  *         if (key in reachable_buffer):
  *             reachable = reachable_buffer[key]
  */
-  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 898; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_reachable = ((PyObject *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":894
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":899
  *         key = tuple([i,spanlen])
  *         reachable = []
  *         if (key in reachable_buffer):             # <<<<<<<<<<<<<<
  *             reachable = reachable_buffer[key]
  *         else:
  */
-  __pyx_t_5 = (__Pyx_PySequence_Contains(((PyObject *)__pyx_v_key), __pyx_v_reachable_buffer, Py_EQ)); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = (__Pyx_PySequence_Contains(((PyObject *)__pyx_v_key), __pyx_v_reachable_buffer, Py_EQ)); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   if (__pyx_t_5) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":895
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":900
  *         reachable = []
  *         if (key in reachable_buffer):
  *             reachable = reachable_buffer[key]             # <<<<<<<<<<<<<<
  *         else:
  *             reachable = self.reachable(fwords, i, spanlen)
  */
-    __pyx_t_1 = PyObject_GetItem(__pyx_v_reachable_buffer, ((PyObject *)__pyx_v_key)); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_GetItem(__pyx_v_reachable_buffer, ((PyObject *)__pyx_v_key)); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 900; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_v_reachable);
     __pyx_v_reachable = __pyx_t_1;
@@ -45318,16 +45300,16 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":897
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":902
  *             reachable = reachable_buffer[key]
  *         else:
  *             reachable = self.reachable(fwords, i, spanlen)             # <<<<<<<<<<<<<<
  *             reachable_buffer[key] = reachable
  *         for nextreachable in reachable:
  */
-    __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__reachable); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__reachable); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 902; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 902; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_INCREF(__pyx_v_fwords);
     PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_fwords);
@@ -45338,7 +45320,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
     __Pyx_INCREF(__pyx_v_spanlen);
     PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_v_spanlen);
     __Pyx_GIVEREF(__pyx_v_spanlen);
-    __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 902; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
@@ -45346,18 +45328,18 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
     __pyx_v_reachable = __pyx_t_2;
     __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":898
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":903
  *         else:
  *             reachable = self.reachable(fwords, i, spanlen)
  *             reachable_buffer[key] = reachable             # <<<<<<<<<<<<<<
  *         for nextreachable in reachable:
  *             for next_id in next_states[nextreachable]:
  */
-    if (PyObject_SetItem(__pyx_v_reachable_buffer, ((PyObject *)__pyx_v_key), __pyx_v_reachable) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 898; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyObject_SetItem(__pyx_v_reachable_buffer, ((PyObject *)__pyx_v_key), __pyx_v_reachable) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 903; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __pyx_L4:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":899
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":904
  *             reachable = self.reachable(fwords, i, spanlen)
  *             reachable_buffer[key] = reachable
  *         for nextreachable in reachable:             # <<<<<<<<<<<<<<
@@ -45368,7 +45350,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
     __pyx_t_2 = __pyx_v_reachable; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0;
     __pyx_t_6 = NULL;
   } else {
-    __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_reachable); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_reachable); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_6 = Py_TYPE(__pyx_t_2)->tp_iternext;
   }
@@ -45376,23 +45358,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
     if (!__pyx_t_6 && PyList_CheckExact(__pyx_t_2)) {
       if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_2)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_4 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_4); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_4); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_6 && PyTuple_CheckExact(__pyx_t_2)) {
       if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_4); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_4); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_4 = __pyx_t_6(__pyx_t_2);
       if (unlikely(!__pyx_t_4)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -45402,20 +45384,20 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
     __pyx_v_nextreachable = __pyx_t_4;
     __pyx_t_4 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":900
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":905
  *             reachable_buffer[key] = reachable
  *         for nextreachable in reachable:
  *             for next_id in next_states[nextreachable]:             # <<<<<<<<<<<<<<
  *                 jump = self.shortest(fwords,i,next_id)
  *                 if jump < skip:
  */
-    __pyx_t_4 = PyObject_GetItem(__pyx_v_next_states, __pyx_v_nextreachable); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 900; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_GetItem(__pyx_v_next_states, __pyx_v_nextreachable); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     if (PyList_CheckExact(__pyx_t_4) || PyTuple_CheckExact(__pyx_t_4)) {
       __pyx_t_1 = __pyx_t_4; __Pyx_INCREF(__pyx_t_1); __pyx_t_7 = 0;
       __pyx_t_8 = NULL;
     } else {
-      __pyx_t_7 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 900; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __pyx_t_8 = Py_TYPE(__pyx_t_1)->tp_iternext;
     }
@@ -45424,23 +45406,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
       if (!__pyx_t_8 && PyList_CheckExact(__pyx_t_1)) {
         if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_1)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_7); __Pyx_INCREF(__pyx_t_4); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 900; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_7); __Pyx_INCREF(__pyx_t_4); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 900; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else if (!__pyx_t_8 && PyTuple_CheckExact(__pyx_t_1)) {
         if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_7); __Pyx_INCREF(__pyx_t_4); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 900; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_7); __Pyx_INCREF(__pyx_t_4); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 900; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else {
         __pyx_t_4 = __pyx_t_8(__pyx_t_1);
         if (unlikely(!__pyx_t_4)) {
           if (PyErr_Occurred()) {
             if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 900; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           }
           break;
         }
@@ -45450,16 +45432,16 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
       __pyx_v_next_id = __pyx_t_4;
       __pyx_t_4 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":901
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":906
  *         for nextreachable in reachable:
  *             for next_id in next_states[nextreachable]:
  *                 jump = self.shortest(fwords,i,next_id)             # <<<<<<<<<<<<<<
  *                 if jump < skip:
  *                     continue
  */
-      __pyx_t_4 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__shortest); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 901; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__shortest); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_9 = PyTuple_New(3); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 901; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_9 = PyTuple_New(3); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_9);
       __Pyx_INCREF(__pyx_v_fwords);
       PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_v_fwords);
@@ -45470,7 +45452,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
       __Pyx_INCREF(__pyx_v_next_id);
       PyTuple_SET_ITEM(__pyx_t_9, 2, __pyx_v_next_id);
       __Pyx_GIVEREF(__pyx_v_next_id);
-      __pyx_t_10 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 901; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_10 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_10);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
@@ -45478,19 +45460,19 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
       __pyx_v_jump = __pyx_t_10;
       __pyx_t_10 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":902
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":907
  *             for next_id in next_states[nextreachable]:
  *                 jump = self.shortest(fwords,i,next_id)
  *                 if jump < skip:             # <<<<<<<<<<<<<<
  *                     continue
  *                 if pathlen+jump <= self.max_initial_size:
  */
-      __pyx_t_10 = PyObject_RichCompare(__pyx_v_jump, __pyx_v_skip, Py_LT); __Pyx_XGOTREF(__pyx_t_10); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 902; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 902; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_10 = PyObject_RichCompare(__pyx_v_jump, __pyx_v_skip, Py_LT); __Pyx_XGOTREF(__pyx_t_10); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 907; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 907; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
       if (__pyx_t_5) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":903
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":908
  *                 jump = self.shortest(fwords,i,next_id)
  *                 if jump < skip:
  *                     continue             # <<<<<<<<<<<<<<
@@ -45502,50 +45484,50 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
       }
       __pyx_L9:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":904
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":909
  *                 if jump < skip:
  *                     continue
  *                 if pathlen+jump <= self.max_initial_size:             # <<<<<<<<<<<<<<
  *                     for alt_id in range(len(fwords[next_id])):
  *                         if (fwords[next_id][alt_id][0] != EPSILON):
  */
-      __pyx_t_10 = PyNumber_Add(__pyx_v_pathlen, __pyx_v_jump); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_10 = PyNumber_Add(__pyx_v_pathlen, __pyx_v_jump); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 909; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_10);
-      __pyx_t_9 = PyInt_FromLong(__pyx_v_self->max_initial_size); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_9 = PyInt_FromLong(__pyx_v_self->max_initial_size); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 909; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_9);
-      __pyx_t_4 = PyObject_RichCompare(__pyx_t_10, __pyx_t_9, Py_LE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_RichCompare(__pyx_t_10, __pyx_t_9, Py_LE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 909; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
       __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 909; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       if (__pyx_t_5) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":905
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":910
  *                     continue
  *                 if pathlen+jump <= self.max_initial_size:
  *                     for alt_id in range(len(fwords[next_id])):             # <<<<<<<<<<<<<<
  *                         if (fwords[next_id][alt_id][0] != EPSILON):
  *                             newel = (next_id,alt_id,pathlen+jump)
  */
-        __pyx_t_4 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_next_id); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_next_id); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_4);
-        __pyx_t_11 = PyObject_Length(__pyx_t_4); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_11 = PyObject_Length(__pyx_t_4); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        __pyx_t_4 = PyInt_FromSsize_t(__pyx_t_11); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyInt_FromSsize_t(__pyx_t_11); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_4);
-        __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_9);
         PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_4);
         __Pyx_GIVEREF(__pyx_t_4);
         __pyx_t_4 = 0;
-        __pyx_t_4 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
         if (PyList_CheckExact(__pyx_t_4) || PyTuple_CheckExact(__pyx_t_4)) {
           __pyx_t_9 = __pyx_t_4; __Pyx_INCREF(__pyx_t_9); __pyx_t_11 = 0;
           __pyx_t_12 = NULL;
         } else {
-          __pyx_t_11 = -1; __pyx_t_9 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = -1; __pyx_t_9 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
           __pyx_t_12 = Py_TYPE(__pyx_t_9)->tp_iternext;
         }
@@ -45554,23 +45536,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
           if (!__pyx_t_12 && PyList_CheckExact(__pyx_t_9)) {
             if (__pyx_t_11 >= PyList_GET_SIZE(__pyx_t_9)) break;
             #if CYTHON_COMPILING_IN_CPYTHON
-            __pyx_t_4 = PyList_GET_ITEM(__pyx_t_9, __pyx_t_11); __Pyx_INCREF(__pyx_t_4); __pyx_t_11++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_4 = PyList_GET_ITEM(__pyx_t_9, __pyx_t_11); __Pyx_INCREF(__pyx_t_4); __pyx_t_11++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             #else
-            __pyx_t_4 = PySequence_ITEM(__pyx_t_9, __pyx_t_11); __pyx_t_11++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_4 = PySequence_ITEM(__pyx_t_9, __pyx_t_11); __pyx_t_11++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             #endif
           } else if (!__pyx_t_12 && PyTuple_CheckExact(__pyx_t_9)) {
             if (__pyx_t_11 >= PyTuple_GET_SIZE(__pyx_t_9)) break;
             #if CYTHON_COMPILING_IN_CPYTHON
-            __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_9, __pyx_t_11); __Pyx_INCREF(__pyx_t_4); __pyx_t_11++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_9, __pyx_t_11); __Pyx_INCREF(__pyx_t_4); __pyx_t_11++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             #else
-            __pyx_t_4 = PySequence_ITEM(__pyx_t_9, __pyx_t_11); __pyx_t_11++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_4 = PySequence_ITEM(__pyx_t_9, __pyx_t_11); __pyx_t_11++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             #endif
           } else {
             __pyx_t_4 = __pyx_t_12(__pyx_t_9);
             if (unlikely(!__pyx_t_4)) {
               if (PyErr_Occurred()) {
                 if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-                else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               }
               break;
             }
@@ -45580,40 +45562,40 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
           __pyx_v_alt_id = __pyx_t_4;
           __pyx_t_4 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":906
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":911
  *                 if pathlen+jump <= self.max_initial_size:
  *                     for alt_id in range(len(fwords[next_id])):
  *                         if (fwords[next_id][alt_id][0] != EPSILON):             # <<<<<<<<<<<<<<
  *                             newel = (next_id,alt_id,pathlen+jump)
  *                             if newel not in frontier:
  */
-          __pyx_t_4 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_next_id); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_4 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_next_id); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_4);
-          __pyx_t_10 = PyObject_GetItem(__pyx_t_4, __pyx_v_alt_id); if (!__pyx_t_10) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_10 = PyObject_GetItem(__pyx_t_4, __pyx_v_alt_id); if (!__pyx_t_10) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_10);
           __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-          __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_10, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_10, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_4);
           __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-          __pyx_t_10 = PyInt_FromLong(__pyx_v_3_sa_EPSILON); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_10 = PyInt_FromLong(__pyx_v_3_sa_EPSILON); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_10);
-          __pyx_t_13 = PyObject_RichCompare(__pyx_t_4, __pyx_t_10, Py_NE); __Pyx_XGOTREF(__pyx_t_13); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_13 = PyObject_RichCompare(__pyx_t_4, __pyx_t_10, Py_NE); __Pyx_XGOTREF(__pyx_t_13); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
           __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-          __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_13); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_13); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
           if (__pyx_t_5) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":907
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":912
  *                     for alt_id in range(len(fwords[next_id])):
  *                         if (fwords[next_id][alt_id][0] != EPSILON):
  *                             newel = (next_id,alt_id,pathlen+jump)             # <<<<<<<<<<<<<<
  *                             if newel not in frontier:
  *                                 frontier.append((next_id,alt_id,pathlen+jump))
  */
-            __pyx_t_13 = PyNumber_Add(__pyx_v_pathlen, __pyx_v_jump); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 907; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_13 = PyNumber_Add(__pyx_v_pathlen, __pyx_v_jump); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 912; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_13);
-            __pyx_t_10 = PyTuple_New(3); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 907; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_10 = PyTuple_New(3); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 912; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_10);
             __Pyx_INCREF(__pyx_v_next_id);
             PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_v_next_id);
@@ -45628,26 +45610,26 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
             __pyx_v_newel = __pyx_t_10;
             __pyx_t_10 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":908
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":913
  *                         if (fwords[next_id][alt_id][0] != EPSILON):
  *                             newel = (next_id,alt_id,pathlen+jump)
  *                             if newel not in frontier:             # <<<<<<<<<<<<<<
  *                                 frontier.append((next_id,alt_id,pathlen+jump))
  *         return frontier
  */
-            __pyx_t_5 = (__Pyx_PySequence_Contains(((PyObject *)__pyx_v_newel), ((PyObject *)__pyx_v_frontier), Py_NE)); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 908; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_5 = (__Pyx_PySequence_Contains(((PyObject *)__pyx_v_newel), ((PyObject *)__pyx_v_frontier), Py_NE)); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             if (__pyx_t_5) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":909
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":914
  *                             newel = (next_id,alt_id,pathlen+jump)
  *                             if newel not in frontier:
  *                                 frontier.append((next_id,alt_id,pathlen+jump))             # <<<<<<<<<<<<<<
  *         return frontier
  * 
  */
-              __pyx_t_10 = PyNumber_Add(__pyx_v_pathlen, __pyx_v_jump); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 909; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_10 = PyNumber_Add(__pyx_v_pathlen, __pyx_v_jump); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_10);
-              __pyx_t_13 = PyTuple_New(3); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 909; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_13 = PyTuple_New(3); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_13);
               __Pyx_INCREF(__pyx_v_next_id);
               PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_v_next_id);
@@ -45658,7 +45640,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
               PyTuple_SET_ITEM(__pyx_t_13, 2, __pyx_t_10);
               __Pyx_GIVEREF(__pyx_t_10);
               __pyx_t_10 = 0;
-              __pyx_t_14 = PyList_Append(__pyx_v_frontier, ((PyObject *)__pyx_t_13)); if (unlikely(__pyx_t_14 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 909; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_14 = PyList_Append(__pyx_v_frontier, ((PyObject *)__pyx_t_13)); if (unlikely(__pyx_t_14 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_DECREF(((PyObject *)__pyx_t_13)); __pyx_t_13 = 0;
               goto __pyx_L14;
             }
@@ -45677,7 +45659,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
   }
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":910
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":915
  *                             if newel not in frontier:
  *                                 frontier.append((next_id,alt_id,pathlen+jump))
  *         return frontier             # <<<<<<<<<<<<<<
@@ -45744,16 +45726,16 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_17reachable(PyObject *_
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__ifrom)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("reachable", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 912; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("reachable", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 917; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__dist)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("reachable", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 912; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("reachable", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 917; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reachable") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 912; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reachable") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 917; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
       goto __pyx_L5_argtuple_error;
@@ -45768,7 +45750,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_17reachable(PyObject *_
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("reachable", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 912; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("reachable", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 917; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.reachable", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -45779,7 +45761,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_17reachable(PyObject *_
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":912
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":917
  *         return frontier
  * 
  *     def reachable(self, fwords, ifrom, dist):             # <<<<<<<<<<<<<<
@@ -45809,35 +45791,35 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_16reachable(struct __py
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("reachable", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":913
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":918
  * 
  *     def reachable(self, fwords, ifrom, dist):
  *         ret = []             # <<<<<<<<<<<<<<
  *         if (ifrom >= len(fwords)):
  *             return ret
  */
-  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_ret = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":914
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":919
  *     def reachable(self, fwords, ifrom, dist):
  *         ret = []
  *         if (ifrom >= len(fwords)):             # <<<<<<<<<<<<<<
  *             return ret
  *         for alt_id in range(len(fwords[ifrom])):
  */
-  __pyx_t_2 = PyObject_Length(__pyx_v_fwords); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Length(__pyx_v_fwords); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 919; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 919; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyObject_RichCompare(__pyx_v_ifrom, __pyx_t_1, Py_GE); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_RichCompare(__pyx_v_ifrom, __pyx_t_1, Py_GE); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 919; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 919; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   if (__pyx_t_4) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":915
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":920
  *         ret = []
  *         if (ifrom >= len(fwords)):
  *             return ret             # <<<<<<<<<<<<<<
@@ -45852,32 +45834,32 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_16reachable(struct __py
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":916
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":921
  *         if (ifrom >= len(fwords)):
  *             return ret
  *         for alt_id in range(len(fwords[ifrom])):             # <<<<<<<<<<<<<<
  *             if (fwords[ifrom][alt_id][0] == EPSILON):
  *                 ret.extend(self.reachable(fwords,ifrom+fwords[ifrom][alt_id][2],dist))
  */
-  __pyx_t_3 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ifrom); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 916; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ifrom); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_2 = PyObject_Length(__pyx_t_3); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 916; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Length(__pyx_t_3); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_3 = PyInt_FromSsize_t(__pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 916; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyInt_FromSsize_t(__pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 916; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_3);
   __Pyx_GIVEREF(__pyx_t_3);
   __pyx_t_3 = 0;
-  __pyx_t_3 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 916; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
   if (PyList_CheckExact(__pyx_t_3) || PyTuple_CheckExact(__pyx_t_3)) {
     __pyx_t_1 = __pyx_t_3; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
     __pyx_t_5 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 916; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_5 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -45886,23 +45868,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_16reachable(struct __py
     if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 916; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 916; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 916; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 916; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_3 = __pyx_t_5(__pyx_t_1);
       if (unlikely(!__pyx_t_3)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 916; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -45912,53 +45894,53 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_16reachable(struct __py
     __pyx_v_alt_id = __pyx_t_3;
     __pyx_t_3 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":917
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":922
  *             return ret
  *         for alt_id in range(len(fwords[ifrom])):
  *             if (fwords[ifrom][alt_id][0] == EPSILON):             # <<<<<<<<<<<<<<
  *                 ret.extend(self.reachable(fwords,ifrom+fwords[ifrom][alt_id][2],dist))
  *             else:
  */
-    __pyx_t_3 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ifrom); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 917; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ifrom); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_6 = PyObject_GetItem(__pyx_t_3, __pyx_v_alt_id); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 917; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyObject_GetItem(__pyx_t_3, __pyx_v_alt_id); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_6, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 917; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_6, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = PyInt_FromLong(__pyx_v_3_sa_EPSILON); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 917; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyInt_FromLong(__pyx_v_3_sa_EPSILON); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_7 = PyObject_RichCompare(__pyx_t_3, __pyx_t_6, Py_EQ); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 917; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyObject_RichCompare(__pyx_t_3, __pyx_t_6, Py_EQ); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 917; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     if (__pyx_t_4) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":918
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":923
  *         for alt_id in range(len(fwords[ifrom])):
  *             if (fwords[ifrom][alt_id][0] == EPSILON):
  *                 ret.extend(self.reachable(fwords,ifrom+fwords[ifrom][alt_id][2],dist))             # <<<<<<<<<<<<<<
  *             else:
  *                 if (dist==0):
  */
-      __pyx_t_7 = PyObject_GetAttr(((PyObject *)__pyx_v_ret), __pyx_n_s__extend); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyObject_GetAttr(((PyObject *)__pyx_v_ret), __pyx_n_s__extend); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_7);
-      __pyx_t_6 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__reachable); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__reachable); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_6);
-      __pyx_t_3 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ifrom); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ifrom); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_8 = PyObject_GetItem(__pyx_t_3, __pyx_v_alt_id); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyObject_GetItem(__pyx_t_3, __pyx_v_alt_id); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_8, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_8, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-      __pyx_t_8 = PyNumber_Add(__pyx_v_ifrom, __pyx_t_3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyNumber_Add(__pyx_v_ifrom, __pyx_t_3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_INCREF(__pyx_v_fwords);
       PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_fwords);
@@ -45969,16 +45951,16 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_16reachable(struct __py
       PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_v_dist);
       __Pyx_GIVEREF(__pyx_v_dist);
       __pyx_t_8 = 0;
-      __pyx_t_8 = PyObject_Call(__pyx_t_6, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyObject_Call(__pyx_t_6, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
-      __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_8);
       __Pyx_GIVEREF(__pyx_t_8);
       __pyx_t_8 = 0;
-      __pyx_t_8 = PyObject_Call(__pyx_t_7, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyObject_Call(__pyx_t_7, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
@@ -45987,36 +45969,36 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_16reachable(struct __py
     }
     /*else*/ {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":920
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":925
  *                 ret.extend(self.reachable(fwords,ifrom+fwords[ifrom][alt_id][2],dist))
  *             else:
  *                 if (dist==0):             # <<<<<<<<<<<<<<
  *                     if (ifrom not in ret):
  *                         ret.append(ifrom)
  */
-      __pyx_t_8 = PyObject_RichCompare(__pyx_v_dist, __pyx_int_0, Py_EQ); __Pyx_XGOTREF(__pyx_t_8); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 920; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 920; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyObject_RichCompare(__pyx_v_dist, __pyx_int_0, Py_EQ); __Pyx_XGOTREF(__pyx_t_8); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       if (__pyx_t_4) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":921
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":926
  *             else:
  *                 if (dist==0):
  *                     if (ifrom not in ret):             # <<<<<<<<<<<<<<
  *                         ret.append(ifrom)
  *                 else:
  */
-        __pyx_t_4 = (__Pyx_PySequence_Contains(__pyx_v_ifrom, ((PyObject *)__pyx_v_ret), Py_NE)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = (__Pyx_PySequence_Contains(__pyx_v_ifrom, ((PyObject *)__pyx_v_ret), Py_NE)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 926; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         if (__pyx_t_4) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":922
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":927
  *                 if (dist==0):
  *                     if (ifrom not in ret):
  *                         ret.append(ifrom)             # <<<<<<<<<<<<<<
  *                 else:
  *                     for ifromchild in self.reachable(fwords,ifrom+fwords[ifrom][alt_id][2],dist-1):
  */
-          __pyx_t_9 = PyList_Append(__pyx_v_ret, __pyx_v_ifrom); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyList_Append(__pyx_v_ret, __pyx_v_ifrom); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 927; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           goto __pyx_L8;
         }
         __pyx_L8:;
@@ -46024,29 +46006,29 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_16reachable(struct __py
       }
       /*else*/ {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":924
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":929
  *                         ret.append(ifrom)
  *                 else:
  *                     for ifromchild in self.reachable(fwords,ifrom+fwords[ifrom][alt_id][2],dist-1):             # <<<<<<<<<<<<<<
  *                         if (ifromchild not in ret):
  *                             ret.append(ifromchild)
  */
-        __pyx_t_8 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__reachable); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_8 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__reachable); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_8);
-        __pyx_t_3 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ifrom); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ifrom); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_3);
-        __pyx_t_7 = PyObject_GetItem(__pyx_t_3, __pyx_v_alt_id); if (!__pyx_t_7) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PyObject_GetItem(__pyx_t_3, __pyx_v_alt_id); if (!__pyx_t_7) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_7);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_7, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_7, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-        __pyx_t_7 = PyNumber_Add(__pyx_v_ifrom, __pyx_t_3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PyNumber_Add(__pyx_v_ifrom, __pyx_t_3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_7);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_3 = PyNumber_Subtract(__pyx_v_dist, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = PyNumber_Subtract(__pyx_v_dist, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_3);
-        __pyx_t_6 = PyTuple_New(3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_6 = PyTuple_New(3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_6);
         __Pyx_INCREF(__pyx_v_fwords);
         PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_v_fwords);
@@ -46057,7 +46039,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_16reachable(struct __py
         __Pyx_GIVEREF(__pyx_t_3);
         __pyx_t_7 = 0;
         __pyx_t_3 = 0;
-        __pyx_t_3 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
         __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
@@ -46065,7 +46047,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_16reachable(struct __py
           __pyx_t_6 = __pyx_t_3; __Pyx_INCREF(__pyx_t_6); __pyx_t_10 = 0;
           __pyx_t_11 = NULL;
         } else {
-          __pyx_t_10 = -1; __pyx_t_6 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_10 = -1; __pyx_t_6 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_6);
           __pyx_t_11 = Py_TYPE(__pyx_t_6)->tp_iternext;
         }
@@ -46074,23 +46056,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_16reachable(struct __py
           if (!__pyx_t_11 && PyList_CheckExact(__pyx_t_6)) {
             if (__pyx_t_10 >= PyList_GET_SIZE(__pyx_t_6)) break;
             #if CYTHON_COMPILING_IN_CPYTHON
-            __pyx_t_3 = PyList_GET_ITEM(__pyx_t_6, __pyx_t_10); __Pyx_INCREF(__pyx_t_3); __pyx_t_10++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = PyList_GET_ITEM(__pyx_t_6, __pyx_t_10); __Pyx_INCREF(__pyx_t_3); __pyx_t_10++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             #else
-            __pyx_t_3 = PySequence_ITEM(__pyx_t_6, __pyx_t_10); __pyx_t_10++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = PySequence_ITEM(__pyx_t_6, __pyx_t_10); __pyx_t_10++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             #endif
           } else if (!__pyx_t_11 && PyTuple_CheckExact(__pyx_t_6)) {
             if (__pyx_t_10 >= PyTuple_GET_SIZE(__pyx_t_6)) break;
             #if CYTHON_COMPILING_IN_CPYTHON
-            __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_6, __pyx_t_10); __Pyx_INCREF(__pyx_t_3); __pyx_t_10++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_6, __pyx_t_10); __Pyx_INCREF(__pyx_t_3); __pyx_t_10++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             #else
-            __pyx_t_3 = PySequence_ITEM(__pyx_t_6, __pyx_t_10); __pyx_t_10++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = PySequence_ITEM(__pyx_t_6, __pyx_t_10); __pyx_t_10++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             #endif
           } else {
             __pyx_t_3 = __pyx_t_11(__pyx_t_6);
             if (unlikely(!__pyx_t_3)) {
               if (PyErr_Occurred()) {
                 if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-                else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               }
               break;
             }
@@ -46100,24 +46082,24 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_16reachable(struct __py
           __pyx_v_ifromchild = __pyx_t_3;
           __pyx_t_3 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":925
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":930
  *                 else:
  *                     for ifromchild in self.reachable(fwords,ifrom+fwords[ifrom][alt_id][2],dist-1):
  *                         if (ifromchild not in ret):             # <<<<<<<<<<<<<<
  *                             ret.append(ifromchild)
  * 
  */
-          __pyx_t_4 = (__Pyx_PySequence_Contains(__pyx_v_ifromchild, ((PyObject *)__pyx_v_ret), Py_NE)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_4 = (__Pyx_PySequence_Contains(__pyx_v_ifromchild, ((PyObject *)__pyx_v_ret), Py_NE)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 930; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           if (__pyx_t_4) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":926
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":931
  *                     for ifromchild in self.reachable(fwords,ifrom+fwords[ifrom][alt_id][2],dist-1):
  *                         if (ifromchild not in ret):
  *                             ret.append(ifromchild)             # <<<<<<<<<<<<<<
  * 
  *         return ret
  */
-            __pyx_t_9 = PyList_Append(__pyx_v_ret, __pyx_v_ifromchild); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 926; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_9 = PyList_Append(__pyx_v_ret, __pyx_v_ifromchild); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             goto __pyx_L11;
           }
           __pyx_L11:;
@@ -46130,7 +46112,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_16reachable(struct __py
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":928
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":933
  *                             ret.append(ifromchild)
  * 
  *         return ret             # <<<<<<<<<<<<<<
@@ -46191,16 +46173,16 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_19shortest(PyObject *__
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__ifrom)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("shortest", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 930; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("shortest", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 935; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__ito)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("shortest", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 930; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("shortest", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 935; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "shortest") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 930; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "shortest") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 935; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
       goto __pyx_L5_argtuple_error;
@@ -46215,7 +46197,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_19shortest(PyObject *__
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("shortest", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 930; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("shortest", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 935; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.shortest", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -46226,7 +46208,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_19shortest(PyObject *__
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":930
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":935
  *         return ret
  * 
  *     def shortest(self, fwords, ifrom, ito):             # <<<<<<<<<<<<<<
@@ -46251,7 +46233,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_18shortest(struct __pyx
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("shortest", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":932
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":937
  *     def shortest(self, fwords, ifrom, ito):
  *         cdef unsigned alt_id
  *         min = 1000             # <<<<<<<<<<<<<<
@@ -46261,19 +46243,19 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_18shortest(struct __pyx
   __Pyx_INCREF(__pyx_int_1000);
   __pyx_v_min = __pyx_int_1000;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":933
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":938
  *         cdef unsigned alt_id
  *         min = 1000
  *         if (ifrom > ito):             # <<<<<<<<<<<<<<
  *             return min
  *         if (ifrom == ito):
  */
-  __pyx_t_1 = PyObject_RichCompare(__pyx_v_ifrom, __pyx_v_ito, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 933; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 933; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_RichCompare(__pyx_v_ifrom, __pyx_v_ito, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   if (__pyx_t_2) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":934
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":939
  *         min = 1000
  *         if (ifrom > ito):
  *             return min             # <<<<<<<<<<<<<<
@@ -46288,19 +46270,19 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_18shortest(struct __pyx
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":935
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":940
  *         if (ifrom > ito):
  *             return min
  *         if (ifrom == ito):             # <<<<<<<<<<<<<<
  *             return 0
  *         for alt_id in range(len(fwords[ifrom])):
  */
-  __pyx_t_1 = PyObject_RichCompare(__pyx_v_ifrom, __pyx_v_ito, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 935; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 935; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_RichCompare(__pyx_v_ifrom, __pyx_v_ito, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   if (__pyx_t_2) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":936
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":941
  *             return min
  *         if (ifrom == ito):
  *             return 0             # <<<<<<<<<<<<<<
@@ -46315,41 +46297,41 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_18shortest(struct __pyx
   }
   __pyx_L4:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":937
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":942
  *         if (ifrom == ito):
  *             return 0
  *         for alt_id in range(len(fwords[ifrom])):             # <<<<<<<<<<<<<<
  *             currmin = self.shortest(fwords,ifrom+fwords[ifrom][alt_id][2],ito)
  *             if (fwords[ifrom][alt_id][0] != EPSILON):
  */
-  __pyx_t_1 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ifrom); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 937; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ifrom); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 942; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 937; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 942; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
     __pyx_v_alt_id = __pyx_t_4;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":938
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":943
  *             return 0
  *         for alt_id in range(len(fwords[ifrom])):
  *             currmin = self.shortest(fwords,ifrom+fwords[ifrom][alt_id][2],ito)             # <<<<<<<<<<<<<<
  *             if (fwords[ifrom][alt_id][0] != EPSILON):
  *                 currmin += 1
  */
-    __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__shortest); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__shortest); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_5 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ifrom); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ifrom); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_6 = __Pyx_GetItemInt(__pyx_t_5, __pyx_v_alt_id, sizeof(unsigned int)+1, PyLong_FromUnsignedLong); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = __Pyx_GetItemInt(__pyx_t_5, __pyx_v_alt_id, sizeof(unsigned int)+1, PyLong_FromUnsignedLong); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __pyx_t_5 = __Pyx_GetItemInt(__pyx_t_6, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_GetItemInt(__pyx_t_6, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = PyNumber_Add(__pyx_v_ifrom, __pyx_t_5); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyNumber_Add(__pyx_v_ifrom, __pyx_t_5); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_INCREF(__pyx_v_fwords);
     PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_fwords);
@@ -46360,7 +46342,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_18shortest(struct __pyx
     PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_v_ito);
     __Pyx_GIVEREF(__pyx_v_ito);
     __pyx_t_6 = 0;
-    __pyx_t_6 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
@@ -46368,38 +46350,38 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_18shortest(struct __pyx
     __pyx_v_currmin = __pyx_t_6;
     __pyx_t_6 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":939
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":944
  *         for alt_id in range(len(fwords[ifrom])):
  *             currmin = self.shortest(fwords,ifrom+fwords[ifrom][alt_id][2],ito)
  *             if (fwords[ifrom][alt_id][0] != EPSILON):             # <<<<<<<<<<<<<<
  *                 currmin += 1
  *             if (currmin<min):
  */
-    __pyx_t_6 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ifrom); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 939; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ifrom); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_5 = __Pyx_GetItemInt(__pyx_t_6, __pyx_v_alt_id, sizeof(unsigned int)+1, PyLong_FromUnsignedLong); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 939; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_GetItemInt(__pyx_t_6, __pyx_v_alt_id, sizeof(unsigned int)+1, PyLong_FromUnsignedLong); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = __Pyx_GetItemInt(__pyx_t_5, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 939; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = __Pyx_GetItemInt(__pyx_t_5, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __pyx_t_5 = PyInt_FromLong(__pyx_v_3_sa_EPSILON); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 939; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyInt_FromLong(__pyx_v_3_sa_EPSILON); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_1 = PyObject_RichCompare(__pyx_t_6, __pyx_t_5, Py_NE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 939; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_RichCompare(__pyx_t_6, __pyx_t_5, Py_NE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 939; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     if (__pyx_t_2) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":940
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":945
  *             currmin = self.shortest(fwords,ifrom+fwords[ifrom][alt_id][2],ito)
  *             if (fwords[ifrom][alt_id][0] != EPSILON):
  *                 currmin += 1             # <<<<<<<<<<<<<<
  *             if (currmin<min):
  *                 min = currmin
  */
-      __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_currmin, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_currmin, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_v_currmin);
       __pyx_v_currmin = __pyx_t_1;
@@ -46408,19 +46390,19 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_18shortest(struct __pyx
     }
     __pyx_L7:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":941
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":946
  *             if (fwords[ifrom][alt_id][0] != EPSILON):
  *                 currmin += 1
  *             if (currmin<min):             # <<<<<<<<<<<<<<
  *                 min = currmin
  *         return min
  */
-    __pyx_t_1 = PyObject_RichCompare(__pyx_v_currmin, __pyx_v_min, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 941; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 941; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_RichCompare(__pyx_v_currmin, __pyx_v_min, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     if (__pyx_t_2) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":942
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":947
  *                 currmin += 1
  *             if (currmin<min):
  *                 min = currmin             # <<<<<<<<<<<<<<
@@ -46435,7 +46417,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_18shortest(struct __pyx
     __pyx_L8:;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":943
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":948
  *             if (currmin<min):
  *                 min = currmin
  *         return min             # <<<<<<<<<<<<<<
@@ -46494,7 +46476,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_21get_next_states(PyObj
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__curr_idx)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("get_next_states", 0, 2, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 945; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("get_next_states", 0, 2, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 950; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (kw_args > 0) {
@@ -46503,7 +46485,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_21get_next_states(PyObj
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "get_next_states") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 945; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "get_next_states") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 950; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -46520,7 +46502,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_21get_next_states(PyObj
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("get_next_states", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 945; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("get_next_states", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 950; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.get_next_states", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -46531,7 +46513,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_21get_next_states(PyObj
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":945
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":950
  *         return min
  * 
  *     def get_next_states(self, _columns, curr_idx, min_dist=2):             # <<<<<<<<<<<<<<
@@ -46564,26 +46546,26 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_next_states", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":946
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":951
  * 
  *     def get_next_states(self, _columns, curr_idx, min_dist=2):
  *         result = []             # <<<<<<<<<<<<<<
  *         candidate = [[curr_idx,0]]
  * 
  */
-  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 951; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_result = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":947
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":952
  *     def get_next_states(self, _columns, curr_idx, min_dist=2):
  *         result = []
  *         candidate = [[curr_idx,0]]             # <<<<<<<<<<<<<<
  * 
  *         while len(candidate) > 0:
  */
-  __pyx_t_1 = PyList_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyList_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 952; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(__pyx_v_curr_idx);
   PyList_SET_ITEM(__pyx_t_1, 0, __pyx_v_curr_idx);
@@ -46591,7 +46573,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
   __Pyx_INCREF(__pyx_int_0);
   PyList_SET_ITEM(__pyx_t_1, 1, __pyx_int_0);
   __Pyx_GIVEREF(__pyx_int_0);
-  __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 952; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   PyList_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_t_1));
   __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
@@ -46599,7 +46581,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
   __pyx_v_candidate = __pyx_t_2;
   __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":949
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":954
  *         candidate = [[curr_idx,0]]
  * 
  *         while len(candidate) > 0:             # <<<<<<<<<<<<<<
@@ -46607,43 +46589,43 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
  *             if curr[0] >= len(_columns):
  */
   while (1) {
-    __pyx_t_3 = PyList_GET_SIZE(((PyObject *)__pyx_v_candidate)); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 949; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyList_GET_SIZE(((PyObject *)__pyx_v_candidate)); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 954; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __pyx_t_4 = (__pyx_t_3 > 0);
     if (!__pyx_t_4) break;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":950
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":955
  * 
  *         while len(candidate) > 0:
  *             curr = candidate.pop()             # <<<<<<<<<<<<<<
  *             if curr[0] >= len(_columns):
  *                 continue
  */
-    __pyx_t_2 = __Pyx_PyObject_Pop(((PyObject *)__pyx_v_candidate)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 950; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_PyObject_Pop(((PyObject *)__pyx_v_candidate)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 955; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_XDECREF(__pyx_v_curr);
     __pyx_v_curr = __pyx_t_2;
     __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":951
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":956
  *         while len(candidate) > 0:
  *             curr = candidate.pop()
  *             if curr[0] >= len(_columns):             # <<<<<<<<<<<<<<
  *                 continue
  *             if curr[0] not in result and min_dist <= curr[1] <= self.max_initial_size:
  */
-    __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_curr, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 951; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_curr, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_3 = PyObject_Length(__pyx_v__columns); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 951; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 951; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_Length(__pyx_v__columns); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_5 = PyObject_RichCompare(__pyx_t_2, __pyx_t_1, Py_GE); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 951; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyObject_RichCompare(__pyx_t_2, __pyx_t_1, Py_GE); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 951; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     if (__pyx_t_4) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":952
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":957
  *             curr = candidate.pop()
  *             if curr[0] >= len(_columns):
  *                 continue             # <<<<<<<<<<<<<<
@@ -46655,30 +46637,30 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
     }
     __pyx_L5:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":953
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":958
  *             if curr[0] >= len(_columns):
  *                 continue
  *             if curr[0] not in result and min_dist <= curr[1] <= self.max_initial_size:             # <<<<<<<<<<<<<<
  *                 result.append(curr[0]);
  *             curr_col = _columns[curr[0]]
  */
-    __pyx_t_5 = __Pyx_GetItemInt(__pyx_v_curr, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_GetItemInt(__pyx_v_curr, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 958; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_4 = (__Pyx_PySequence_Contains(__pyx_t_5, ((PyObject *)__pyx_v_result), Py_NE)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = (__Pyx_PySequence_Contains(__pyx_t_5, ((PyObject *)__pyx_v_result), Py_NE)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 958; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     if (__pyx_t_4) {
-      __pyx_t_5 = __Pyx_GetItemInt(__pyx_v_curr, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = __Pyx_GetItemInt(__pyx_v_curr, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 958; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_1 = PyObject_RichCompare(__pyx_v_min_dist, __pyx_t_5, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_RichCompare(__pyx_v_min_dist, __pyx_t_5, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 958; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       if (__Pyx_PyObject_IsTrue(__pyx_t_1)) {
         __Pyx_DECREF(__pyx_t_1);
-        __pyx_t_2 = PyInt_FromLong(__pyx_v_self->max_initial_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_2 = PyInt_FromLong(__pyx_v_self->max_initial_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 958; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
-        __pyx_t_1 = PyObject_RichCompare(__pyx_t_5, __pyx_t_2, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyObject_RichCompare(__pyx_t_5, __pyx_t_2, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 958; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       }
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 958; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       __pyx_t_7 = __pyx_t_6;
     } else {
@@ -46686,38 +46668,38 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
     }
     if (__pyx_t_7) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":954
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":959
  *                 continue
  *             if curr[0] not in result and min_dist <= curr[1] <= self.max_initial_size:
  *                 result.append(curr[0]);             # <<<<<<<<<<<<<<
  *             curr_col = _columns[curr[0]]
  *             for alt in curr_col:
  */
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_curr, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 954; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_curr, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 959; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_8 = PyList_Append(__pyx_v_result, __pyx_t_1); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 954; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyList_Append(__pyx_v_result, __pyx_t_1); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 959; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       goto __pyx_L6;
     }
     __pyx_L6:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":955
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":960
  *             if curr[0] not in result and min_dist <= curr[1] <= self.max_initial_size:
  *                 result.append(curr[0]);
  *             curr_col = _columns[curr[0]]             # <<<<<<<<<<<<<<
  *             for alt in curr_col:
  *                 next_id = curr[0]+alt[2]
  */
-    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_curr, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 955; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_curr, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 960; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_5 = PyObject_GetItem(__pyx_v__columns, __pyx_t_1); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 955; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyObject_GetItem(__pyx_v__columns, __pyx_t_1); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 960; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_XDECREF(__pyx_v_curr_col);
     __pyx_v_curr_col = __pyx_t_5;
     __pyx_t_5 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":956
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":961
  *                 result.append(curr[0]);
  *             curr_col = _columns[curr[0]]
  *             for alt in curr_col:             # <<<<<<<<<<<<<<
@@ -46728,7 +46710,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
       __pyx_t_5 = __pyx_v_curr_col; __Pyx_INCREF(__pyx_t_5); __pyx_t_3 = 0;
       __pyx_t_9 = NULL;
     } else {
-      __pyx_t_3 = -1; __pyx_t_5 = PyObject_GetIter(__pyx_v_curr_col); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = -1; __pyx_t_5 = PyObject_GetIter(__pyx_v_curr_col); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
       __pyx_t_9 = Py_TYPE(__pyx_t_5)->tp_iternext;
     }
@@ -46736,23 +46718,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
       if (!__pyx_t_9 && PyList_CheckExact(__pyx_t_5)) {
         if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_5)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_1 = PyList_GET_ITEM(__pyx_t_5, __pyx_t_3); __Pyx_INCREF(__pyx_t_1); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyList_GET_ITEM(__pyx_t_5, __pyx_t_3); __Pyx_INCREF(__pyx_t_1); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_1 = PySequence_ITEM(__pyx_t_5, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PySequence_ITEM(__pyx_t_5, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else if (!__pyx_t_9 && PyTuple_CheckExact(__pyx_t_5)) {
         if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_5)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_5, __pyx_t_3); __Pyx_INCREF(__pyx_t_1); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_5, __pyx_t_3); __Pyx_INCREF(__pyx_t_1); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_1 = PySequence_ITEM(__pyx_t_5, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PySequence_ITEM(__pyx_t_5, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else {
         __pyx_t_1 = __pyx_t_9(__pyx_t_5);
         if (unlikely(!__pyx_t_1)) {
           if (PyErr_Occurred()) {
             if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           }
           break;
         }
@@ -46762,18 +46744,18 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
       __pyx_v_alt = __pyx_t_1;
       __pyx_t_1 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":957
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":962
  *             curr_col = _columns[curr[0]]
  *             for alt in curr_col:
  *                 next_id = curr[0]+alt[2]             # <<<<<<<<<<<<<<
  *                 jump = 1
  *                 if (alt[0] == EPSILON):
  */
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_curr, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_curr, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 962; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_alt, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_alt, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 962; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_10 = PyNumber_Add(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_10 = PyNumber_Add(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 962; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_10);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -46781,7 +46763,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
       __pyx_v_next_id = __pyx_t_10;
       __pyx_t_10 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":958
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":963
  *             for alt in curr_col:
  *                 next_id = curr[0]+alt[2]
  *                 jump = 1             # <<<<<<<<<<<<<<
@@ -46792,25 +46774,25 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
       __Pyx_XDECREF(__pyx_v_jump);
       __pyx_v_jump = __pyx_int_1;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":959
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":964
  *                 next_id = curr[0]+alt[2]
  *                 jump = 1
  *                 if (alt[0] == EPSILON):             # <<<<<<<<<<<<<<
  *                     jump = 0
  *                 if next_id not in result and min_dist <= curr[1]+jump <= self.max_initial_size+1:
  */
-      __pyx_t_10 = __Pyx_GetItemInt(__pyx_v_alt, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_10) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 959; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_10 = __Pyx_GetItemInt(__pyx_v_alt, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_10) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 964; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_10);
-      __pyx_t_2 = PyInt_FromLong(__pyx_v_3_sa_EPSILON); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 959; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyInt_FromLong(__pyx_v_3_sa_EPSILON); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 964; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_1 = PyObject_RichCompare(__pyx_t_10, __pyx_t_2, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 959; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_RichCompare(__pyx_t_10, __pyx_t_2, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 964; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 959; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 964; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       if (__pyx_t_7) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":960
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":965
  *                 jump = 1
  *                 if (alt[0] == EPSILON):
  *                     jump = 0             # <<<<<<<<<<<<<<
@@ -46824,30 +46806,30 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
       }
       __pyx_L9:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":961
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":966
  *                 if (alt[0] == EPSILON):
  *                     jump = 0
  *                 if next_id not in result and min_dist <= curr[1]+jump <= self.max_initial_size+1:             # <<<<<<<<<<<<<<
  *                     candidate.append([next_id,curr[1]+jump])
  *         return sorted(result);
  */
-      __pyx_t_7 = (__Pyx_PySequence_Contains(__pyx_v_next_id, ((PyObject *)__pyx_v_result), Py_NE)); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = (__Pyx_PySequence_Contains(__pyx_v_next_id, ((PyObject *)__pyx_v_result), Py_NE)); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       if (__pyx_t_7) {
-        __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_curr, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_curr, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
-        __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_v_jump); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_v_jump); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-        __pyx_t_1 = PyObject_RichCompare(__pyx_v_min_dist, __pyx_t_2, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyObject_RichCompare(__pyx_v_min_dist, __pyx_t_2, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         if (__Pyx_PyObject_IsTrue(__pyx_t_1)) {
           __Pyx_DECREF(__pyx_t_1);
-          __pyx_t_10 = PyInt_FromLong((__pyx_v_self->max_initial_size + 1)); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_10 = PyInt_FromLong((__pyx_v_self->max_initial_size + 1)); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_10);
-          __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_10, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_10, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
         }
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-        __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
         __pyx_t_6 = __pyx_t_4;
       } else {
@@ -46855,19 +46837,19 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
       }
       if (__pyx_t_6) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":962
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":967
  *                     jump = 0
  *                 if next_id not in result and min_dist <= curr[1]+jump <= self.max_initial_size+1:
  *                     candidate.append([next_id,curr[1]+jump])             # <<<<<<<<<<<<<<
  *         return sorted(result);
  * 
  */
-        __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_curr, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 962; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_curr, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
-        __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_v_jump); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 962; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_v_jump); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-        __pyx_t_1 = PyList_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 962; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyList_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
         __Pyx_INCREF(__pyx_v_next_id);
         PyList_SET_ITEM(__pyx_t_1, 0, __pyx_v_next_id);
@@ -46875,7 +46857,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
         PyList_SET_ITEM(__pyx_t_1, 1, __pyx_t_2);
         __Pyx_GIVEREF(__pyx_t_2);
         __pyx_t_2 = 0;
-        __pyx_t_8 = PyList_Append(__pyx_v_candidate, ((PyObject *)__pyx_t_1)); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 962; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_8 = PyList_Append(__pyx_v_candidate, ((PyObject *)__pyx_t_1)); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
         goto __pyx_L10;
       }
@@ -46885,7 +46867,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
     __pyx_L3_continue:;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":963
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":968
  *                 if next_id not in result and min_dist <= curr[1]+jump <= self.max_initial_size+1:
  *                     candidate.append([next_id,curr[1]+jump])
  *         return sorted(result);             # <<<<<<<<<<<<<<
@@ -46893,12 +46875,12 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
  *     def input(self, fwords, meta):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 963; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_INCREF(((PyObject *)__pyx_v_result));
   PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)__pyx_v_result));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_result));
-  __pyx_t_1 = PyObject_Call(__pyx_builtin_sorted, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 963; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(__pyx_builtin_sorted, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
   __pyx_r = __pyx_t_1;
@@ -46957,11 +46939,11 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_23input(PyObject *__pyx
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__meta)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("input", 1, 2, 2, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 965; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("input", 1, 2, 2, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 970; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "input") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 965; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "input") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 970; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -46974,7 +46956,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_23input(PyObject *__pyx
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("input", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 965; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("input", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 970; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.input", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -47009,7 +46991,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_5input_7lambda4_lambda5
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1130
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1135
  *                         if len(extracts) > 0:
  *                             fcount = Counter()
  *                             fphrases = defaultdict(lambda: defaultdict(lambda: defaultdict(list)))             # <<<<<<<<<<<<<<
@@ -47028,14 +47010,14 @@ static PyObject *__pyx_lambda_funcdef_lambda5(CYTHON_UNUSED PyObject *__pyx_self
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("lambda5", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_INCREF(((PyObject *)((PyObject*)(&PyList_Type))));
   PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)((PyObject*)(&PyList_Type))));
   __Pyx_GIVEREF(((PyObject *)((PyObject*)(&PyList_Type))));
-  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
@@ -47068,16 +47050,16 @@ static PyObject *__pyx_lambda_funcdef_lambda4(CYTHON_UNUSED PyObject *__pyx_self
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("lambda4", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_5input_7lambda4_lambda5, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_5input_7lambda4_lambda5, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
   __Pyx_GIVEREF(__pyx_t_2);
   __pyx_t_2 = 0;
-  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
@@ -47111,7 +47093,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_5input_1lambda6(PyObjec
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1136
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1141
  *                             for f, elist in fphrases.iteritems():
  *                                 for e, alslist in elist.iteritems():
  *                                     alignment, max_locs = max(alslist.iteritems(), key=lambda x: len(x[1]))             # <<<<<<<<<<<<<<
@@ -47129,11 +47111,11 @@ static PyObject *__pyx_lambda_funcdef_lambda6(CYTHON_UNUSED PyObject *__pyx_self
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("lambda6", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_x, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_x, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -47152,12 +47134,12 @@ static PyObject *__pyx_lambda_funcdef_lambda6(CYTHON_UNUSED PyObject *__pyx_self
 }
 static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_5input_4generator14(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value); /* proto */
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1175
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1180
  *         # Online rule extraction and scoring
  *         if self.online:
  *             f_syms = tuple(word[0][0] for word in fwords)             # <<<<<<<<<<<<<<
- *             for (f, e, spanlen) in self.online_match(f_syms, seen_phrases):
- *                 scores = self.scorer.score(FeatureContext(
+ *             for (f, lex_i, lex_j) in self.get_f_phrases(f_syms):
+ *                 spanlen = (lex_j - lex_i) + 1
  */
 
 static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_5input_2genexpr(PyObject *__pyx_self) {
@@ -47178,7 +47160,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_5input_2genexpr(PyObjec
   __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_outer_scope));
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_outer_scope);
   {
-    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_23HieroCachingRuleFactory_5input_4generator14, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_23HieroCachingRuleFactory_5input_4generator14, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_cur_scope);
     __Pyx_RefNannyFinishContext();
     return (PyObject *) gen;
@@ -47215,13 +47197,13 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_5input_4generator14(__p
     return NULL;
   }
   __pyx_L3_first_run:;
-  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_fwords)) { __Pyx_RaiseClosureNameError("fwords"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_fwords)) { __Pyx_RaiseClosureNameError("fwords"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
   if (PyList_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_fwords) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_fwords)) {
     __pyx_t_1 = __pyx_cur_scope->__pyx_outer_scope->__pyx_v_fwords; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
     __pyx_t_3 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_fwords); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_fwords); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -47229,23 +47211,23 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_5input_4generator14(__p
     if (!__pyx_t_3 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_3 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_4 = __pyx_t_3(__pyx_t_1);
       if (unlikely(!__pyx_t_4)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -47256,9 +47238,9 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_5input_4generator14(__p
     __Pyx_GIVEREF(__pyx_t_4);
     __pyx_cur_scope->__pyx_v_word = __pyx_t_4;
     __pyx_t_4 = 0;
-    __pyx_t_4 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_word, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_word, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = __Pyx_GetItemInt(__pyx_t_4, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_GetItemInt(__pyx_t_4, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __pyx_r = __pyx_t_5;
@@ -47278,7 +47260,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_5input_4generator14(__p
     __Pyx_XGOTREF(__pyx_t_1);
     __pyx_t_2 = __pyx_cur_scope->__pyx_t_1;
     __pyx_t_3 = __pyx_cur_scope->__pyx_t_2;
-    if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyErr_SetNone(PyExc_StopIteration);
@@ -47296,7 +47278,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_5input_4generator14(__p
   return NULL;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":965
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":970
  *         return sorted(result);
  * 
  *     def input(self, fwords, meta):             # <<<<<<<<<<<<<<
@@ -47328,7 +47310,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_22input(struct __pyx_ob
   __Pyx_INCREF(__pyx_cur_scope->__pyx_v_meta);
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_meta);
   {
-    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 965; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 970; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_cur_scope);
     __Pyx_RefNannyFinishContext();
     return (PyObject *) gen;
@@ -47378,20 +47360,21 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
   Py_ssize_t __pyx_t_26;
   int __pyx_t_27;
   int __pyx_t_28;
+  PyObject *(*__pyx_t_29)(PyObject *);
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("None", 0);
   switch (__pyx_generator->resume_label) {
     case 0: goto __pyx_L3_first_run;
     case 1: goto __pyx_L61_resume_from_yield;
-    case 2: goto __pyx_L77_resume_from_yield;
+    case 2: goto __pyx_L82_resume_from_yield;
     default: /* CPython raises the right error here */
     __Pyx_RefNannyFinishContext();
     return NULL;
   }
   __pyx_L3_first_run:;
-  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 965; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 970; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":976
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":981
  *         cdef Phrase hiero_phrase
  * 
  *         flen = len(fwords)             # <<<<<<<<<<<<<<
@@ -47400,11 +47383,11 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
   __pyx_t_1 = __pyx_cur_scope->__pyx_v_fwords;
   __Pyx_INCREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 976; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_cur_scope->__pyx_v_flen = __pyx_t_2;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":977
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":982
  * 
  *         flen = len(fwords)
  *         start_time = monitor_cpu()             # <<<<<<<<<<<<<<
@@ -47413,7 +47396,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
   __pyx_cur_scope->__pyx_v_start_time = __pyx_f_3_sa_monitor_cpu();
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":978
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":983
  *         flen = len(fwords)
  *         start_time = monitor_cpu()
  *         self.extract_time = 0.0             # <<<<<<<<<<<<<<
@@ -47422,20 +47405,20 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
   __pyx_cur_scope->__pyx_v_self->extract_time = 0.0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":979
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":984
  *         start_time = monitor_cpu()
  *         self.extract_time = 0.0
  *         nodes_isteps_away_buffer = {}             # <<<<<<<<<<<<<<
  *         hit = 0
  *         reachable_buffer = {}
  */
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 979; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
   __pyx_cur_scope->__pyx_v_nodes_isteps_away_buffer = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":980
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":985
  *         self.extract_time = 0.0
  *         nodes_isteps_away_buffer = {}
  *         hit = 0             # <<<<<<<<<<<<<<
@@ -47444,46 +47427,46 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
   __pyx_cur_scope->__pyx_v_hit = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":981
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":986
  *         nodes_isteps_away_buffer = {}
  *         hit = 0
  *         reachable_buffer = {}             # <<<<<<<<<<<<<<
  * 
  *         # Phrase pairs processed by suffix array extractor.  Do not re-extract
  */
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 986; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
   __pyx_cur_scope->__pyx_v_reachable_buffer = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":986
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":991
  *         # during online extraction.  This is probably the hackiest part of
  *         # online grammar extraction.
  *         seen_phrases = set()             # <<<<<<<<<<<<<<
  * 
  *         # Do not cache between sentences
  */
-  __pyx_t_1 = PySet_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 986; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PySet_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
   __pyx_cur_scope->__pyx_v_seen_phrases = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":989
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":994
  * 
  *         # Do not cache between sentences
  *         self.rules.root = ExtendedTrieNode(phrase_location=PhraseLocation())             # <<<<<<<<<<<<<<
  * 
  *         frontier = []
  */
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_PhraseLocation)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_PhraseLocation)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__phrase_location), __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__phrase_location), __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_ExtendedTrieNode)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_ExtendedTrieNode)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
   __Pyx_GIVEREF(__pyx_t_3);
@@ -47492,20 +47475,20 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
   __pyx_cur_scope->__pyx_v_self->rules->root = __pyx_t_3;
   __pyx_t_3 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":991
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":996
  *         self.rules.root = ExtendedTrieNode(phrase_location=PhraseLocation())
  * 
  *         frontier = []             # <<<<<<<<<<<<<<
  *         for i in range(len(fwords)):
  *             for alt in range(0, len(fwords[i])):
  */
-  __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_GIVEREF(((PyObject *)__pyx_t_3));
   __pyx_cur_scope->__pyx_v_frontier = __pyx_t_3;
   __pyx_t_3 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":992
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":997
  * 
  *         frontier = []
  *         for i in range(len(fwords)):             # <<<<<<<<<<<<<<
@@ -47514,72 +47497,72 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
   __pyx_t_3 = __pyx_cur_scope->__pyx_v_fwords;
   __Pyx_INCREF(__pyx_t_3);
-  __pyx_t_2 = PyObject_Length(__pyx_t_3); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 992; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Length(__pyx_t_3); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 997; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_2; __pyx_t_4+=1) {
     __pyx_cur_scope->__pyx_v_i = __pyx_t_4;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":993
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":998
  *         frontier = []
  *         for i in range(len(fwords)):
  *             for alt in range(0, len(fwords[i])):             # <<<<<<<<<<<<<<
  *                 if fwords[i][alt][0] != EPSILON:
  *                     frontier.append((i, i, (i,), alt, 0, self.rules.root, (), False))
  */
-    __pyx_t_3 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_fwords, __pyx_cur_scope->__pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_fwords, __pyx_cur_scope->__pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_5 = PyObject_Length(__pyx_t_3); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyObject_Length(__pyx_t_3); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
       __pyx_cur_scope->__pyx_v_alt = __pyx_t_6;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":994
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":999
  *         for i in range(len(fwords)):
  *             for alt in range(0, len(fwords[i])):
  *                 if fwords[i][alt][0] != EPSILON:             # <<<<<<<<<<<<<<
  *                     frontier.append((i, i, (i,), alt, 0, self.rules.root, (), False))
  * 
  */
-      __pyx_t_3 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_fwords, __pyx_cur_scope->__pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_fwords, __pyx_cur_scope->__pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_3, __pyx_cur_scope->__pyx_v_alt, sizeof(int), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_3, __pyx_cur_scope->__pyx_v_alt, sizeof(int), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_1 = PyInt_FromLong(__pyx_v_3_sa_EPSILON); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyInt_FromLong(__pyx_v_3_sa_EPSILON); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_7 = PyObject_RichCompare(__pyx_t_3, __pyx_t_1, Py_NE); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyObject_RichCompare(__pyx_t_3, __pyx_t_1, Py_NE); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       if (__pyx_t_8) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":995
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1000
  *             for alt in range(0, len(fwords[i])):
  *                 if fwords[i][alt][0] != EPSILON:
  *                     frontier.append((i, i, (i,), alt, 0, self.rules.root, (), False))             # <<<<<<<<<<<<<<
  * 
  *         xroot = None
  */
-        __pyx_t_7 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1000; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_7);
-        __pyx_t_1 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1000; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
-        __pyx_t_3 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1000; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_3);
-        __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1000; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_9);
         PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_3);
         __Pyx_GIVEREF(__pyx_t_3);
         __pyx_t_3 = 0;
-        __pyx_t_3 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_alt); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_alt); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1000; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_3);
-        __pyx_t_10 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_10 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1000; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_10);
-        __pyx_t_11 = PyTuple_New(8); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_11 = PyTuple_New(8); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1000; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_11);
         PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_7);
         __Pyx_GIVEREF(__pyx_t_7);
@@ -47605,7 +47588,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         __pyx_t_9 = 0;
         __pyx_t_3 = 0;
         __pyx_t_10 = 0;
-        __pyx_t_12 = PyList_Append(__pyx_cur_scope->__pyx_v_frontier, ((PyObject *)__pyx_t_11)); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_12 = PyList_Append(__pyx_cur_scope->__pyx_v_frontier, ((PyObject *)__pyx_t_11)); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1000; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(((PyObject *)__pyx_t_11)); __pyx_t_11 = 0;
         goto __pyx_L8;
       }
@@ -47613,7 +47596,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
     }
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":997
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1002
  *                     frontier.append((i, i, (i,), alt, 0, self.rules.root, (), False))
  * 
  *         xroot = None             # <<<<<<<<<<<<<<
@@ -47624,7 +47607,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
   __Pyx_GIVEREF(Py_None);
   __pyx_cur_scope->__pyx_v_xroot = Py_None;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":998
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1003
  * 
  *         xroot = None
  *         x1 = sym_setindex(self.category, 1)             # <<<<<<<<<<<<<<
@@ -47633,32 +47616,32 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
   __pyx_cur_scope->__pyx_v_x1 = __pyx_f_3_sa_sym_setindex(__pyx_cur_scope->__pyx_v_self->category, 1);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":999
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1004
  *         xroot = None
  *         x1 = sym_setindex(self.category, 1)
  *         if x1 in self.rules.root.children:             # <<<<<<<<<<<<<<
  *             xroot = self.rules.root.children[x1]
  *         else:
  */
-  __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_x1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_x1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1004; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_11);
-  __pyx_t_10 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_self->rules->root, __pyx_n_s__children); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_10 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_self->rules->root, __pyx_n_s__children); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1004; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_10);
-  __pyx_t_8 = (__Pyx_PySequence_Contains(__pyx_t_11, __pyx_t_10, Py_EQ)); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_8 = (__Pyx_PySequence_Contains(__pyx_t_11, __pyx_t_10, Py_EQ)); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1004; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
   __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
   if (__pyx_t_8) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1000
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1005
  *         x1 = sym_setindex(self.category, 1)
  *         if x1 in self.rules.root.children:
  *             xroot = self.rules.root.children[x1]             # <<<<<<<<<<<<<<
  *         else:
  *             xroot = ExtendedTrieNode(suffix_link=self.rules.root, phrase_location=PhraseLocation())
  */
-    __pyx_t_10 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_self->rules->root, __pyx_n_s__children); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1000; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_self->rules->root, __pyx_n_s__children); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1005; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_10);
-    __pyx_t_11 = __Pyx_GetItemInt(__pyx_t_10, __pyx_cur_scope->__pyx_v_x1, sizeof(int), PyInt_FromLong); if (!__pyx_t_11) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1000; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_11 = __Pyx_GetItemInt(__pyx_t_10, __pyx_cur_scope->__pyx_v_x1, sizeof(int), PyInt_FromLong); if (!__pyx_t_11) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1005; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_11);
     __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
     __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_xroot);
@@ -47670,21 +47653,21 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1002
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1007
  *             xroot = self.rules.root.children[x1]
  *         else:
  *             xroot = ExtendedTrieNode(suffix_link=self.rules.root, phrase_location=PhraseLocation())             # <<<<<<<<<<<<<<
  *             self.rules.root.children[x1] = xroot
  * 
  */
-    __pyx_t_11 = PyDict_New(); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1002; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_11 = PyDict_New(); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(((PyObject *)__pyx_t_11));
-    if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__suffix_link), __pyx_cur_scope->__pyx_v_self->rules->root) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1002; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_10 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_PhraseLocation)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1002; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__suffix_link), __pyx_cur_scope->__pyx_v_self->rules->root) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_PhraseLocation)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_10);
-    if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__phrase_location), __pyx_t_10) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1002; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__phrase_location), __pyx_t_10) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-    __pyx_t_10 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_ExtendedTrieNode)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_11)); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1002; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_ExtendedTrieNode)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_11)); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_10);
     __Pyx_DECREF(((PyObject *)__pyx_t_11)); __pyx_t_11 = 0;
     __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_xroot);
@@ -47693,21 +47676,21 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
     __pyx_cur_scope->__pyx_v_xroot = __pyx_t_10;
     __pyx_t_10 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1003
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1008
  *         else:
  *             xroot = ExtendedTrieNode(suffix_link=self.rules.root, phrase_location=PhraseLocation())
  *             self.rules.root.children[x1] = xroot             # <<<<<<<<<<<<<<
  * 
  *         for i in range(self.min_gap_size, len(fwords)):
  */
-    __pyx_t_10 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_self->rules->root, __pyx_n_s__children); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1003; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_self->rules->root, __pyx_n_s__children); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1008; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_10);
-    if (__Pyx_SetItemInt(__pyx_t_10, __pyx_cur_scope->__pyx_v_x1, __pyx_cur_scope->__pyx_v_xroot, sizeof(int), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1003; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (__Pyx_SetItemInt(__pyx_t_10, __pyx_cur_scope->__pyx_v_x1, __pyx_cur_scope->__pyx_v_xroot, sizeof(int), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1008; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
   }
   __pyx_L9:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1005
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1010
  *             self.rules.root.children[x1] = xroot
  * 
  *         for i in range(self.min_gap_size, len(fwords)):             # <<<<<<<<<<<<<<
@@ -47716,81 +47699,81 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
   __pyx_t_10 = __pyx_cur_scope->__pyx_v_fwords;
   __Pyx_INCREF(__pyx_t_10);
-  __pyx_t_2 = PyObject_Length(__pyx_t_10); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1005; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Length(__pyx_t_10); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
   for (__pyx_t_4 = __pyx_cur_scope->__pyx_v_self->min_gap_size; __pyx_t_4 < __pyx_t_2; __pyx_t_4+=1) {
     __pyx_cur_scope->__pyx_v_i = __pyx_t_4;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1006
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1011
  * 
  *         for i in range(self.min_gap_size, len(fwords)):
  *             for alt in range(0, len(fwords[i])):             # <<<<<<<<<<<<<<
  *                 if fwords[i][alt][0] != EPSILON:
  *                     frontier.append((i-self.min_gap_size, i, (i,), alt, self.min_gap_size, xroot, (x1,), True))
  */
-    __pyx_t_10 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_fwords, __pyx_cur_scope->__pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_10) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1006; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_fwords, __pyx_cur_scope->__pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_10) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_10);
-    __pyx_t_5 = PyObject_Length(__pyx_t_10); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1006; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyObject_Length(__pyx_t_10); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
     for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
       __pyx_cur_scope->__pyx_v_alt = __pyx_t_6;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1007
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1012
  *         for i in range(self.min_gap_size, len(fwords)):
  *             for alt in range(0, len(fwords[i])):
  *                 if fwords[i][alt][0] != EPSILON:             # <<<<<<<<<<<<<<
  *                     frontier.append((i-self.min_gap_size, i, (i,), alt, self.min_gap_size, xroot, (x1,), True))
  * 
  */
-      __pyx_t_10 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_fwords, __pyx_cur_scope->__pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_10) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_10 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_fwords, __pyx_cur_scope->__pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_10) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_10);
-      __pyx_t_11 = __Pyx_GetItemInt(__pyx_t_10, __pyx_cur_scope->__pyx_v_alt, sizeof(int), PyInt_FromLong); if (!__pyx_t_11) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_11 = __Pyx_GetItemInt(__pyx_t_10, __pyx_cur_scope->__pyx_v_alt, sizeof(int), PyInt_FromLong); if (!__pyx_t_11) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_11);
       __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-      __pyx_t_10 = __Pyx_GetItemInt(__pyx_t_11, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_10) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_10 = __Pyx_GetItemInt(__pyx_t_11, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_10) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_10);
       __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-      __pyx_t_11 = PyInt_FromLong(__pyx_v_3_sa_EPSILON); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_11 = PyInt_FromLong(__pyx_v_3_sa_EPSILON); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_11);
-      __pyx_t_3 = PyObject_RichCompare(__pyx_t_10, __pyx_t_11, Py_NE); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyObject_RichCompare(__pyx_t_10, __pyx_t_11, Py_NE); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
       __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-      __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
       if (__pyx_t_8) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1008
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1013
  *             for alt in range(0, len(fwords[i])):
  *                 if fwords[i][alt][0] != EPSILON:
  *                     frontier.append((i-self.min_gap_size, i, (i,), alt, self.min_gap_size, xroot, (x1,), True))             # <<<<<<<<<<<<<<
  * 
  *         next_states = []
  */
-        __pyx_t_3 = PyInt_FromLong((__pyx_cur_scope->__pyx_v_i - __pyx_cur_scope->__pyx_v_self->min_gap_size)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1008; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = PyInt_FromLong((__pyx_cur_scope->__pyx_v_i - __pyx_cur_scope->__pyx_v_self->min_gap_size)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_3);
-        __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1008; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_11);
-        __pyx_t_10 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1008; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_10 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_10);
-        __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1008; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_9);
         PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_10);
         __Pyx_GIVEREF(__pyx_t_10);
         __pyx_t_10 = 0;
-        __pyx_t_10 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_alt); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1008; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_10 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_alt); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_10);
-        __pyx_t_1 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->min_gap_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1008; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->min_gap_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
-        __pyx_t_7 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_x1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1008; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_x1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_7);
-        __pyx_t_13 = PyTuple_New(1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1008; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_13 = PyTuple_New(1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_13);
         PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_7);
         __Pyx_GIVEREF(__pyx_t_7);
         __pyx_t_7 = 0;
-        __pyx_t_7 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1008; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_7);
-        __pyx_t_14 = PyTuple_New(8); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1008; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_14 = PyTuple_New(8); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_14);
         PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_t_3);
         __Pyx_GIVEREF(__pyx_t_3);
@@ -47816,7 +47799,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         __pyx_t_1 = 0;
         __pyx_t_13 = 0;
         __pyx_t_7 = 0;
-        __pyx_t_12 = PyList_Append(__pyx_cur_scope->__pyx_v_frontier, ((PyObject *)__pyx_t_14)); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1008; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_12 = PyList_Append(__pyx_cur_scope->__pyx_v_frontier, ((PyObject *)__pyx_t_14)); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
         goto __pyx_L14;
       }
@@ -47824,20 +47807,20 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
     }
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1010
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1015
  *                     frontier.append((i-self.min_gap_size, i, (i,), alt, self.min_gap_size, xroot, (x1,), True))
  * 
  *         next_states = []             # <<<<<<<<<<<<<<
  *         for i in range(len(fwords)):
  *             next_states.append(self.get_next_states(fwords,i,self.min_gap_size))
  */
-  __pyx_t_14 = PyList_New(0); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_14 = PyList_New(0); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1015; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_14);
   __Pyx_GIVEREF(((PyObject *)__pyx_t_14));
   __pyx_cur_scope->__pyx_v_next_states = __pyx_t_14;
   __pyx_t_14 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1011
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1016
  * 
  *         next_states = []
  *         for i in range(len(fwords)):             # <<<<<<<<<<<<<<
@@ -47846,25 +47829,25 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
   __pyx_t_14 = __pyx_cur_scope->__pyx_v_fwords;
   __Pyx_INCREF(__pyx_t_14);
-  __pyx_t_2 = PyObject_Length(__pyx_t_14); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Length(__pyx_t_14); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1016; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
   for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_2; __pyx_t_4+=1) {
     __pyx_cur_scope->__pyx_v_i = __pyx_t_4;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1012
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1017
  *         next_states = []
  *         for i in range(len(fwords)):
  *             next_states.append(self.get_next_states(fwords,i,self.min_gap_size))             # <<<<<<<<<<<<<<
  * 
  *         while len(frontier) > 0:
  */
-    __pyx_t_14 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__get_next_states); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_14 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__get_next_states); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1017; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_14);
-    __pyx_t_7 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1017; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_7);
-    __pyx_t_13 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->min_gap_size); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_13 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->min_gap_size); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1017; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_13);
-    __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1017; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_INCREF(__pyx_cur_scope->__pyx_v_fwords);
     PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_cur_scope->__pyx_v_fwords);
@@ -47875,15 +47858,15 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
     __Pyx_GIVEREF(__pyx_t_13);
     __pyx_t_7 = 0;
     __pyx_t_13 = 0;
-    __pyx_t_13 = PyObject_Call(__pyx_t_14, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_13 = PyObject_Call(__pyx_t_14, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1017; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_13);
     __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-    __pyx_t_12 = PyList_Append(__pyx_cur_scope->__pyx_v_next_states, __pyx_t_13); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_12 = PyList_Append(__pyx_cur_scope->__pyx_v_next_states, __pyx_t_13); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1017; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1014
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1019
  *             next_states.append(self.get_next_states(fwords,i,self.min_gap_size))
  * 
  *         while len(frontier) > 0:             # <<<<<<<<<<<<<<
@@ -47891,18 +47874,18 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  *             for k, i, input_match, alt, pathlen, node, prefix, is_shadow_path in frontier:
  */
   while (1) {
-    __pyx_t_2 = PyList_GET_SIZE(((PyObject *)__pyx_cur_scope->__pyx_v_frontier)); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1014; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyList_GET_SIZE(((PyObject *)__pyx_cur_scope->__pyx_v_frontier)); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1019; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __pyx_t_8 = (__pyx_t_2 > 0);
     if (!__pyx_t_8) break;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1015
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1020
  * 
  *         while len(frontier) > 0:
  *             new_frontier = []             # <<<<<<<<<<<<<<
  *             for k, i, input_match, alt, pathlen, node, prefix, is_shadow_path in frontier:
  *                 word_id = fwords[i][alt][0]
  */
-    __pyx_t_13 = PyList_New(0); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1015; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_13 = PyList_New(0); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1020; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_13);
     __Pyx_XGOTREF(((PyObject *)__pyx_cur_scope->__pyx_v_new_frontier));
     __Pyx_XDECREF(((PyObject *)__pyx_cur_scope->__pyx_v_new_frontier));
@@ -47910,7 +47893,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
     __pyx_cur_scope->__pyx_v_new_frontier = __pyx_t_13;
     __pyx_t_13 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1016
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1021
  *         while len(frontier) > 0:
  *             new_frontier = []
  *             for k, i, input_match, alt, pathlen, node, prefix, is_shadow_path in frontier:             # <<<<<<<<<<<<<<
@@ -47921,9 +47904,9 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
     for (;;) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_13)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_1 = PyList_GET_ITEM(__pyx_t_13, __pyx_t_2); __Pyx_INCREF(__pyx_t_1); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1016; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyList_GET_ITEM(__pyx_t_13, __pyx_t_2); __Pyx_INCREF(__pyx_t_1); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_1 = PySequence_ITEM(__pyx_t_13, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1016; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PySequence_ITEM(__pyx_t_13, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
       if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) {
         PyObject* sequence = __pyx_t_1;
@@ -47935,7 +47918,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         if (unlikely(size != 8)) {
           if (size > 8) __Pyx_RaiseTooManyValuesError(8);
           else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-          {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1016; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         #if CYTHON_COMPILING_IN_CPYTHON
         if (likely(PyTuple_CheckExact(sequence))) {
@@ -47969,7 +47952,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         Py_ssize_t i;
         PyObject** temps[8] = {&__pyx_t_14,&__pyx_t_7,&__pyx_t_10,&__pyx_t_9,&__pyx_t_11,&__pyx_t_3,&__pyx_t_15,&__pyx_t_16};
         for (i=0; i < 8; i++) {
-          PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1016; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           *(temps[i]) = item;
         }
         #endif
@@ -47978,7 +47961,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       {
         Py_ssize_t index = -1;
         PyObject** temps[8] = {&__pyx_t_14,&__pyx_t_7,&__pyx_t_10,&__pyx_t_9,&__pyx_t_11,&__pyx_t_3,&__pyx_t_15,&__pyx_t_16};
-        __pyx_t_17 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_17)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1016; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_17 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_17)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_17);
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
         __pyx_t_18 = Py_TYPE(__pyx_t_17)->tp_iternext;
@@ -47987,7 +47970,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __Pyx_GOTREF(item);
           *(temps[index]) = item;
         }
-        if (__Pyx_IternextUnpackEndCheck(__pyx_t_18(__pyx_t_17), 8) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1016; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (__Pyx_IternextUnpackEndCheck(__pyx_t_18(__pyx_t_17), 8) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __pyx_t_18 = NULL;
         __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0;
         goto __pyx_L22_unpacking_done;
@@ -47995,14 +47978,14 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0;
         __pyx_t_18 = NULL;
         if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1016; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __pyx_L22_unpacking_done:;
       }
-      __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_t_14); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1016; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_t_14); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
-      __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_t_7); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1016; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_t_7); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-      __pyx_t_19 = __Pyx_PyInt_AsInt(__pyx_t_9); if (unlikely((__pyx_t_19 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1016; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_19 = __Pyx_PyInt_AsInt(__pyx_t_9); if (unlikely((__pyx_t_19 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
       __pyx_cur_scope->__pyx_v_k = __pyx_t_4;
       __pyx_cur_scope->__pyx_v_i = __pyx_t_6;
@@ -48033,19 +48016,19 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       __pyx_cur_scope->__pyx_v_is_shadow_path = __pyx_t_16;
       __pyx_t_16 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1017
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1022
  *             new_frontier = []
  *             for k, i, input_match, alt, pathlen, node, prefix, is_shadow_path in frontier:
  *                 word_id = fwords[i][alt][0]             # <<<<<<<<<<<<<<
  *                 spanlen = fwords[i][alt][2]
  *                 # TODO get rid of k -- pathlen is replacing it
  */
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_fwords, __pyx_cur_scope->__pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1017; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_fwords, __pyx_cur_scope->__pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1022; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_16 = __Pyx_GetItemInt(__pyx_t_1, __pyx_cur_scope->__pyx_v_alt, sizeof(int), PyInt_FromLong); if (!__pyx_t_16) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1017; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_16 = __Pyx_GetItemInt(__pyx_t_1, __pyx_cur_scope->__pyx_v_alt, sizeof(int), PyInt_FromLong); if (!__pyx_t_16) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1022; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_16);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_16, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1017; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_16, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1022; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
       __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_word_id);
@@ -48054,19 +48037,19 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       __pyx_cur_scope->__pyx_v_word_id = __pyx_t_1;
       __pyx_t_1 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1018
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1023
  *             for k, i, input_match, alt, pathlen, node, prefix, is_shadow_path in frontier:
  *                 word_id = fwords[i][alt][0]
  *                 spanlen = fwords[i][alt][2]             # <<<<<<<<<<<<<<
  *                 # TODO get rid of k -- pathlen is replacing it
  *                 if word_id == EPSILON:
  */
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_fwords, __pyx_cur_scope->__pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1018; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_fwords, __pyx_cur_scope->__pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_16 = __Pyx_GetItemInt(__pyx_t_1, __pyx_cur_scope->__pyx_v_alt, sizeof(int), PyInt_FromLong); if (!__pyx_t_16) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1018; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_16 = __Pyx_GetItemInt(__pyx_t_1, __pyx_cur_scope->__pyx_v_alt, sizeof(int), PyInt_FromLong); if (!__pyx_t_16) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_16);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_16, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1018; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_16, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
       __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_spanlen);
@@ -48075,47 +48058,47 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       __pyx_cur_scope->__pyx_v_spanlen = __pyx_t_1;
       __pyx_t_1 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1020
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1025
  *                 spanlen = fwords[i][alt][2]
  *                 # TODO get rid of k -- pathlen is replacing it
  *                 if word_id == EPSILON:             # <<<<<<<<<<<<<<
  *                     # skipping because word_id is epsilon
  *                     if i+spanlen >= len(fwords):
  */
-      __pyx_t_1 = PyInt_FromLong(__pyx_v_3_sa_EPSILON); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1020; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyInt_FromLong(__pyx_v_3_sa_EPSILON); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1025; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_16 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_word_id, __pyx_t_1, Py_EQ); __Pyx_XGOTREF(__pyx_t_16); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1020; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_16 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_word_id, __pyx_t_1, Py_EQ); __Pyx_XGOTREF(__pyx_t_16); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1025; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_16); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1020; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_16); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1025; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
       if (__pyx_t_8) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1022
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1027
  *                 if word_id == EPSILON:
  *                     # skipping because word_id is epsilon
  *                     if i+spanlen >= len(fwords):             # <<<<<<<<<<<<<<
  *                         continue
  *                     for nualt in range(0,len(fwords[i+spanlen])):
  */
-        __pyx_t_16 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1022; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_16 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1027; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_16);
-        __pyx_t_1 = PyNumber_Add(__pyx_t_16, __pyx_cur_scope->__pyx_v_spanlen); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1022; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyNumber_Add(__pyx_t_16, __pyx_cur_scope->__pyx_v_spanlen); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1027; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
         __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
         __pyx_t_16 = __pyx_cur_scope->__pyx_v_fwords;
         __Pyx_INCREF(__pyx_t_16);
-        __pyx_t_5 = PyObject_Length(__pyx_t_16); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1022; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = PyObject_Length(__pyx_t_16); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1027; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
-        __pyx_t_16 = PyInt_FromSsize_t(__pyx_t_5); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1022; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_16 = PyInt_FromSsize_t(__pyx_t_5); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1027; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_16);
-        __pyx_t_15 = PyObject_RichCompare(__pyx_t_1, __pyx_t_16, Py_GE); __Pyx_XGOTREF(__pyx_t_15); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1022; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_15 = PyObject_RichCompare(__pyx_t_1, __pyx_t_16, Py_GE); __Pyx_XGOTREF(__pyx_t_15); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1027; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
         __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
-        __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_15); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1022; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_15); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1027; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
         if (__pyx_t_8) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1023
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1028
  *                     # skipping because word_id is epsilon
  *                     if i+spanlen >= len(fwords):
  *                         continue             # <<<<<<<<<<<<<<
@@ -48127,43 +48110,43 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         }
         __pyx_L24:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1024
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1029
  *                     if i+spanlen >= len(fwords):
  *                         continue
  *                     for nualt in range(0,len(fwords[i+spanlen])):             # <<<<<<<<<<<<<<
  *                         frontier.append((k, i+spanlen, input_match, nualt, pathlen, node, prefix, is_shadow_path))
  *                     continue
  */
-        __pyx_t_15 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1024; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_15 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1029; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_15);
-        __pyx_t_16 = PyNumber_Add(__pyx_t_15, __pyx_cur_scope->__pyx_v_spanlen); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1024; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_16 = PyNumber_Add(__pyx_t_15, __pyx_cur_scope->__pyx_v_spanlen); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1029; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_16);
         __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
-        __pyx_t_15 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fwords, __pyx_t_16); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1024; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_15 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fwords, __pyx_t_16); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1029; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_15);
         __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
-        __pyx_t_5 = PyObject_Length(__pyx_t_15); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1024; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = PyObject_Length(__pyx_t_15); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1029; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
         for (__pyx_t_19 = 0; __pyx_t_19 < __pyx_t_5; __pyx_t_19+=1) {
           __pyx_cur_scope->__pyx_v_nualt = __pyx_t_19;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1025
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1030
  *                         continue
  *                     for nualt in range(0,len(fwords[i+spanlen])):
  *                         frontier.append((k, i+spanlen, input_match, nualt, pathlen, node, prefix, is_shadow_path))             # <<<<<<<<<<<<<<
  *                     continue
  * 
  */
-          __pyx_t_15 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_k); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1025; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_15 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_k); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_15);
-          __pyx_t_16 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1025; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_16 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_16);
-          __pyx_t_1 = PyNumber_Add(__pyx_t_16, __pyx_cur_scope->__pyx_v_spanlen); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1025; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_1 = PyNumber_Add(__pyx_t_16, __pyx_cur_scope->__pyx_v_spanlen); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_1);
           __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
-          __pyx_t_16 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_nualt); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1025; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_16 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_nualt); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_16);
-          __pyx_t_3 = PyTuple_New(8); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1025; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_3 = PyTuple_New(8); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_3);
           PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_15);
           __Pyx_GIVEREF(__pyx_t_15);
@@ -48189,11 +48172,11 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __pyx_t_15 = 0;
           __pyx_t_1 = 0;
           __pyx_t_16 = 0;
-          __pyx_t_12 = PyList_Append(__pyx_cur_scope->__pyx_v_frontier, ((PyObject *)__pyx_t_3)); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1025; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_12 = PyList_Append(__pyx_cur_scope->__pyx_v_frontier, ((PyObject *)__pyx_t_3)); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
         }
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1026
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1031
  *                     for nualt in range(0,len(fwords[i+spanlen])):
  *                         frontier.append((k, i+spanlen, input_match, nualt, pathlen, node, prefix, is_shadow_path))
  *                     continue             # <<<<<<<<<<<<<<
@@ -48205,19 +48188,19 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       }
       __pyx_L23:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1028
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1033
  *                     continue
  * 
  *                 phrase = prefix + (word_id,)             # <<<<<<<<<<<<<<
  *                 hiero_phrase = Phrase(phrase)
  *                 arity = hiero_phrase.arity()
  */
-      __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1028; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_INCREF(__pyx_cur_scope->__pyx_v_word_id);
       PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_cur_scope->__pyx_v_word_id);
       __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_word_id);
-      __pyx_t_16 = PyNumber_Add(__pyx_cur_scope->__pyx_v_prefix, ((PyObject *)__pyx_t_3)); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1028; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_16 = PyNumber_Add(__pyx_cur_scope->__pyx_v_prefix, ((PyObject *)__pyx_t_3)); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_16);
       __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
       __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_phrase);
@@ -48226,19 +48209,19 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       __pyx_cur_scope->__pyx_v_phrase = __pyx_t_16;
       __pyx_t_16 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1029
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1034
  * 
  *                 phrase = prefix + (word_id,)
  *                 hiero_phrase = Phrase(phrase)             # <<<<<<<<<<<<<<
  *                 arity = hiero_phrase.arity()
  * 
  */
-      __pyx_t_16 = PyTuple_New(1); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1029; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_16 = PyTuple_New(1); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1034; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_16);
       __Pyx_INCREF(__pyx_cur_scope->__pyx_v_phrase);
       PyTuple_SET_ITEM(__pyx_t_16, 0, __pyx_cur_scope->__pyx_v_phrase);
       __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_phrase);
-      __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_16), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1029; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_16), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1034; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(((PyObject *)__pyx_t_16)); __pyx_t_16 = 0;
       __Pyx_XGOTREF(((PyObject *)__pyx_cur_scope->__pyx_v_hiero_phrase));
@@ -48247,23 +48230,23 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       __pyx_cur_scope->__pyx_v_hiero_phrase = ((struct __pyx_obj_3_sa_Phrase *)__pyx_t_3);
       __pyx_t_3 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1030
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1035
  *                 phrase = prefix + (word_id,)
  *                 hiero_phrase = Phrase(phrase)
  *                 arity = hiero_phrase.arity()             # <<<<<<<<<<<<<<
  * 
  *                 lookup_required = False
  */
-      __pyx_t_3 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_hiero_phrase), __pyx_n_s__arity); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_hiero_phrase), __pyx_n_s__arity); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_16 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_16 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_16);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_19 = __Pyx_PyInt_AsInt(__pyx_t_16); if (unlikely((__pyx_t_19 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_19 = __Pyx_PyInt_AsInt(__pyx_t_16); if (unlikely((__pyx_t_19 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
       __pyx_cur_scope->__pyx_v_arity = __pyx_t_19;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1032
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1037
  *                 arity = hiero_phrase.arity()
  * 
  *                 lookup_required = False             # <<<<<<<<<<<<<<
@@ -48272,36 +48255,36 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
       __pyx_cur_scope->__pyx_v_lookup_required = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1033
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1038
  * 
  *                 lookup_required = False
  *                 if word_id in node.children:             # <<<<<<<<<<<<<<
  *                     if node.children[word_id] is None:
  *                         # Path dead-ends at this node
  */
-      __pyx_t_16 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_16 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1038; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_16);
-      __pyx_t_8 = (__Pyx_PySequence_Contains(__pyx_cur_scope->__pyx_v_word_id, __pyx_t_16, Py_EQ)); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = (__Pyx_PySequence_Contains(__pyx_cur_scope->__pyx_v_word_id, __pyx_t_16, Py_EQ)); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1038; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
       if (__pyx_t_8) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1034
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1039
  *                 lookup_required = False
  *                 if word_id in node.children:
  *                     if node.children[word_id] is None:             # <<<<<<<<<<<<<<
  *                         # Path dead-ends at this node
  *                         continue
  */
-        __pyx_t_16 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1034; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_16 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_16);
-        __pyx_t_3 = PyObject_GetItem(__pyx_t_16, __pyx_cur_scope->__pyx_v_word_id); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1034; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = PyObject_GetItem(__pyx_t_16, __pyx_cur_scope->__pyx_v_word_id); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
         __pyx_t_8 = (__pyx_t_3 == Py_None);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         if (__pyx_t_8) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1036
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1041
  *                     if node.children[word_id] is None:
  *                         # Path dead-ends at this node
  *                         continue             # <<<<<<<<<<<<<<
@@ -48313,16 +48296,16 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         }
         /*else*/ {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1039
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1044
  *                     else:
  *                         # Path continues at this node
  *                         node = node.children[word_id]             # <<<<<<<<<<<<<<
  *                 else:
  *                     if node.suffix_link is None:
  */
-          __pyx_t_3 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_3 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1044; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_3);
-          __pyx_t_16 = PyObject_GetItem(__pyx_t_3, __pyx_cur_scope->__pyx_v_word_id); if (!__pyx_t_16) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_16 = PyObject_GetItem(__pyx_t_3, __pyx_cur_scope->__pyx_v_word_id); if (!__pyx_t_16) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1044; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_16);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
           __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_node);
@@ -48336,20 +48319,20 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       }
       /*else*/ {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1041
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1046
  *                         node = node.children[word_id]
  *                 else:
  *                     if node.suffix_link is None:             # <<<<<<<<<<<<<<
  *                         # Current node is root; lookup required
  *                         lookup_required = True
  */
-        __pyx_t_16 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1041; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_16 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1046; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_16);
         __pyx_t_8 = (__pyx_t_16 == Py_None);
         __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
         if (__pyx_t_8) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1043
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1048
  *                     if node.suffix_link is None:
  *                         # Current node is root; lookup required
  *                         lookup_required = True             # <<<<<<<<<<<<<<
@@ -48361,54 +48344,54 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         }
         /*else*/ {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1045
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1050
  *                         lookup_required = True
  *                     else:
  *                         if word_id in node.suffix_link.children:             # <<<<<<<<<<<<<<
  *                             if node.suffix_link.children[word_id] is None:
  *                                 # Suffix link reports path is dead end
  */
-          __pyx_t_16 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1045; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_16 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_16);
-          __pyx_t_3 = PyObject_GetAttr(__pyx_t_16, __pyx_n_s__children); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1045; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_3 = PyObject_GetAttr(__pyx_t_16, __pyx_n_s__children); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_3);
           __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
-          __pyx_t_8 = (__Pyx_PySequence_Contains(__pyx_cur_scope->__pyx_v_word_id, __pyx_t_3, Py_EQ)); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1045; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_8 = (__Pyx_PySequence_Contains(__pyx_cur_scope->__pyx_v_word_id, __pyx_t_3, Py_EQ)); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
           if (__pyx_t_8) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1046
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1051
  *                     else:
  *                         if word_id in node.suffix_link.children:
  *                             if node.suffix_link.children[word_id] is None:             # <<<<<<<<<<<<<<
  *                                 # Suffix link reports path is dead end
  *                                 node.children[word_id] = None
  */
-            __pyx_t_3 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1046; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1051; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_3);
-            __pyx_t_16 = PyObject_GetAttr(__pyx_t_3, __pyx_n_s__children); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1046; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_16 = PyObject_GetAttr(__pyx_t_3, __pyx_n_s__children); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1051; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_16);
             __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-            __pyx_t_3 = PyObject_GetItem(__pyx_t_16, __pyx_cur_scope->__pyx_v_word_id); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1046; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = PyObject_GetItem(__pyx_t_16, __pyx_cur_scope->__pyx_v_word_id); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1051; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_3);
             __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
             __pyx_t_8 = (__pyx_t_3 == Py_None);
             __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
             if (__pyx_t_8) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1048
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1053
  *                             if node.suffix_link.children[word_id] is None:
  *                                 # Suffix link reports path is dead end
  *                                 node.children[word_id] = None             # <<<<<<<<<<<<<<
  *                                 continue
  *                             else:
  */
-              __pyx_t_3 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1048; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_3 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_3);
-              if (PyObject_SetItem(__pyx_t_3, __pyx_cur_scope->__pyx_v_word_id, Py_None) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1048; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              if (PyObject_SetItem(__pyx_t_3, __pyx_cur_scope->__pyx_v_word_id, Py_None) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1049
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1054
  *                                 # Suffix link reports path is dead end
  *                                 node.children[word_id] = None
  *                                 continue             # <<<<<<<<<<<<<<
@@ -48420,7 +48403,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             }
             /*else*/ {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1052
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1057
  *                             else:
  *                                 # Suffix link indicates lookup is reqired
  *                                 lookup_required = True             # <<<<<<<<<<<<<<
@@ -48434,18 +48417,18 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           }
           /*else*/ {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1055
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1060
  *                         else:
  *                             #ERROR: We never get here
  *                             raise Exception("Keyword trie error")             # <<<<<<<<<<<<<<
  *                 # checking whether lookup_required
  *                 if lookup_required:
  */
-            __pyx_t_3 = PyObject_Call(__pyx_builtin_Exception, ((PyObject *)__pyx_k_tuple_122), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1055; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = PyObject_Call(__pyx_builtin_Exception, ((PyObject *)__pyx_k_tuple_122), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1060; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 1055; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1060; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           }
           __pyx_L30:;
         }
@@ -48453,7 +48436,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       }
       __pyx_L27:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1057
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1062
  *                             raise Exception("Keyword trie error")
  *                 # checking whether lookup_required
  *                 if lookup_required:             # <<<<<<<<<<<<<<
@@ -48462,7 +48445,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
       if (__pyx_cur_scope->__pyx_v_lookup_required) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1058
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1063
  *                 # checking whether lookup_required
  *                 if lookup_required:
  *                     new_node = None             # <<<<<<<<<<<<<<
@@ -48475,66 +48458,66 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         __Pyx_GIVEREF(Py_None);
         __pyx_cur_scope->__pyx_v_new_node = Py_None;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1059
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1064
  *                 if lookup_required:
  *                     new_node = None
  *                     if is_shadow_path:             # <<<<<<<<<<<<<<
  *                         # Extending shadow path
  *                         # on the shadow path we don't do any search, we just use info from suffix link
  */
-        __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_cur_scope->__pyx_v_is_shadow_path); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1059; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_cur_scope->__pyx_v_is_shadow_path); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1064; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         if (__pyx_t_8) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1062
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1067
  *                         # Extending shadow path
  *                         # on the shadow path we don't do any search, we just use info from suffix link
  *                         new_node = ExtendedTrieNode(phrase_location=node.suffix_link.children[word_id].phrase_location,             # <<<<<<<<<<<<<<
  *                                 suffix_link=node.suffix_link.children[word_id],
  *                                 phrase=hiero_phrase)
  */
-          __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1062; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(((PyObject *)__pyx_t_3));
-          __pyx_t_16 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1062; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_16 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_16);
-          __pyx_t_1 = PyObject_GetAttr(__pyx_t_16, __pyx_n_s__children); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1062; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_1 = PyObject_GetAttr(__pyx_t_16, __pyx_n_s__children); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_1);
           __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
-          __pyx_t_16 = PyObject_GetItem(__pyx_t_1, __pyx_cur_scope->__pyx_v_word_id); if (!__pyx_t_16) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1062; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_16 = PyObject_GetItem(__pyx_t_1, __pyx_cur_scope->__pyx_v_word_id); if (!__pyx_t_16) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_16);
           __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-          __pyx_t_1 = PyObject_GetAttr(__pyx_t_16, __pyx_n_s__phrase_location); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1062; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_1 = PyObject_GetAttr(__pyx_t_16, __pyx_n_s__phrase_location); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_1);
           __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
-          if (PyDict_SetItem(__pyx_t_3, ((PyObject *)__pyx_n_s__phrase_location), __pyx_t_1) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1062; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          if (PyDict_SetItem(__pyx_t_3, ((PyObject *)__pyx_n_s__phrase_location), __pyx_t_1) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1063
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1068
  *                         # on the shadow path we don't do any search, we just use info from suffix link
  *                         new_node = ExtendedTrieNode(phrase_location=node.suffix_link.children[word_id].phrase_location,
  *                                 suffix_link=node.suffix_link.children[word_id],             # <<<<<<<<<<<<<<
  *                                 phrase=hiero_phrase)
  *                     else:
  */
-          __pyx_t_1 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1063; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_1 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1068; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_1);
-          __pyx_t_16 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__children); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1063; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_16 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__children); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1068; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_16);
           __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-          __pyx_t_1 = PyObject_GetItem(__pyx_t_16, __pyx_cur_scope->__pyx_v_word_id); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1063; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_1 = PyObject_GetItem(__pyx_t_16, __pyx_cur_scope->__pyx_v_word_id); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1068; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_1);
           __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
-          if (PyDict_SetItem(__pyx_t_3, ((PyObject *)__pyx_n_s__suffix_link), __pyx_t_1) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1062; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          if (PyDict_SetItem(__pyx_t_3, ((PyObject *)__pyx_n_s__suffix_link), __pyx_t_1) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1064
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1069
  *                         new_node = ExtendedTrieNode(phrase_location=node.suffix_link.children[word_id].phrase_location,
  *                                 suffix_link=node.suffix_link.children[word_id],
  *                                 phrase=hiero_phrase)             # <<<<<<<<<<<<<<
  *                     else:
  *                         if arity > 0:
  */
-          if (PyDict_SetItem(__pyx_t_3, ((PyObject *)__pyx_n_s__phrase), ((PyObject *)__pyx_cur_scope->__pyx_v_hiero_phrase)) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1062; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-          __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_ExtendedTrieNode)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_3)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1062; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          if (PyDict_SetItem(__pyx_t_3, ((PyObject *)__pyx_n_s__phrase), ((PyObject *)__pyx_cur_scope->__pyx_v_hiero_phrase)) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_ExtendedTrieNode)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_3)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_1);
           __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
           __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_new_node);
@@ -48546,7 +48529,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         }
         /*else*/ {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1066
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1071
  *                                 phrase=hiero_phrase)
  *                     else:
  *                         if arity > 0:             # <<<<<<<<<<<<<<
@@ -48556,22 +48539,22 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __pyx_t_8 = (__pyx_cur_scope->__pyx_v_arity > 0);
           if (__pyx_t_8) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1068
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1073
  *                         if arity > 0:
  *                             # Intersecting because of arity > 0
  *                             phrase_location = self.intersect(node, node.suffix_link.children[word_id], hiero_phrase)             # <<<<<<<<<<<<<<
  *                         else:
  *                             # Suffix array search
  */
-            __pyx_t_1 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1068; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_1 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_1);
-            __pyx_t_3 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__children); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1068; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__children); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_3);
             __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-            __pyx_t_1 = PyObject_GetItem(__pyx_t_3, __pyx_cur_scope->__pyx_v_word_id); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1068; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_1 = PyObject_GetItem(__pyx_t_3, __pyx_cur_scope->__pyx_v_word_id); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_1);
             __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-            __pyx_t_3 = ((PyObject *)((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_cur_scope->__pyx_v_self->__pyx_vtab)->intersect(__pyx_cur_scope->__pyx_v_self, __pyx_cur_scope->__pyx_v_node, __pyx_t_1, __pyx_cur_scope->__pyx_v_hiero_phrase)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1068; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = ((PyObject *)((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_cur_scope->__pyx_v_self->__pyx_vtab)->intersect(__pyx_cur_scope->__pyx_v_self, __pyx_cur_scope->__pyx_v_node, __pyx_t_1, __pyx_cur_scope->__pyx_v_hiero_phrase)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_3);
             __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
             __Pyx_XGOTREF(((PyObject *)__pyx_cur_scope->__pyx_v_phrase_location));
@@ -48583,45 +48566,45 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           }
           /*else*/ {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1071
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1076
  *                         else:
  *                             # Suffix array search
  *                             phrase_location = node.phrase_location             # <<<<<<<<<<<<<<
  *                             sa_range = self.fsa.lookup(sym_tostring(phrase[-1]), len(phrase)-1, phrase_location.sa_low, phrase_location.sa_high)
  *                             if sa_range is not None:
  */
-            __pyx_t_3 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__phrase_location); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1071; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__phrase_location); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1076; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_3);
-            if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_3_sa_PhraseLocation))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1071; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_3_sa_PhraseLocation))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1076; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_XGOTREF(((PyObject *)__pyx_cur_scope->__pyx_v_phrase_location));
             __Pyx_XDECREF(((PyObject *)__pyx_cur_scope->__pyx_v_phrase_location));
             __Pyx_GIVEREF(__pyx_t_3);
             __pyx_cur_scope->__pyx_v_phrase_location = ((struct __pyx_obj_3_sa_PhraseLocation *)__pyx_t_3);
             __pyx_t_3 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1072
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1077
  *                             # Suffix array search
  *                             phrase_location = node.phrase_location
  *                             sa_range = self.fsa.lookup(sym_tostring(phrase[-1]), len(phrase)-1, phrase_location.sa_low, phrase_location.sa_high)             # <<<<<<<<<<<<<<
  *                             if sa_range is not None:
  *                                 phrase_location = PhraseLocation(sa_low=sa_range[0], sa_high=sa_range[1])
  */
-            __pyx_t_3 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self->fsa), __pyx_n_s__lookup); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1072; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self->fsa), __pyx_n_s__lookup); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_3);
-            __pyx_t_1 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_phrase, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1072; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_1 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_phrase, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_1);
-            __pyx_t_19 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_19 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1072; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_19 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_19 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-            __pyx_t_1 = PyBytes_FromString(__pyx_f_3_sa_sym_tostring(__pyx_t_19)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1072; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_1 = PyBytes_FromString(__pyx_f_3_sa_sym_tostring(__pyx_t_19)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-            __pyx_t_5 = PyObject_Length(__pyx_cur_scope->__pyx_v_phrase); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1072; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-            __pyx_t_16 = PyInt_FromSsize_t((__pyx_t_5 - 1)); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1072; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_5 = PyObject_Length(__pyx_cur_scope->__pyx_v_phrase); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_16 = PyInt_FromSsize_t((__pyx_t_5 - 1)); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_16);
-            __pyx_t_15 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_phrase_location->sa_low); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1072; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_15 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_phrase_location->sa_low); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_15);
-            __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_phrase_location->sa_high); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1072; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_phrase_location->sa_high); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_11);
-            __pyx_t_9 = PyTuple_New(4); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1072; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_9 = PyTuple_New(4); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_9);
             PyTuple_SET_ITEM(__pyx_t_9, 0, ((PyObject *)__pyx_t_1));
             __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
@@ -48635,7 +48618,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __pyx_t_16 = 0;
             __pyx_t_15 = 0;
             __pyx_t_11 = 0;
-            __pyx_t_11 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1072; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_11 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_11);
             __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
             __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
@@ -48645,7 +48628,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __pyx_cur_scope->__pyx_v_sa_range = __pyx_t_11;
             __pyx_t_11 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1073
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1078
  *                             phrase_location = node.phrase_location
  *                             sa_range = self.fsa.lookup(sym_tostring(phrase[-1]), len(phrase)-1, phrase_location.sa_low, phrase_location.sa_high)
  *                             if sa_range is not None:             # <<<<<<<<<<<<<<
@@ -48655,24 +48638,24 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __pyx_t_8 = (__pyx_cur_scope->__pyx_v_sa_range != Py_None);
             if (__pyx_t_8) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1074
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1079
  *                             sa_range = self.fsa.lookup(sym_tostring(phrase[-1]), len(phrase)-1, phrase_location.sa_low, phrase_location.sa_high)
  *                             if sa_range is not None:
  *                                 phrase_location = PhraseLocation(sa_low=sa_range[0], sa_high=sa_range[1])             # <<<<<<<<<<<<<<
  *                             else:
  *                                 phrase_location = None
  */
-              __pyx_t_11 = PyDict_New(); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1074; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_11 = PyDict_New(); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1079; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(((PyObject *)__pyx_t_11));
-              __pyx_t_9 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_sa_range, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1074; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_9 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_sa_range, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1079; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_9);
-              if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__sa_low), __pyx_t_9) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1074; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__sa_low), __pyx_t_9) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1079; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-              __pyx_t_9 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_sa_range, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1074; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_9 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_sa_range, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1079; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_9);
-              if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__sa_high), __pyx_t_9) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1074; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__sa_high), __pyx_t_9) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1079; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-              __pyx_t_9 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_PhraseLocation)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_11)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1074; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_9 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_PhraseLocation)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_11)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1079; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_9);
               __Pyx_DECREF(((PyObject *)__pyx_t_11)); __pyx_t_11 = 0;
               __Pyx_GOTREF(((PyObject *)__pyx_cur_scope->__pyx_v_phrase_location));
@@ -48684,7 +48667,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             }
             /*else*/ {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1076
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1081
  *                                 phrase_location = PhraseLocation(sa_low=sa_range[0], sa_high=sa_range[1])
  *                             else:
  *                                 phrase_location = None             # <<<<<<<<<<<<<<
@@ -48701,7 +48684,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           }
           __pyx_L34:;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1078
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1083
  *                                 phrase_location = None
  * 
  *                         if phrase_location is None:             # <<<<<<<<<<<<<<
@@ -48711,19 +48694,19 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __pyx_t_8 = (((PyObject *)__pyx_cur_scope->__pyx_v_phrase_location) == Py_None);
           if (__pyx_t_8) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1079
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1084
  * 
  *                         if phrase_location is None:
  *                             node.children[word_id] = None             # <<<<<<<<<<<<<<
  *                             # Search failed
  *                             continue
  */
-            __pyx_t_9 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1079; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_9 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1084; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_9);
-            if (PyObject_SetItem(__pyx_t_9, __pyx_cur_scope->__pyx_v_word_id, Py_None) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1079; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            if (PyObject_SetItem(__pyx_t_9, __pyx_cur_scope->__pyx_v_word_id, Py_None) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1084; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1081
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1086
  *                             node.children[word_id] = None
  *                             # Search failed
  *                             continue             # <<<<<<<<<<<<<<
@@ -48735,7 +48718,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           }
           __pyx_L36:;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1083
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1088
  *                             continue
  *                         # Search succeeded
  *                         suffix_link = self.rules.root             # <<<<<<<<<<<<<<
@@ -48748,32 +48731,32 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_self->rules->root);
           __pyx_cur_scope->__pyx_v_suffix_link = __pyx_cur_scope->__pyx_v_self->rules->root;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1084
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1089
  *                         # Search succeeded
  *                         suffix_link = self.rules.root
  *                         if node.suffix_link is not None:             # <<<<<<<<<<<<<<
  *                             suffix_link = node.suffix_link.children[word_id]
  *                         new_node = ExtendedTrieNode(phrase_location=phrase_location,
  */
-          __pyx_t_9 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1084; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1089; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
           __pyx_t_8 = (__pyx_t_9 != Py_None);
           __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
           if (__pyx_t_8) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1085
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1090
  *                         suffix_link = self.rules.root
  *                         if node.suffix_link is not None:
  *                             suffix_link = node.suffix_link.children[word_id]             # <<<<<<<<<<<<<<
  *                         new_node = ExtendedTrieNode(phrase_location=phrase_location,
  *                                 suffix_link=suffix_link,
  */
-            __pyx_t_9 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1085; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_9 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1090; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_9);
-            __pyx_t_11 = PyObject_GetAttr(__pyx_t_9, __pyx_n_s__children); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1085; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_11 = PyObject_GetAttr(__pyx_t_9, __pyx_n_s__children); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1090; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_11);
             __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-            __pyx_t_9 = PyObject_GetItem(__pyx_t_11, __pyx_cur_scope->__pyx_v_word_id); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1085; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_9 = PyObject_GetItem(__pyx_t_11, __pyx_cur_scope->__pyx_v_word_id); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1090; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_9);
             __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
             __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_suffix_link);
@@ -48785,35 +48768,35 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           }
           __pyx_L37:;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1086
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1091
  *                         if node.suffix_link is not None:
  *                             suffix_link = node.suffix_link.children[word_id]
  *                         new_node = ExtendedTrieNode(phrase_location=phrase_location,             # <<<<<<<<<<<<<<
  *                                 suffix_link=suffix_link,
  *                                 phrase=hiero_phrase)
  */
-          __pyx_t_9 = PyDict_New(); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1086; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyDict_New(); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1091; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(((PyObject *)__pyx_t_9));
-          if (PyDict_SetItem(__pyx_t_9, ((PyObject *)__pyx_n_s__phrase_location), ((PyObject *)__pyx_cur_scope->__pyx_v_phrase_location)) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1086; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          if (PyDict_SetItem(__pyx_t_9, ((PyObject *)__pyx_n_s__phrase_location), ((PyObject *)__pyx_cur_scope->__pyx_v_phrase_location)) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1091; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1087
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1092
  *                             suffix_link = node.suffix_link.children[word_id]
  *                         new_node = ExtendedTrieNode(phrase_location=phrase_location,
  *                                 suffix_link=suffix_link,             # <<<<<<<<<<<<<<
  *                                 phrase=hiero_phrase)
  *                     node.children[word_id] = new_node
  */
-          if (PyDict_SetItem(__pyx_t_9, ((PyObject *)__pyx_n_s__suffix_link), __pyx_cur_scope->__pyx_v_suffix_link) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1086; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          if (PyDict_SetItem(__pyx_t_9, ((PyObject *)__pyx_n_s__suffix_link), __pyx_cur_scope->__pyx_v_suffix_link) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1091; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1088
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1093
  *                         new_node = ExtendedTrieNode(phrase_location=phrase_location,
  *                                 suffix_link=suffix_link,
  *                                 phrase=hiero_phrase)             # <<<<<<<<<<<<<<
  *                     node.children[word_id] = new_node
  *                     node = new_node
  */
-          if (PyDict_SetItem(__pyx_t_9, ((PyObject *)__pyx_n_s__phrase), ((PyObject *)__pyx_cur_scope->__pyx_v_hiero_phrase)) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1086; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-          __pyx_t_11 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_ExtendedTrieNode)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_9)); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1086; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          if (PyDict_SetItem(__pyx_t_9, ((PyObject *)__pyx_n_s__phrase), ((PyObject *)__pyx_cur_scope->__pyx_v_hiero_phrase)) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1091; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_ExtendedTrieNode)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_9)); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1091; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
           __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
           __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_new_node);
@@ -48824,19 +48807,19 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         }
         __pyx_L33:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1089
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1094
  *                                 suffix_link=suffix_link,
  *                                 phrase=hiero_phrase)
  *                     node.children[word_id] = new_node             # <<<<<<<<<<<<<<
  *                     node = new_node
  * 
  */
-        __pyx_t_11 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1089; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_11 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1094; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_11);
-        if (PyObject_SetItem(__pyx_t_11, __pyx_cur_scope->__pyx_v_word_id, __pyx_cur_scope->__pyx_v_new_node) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1089; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (PyObject_SetItem(__pyx_t_11, __pyx_cur_scope->__pyx_v_word_id, __pyx_cur_scope->__pyx_v_new_node) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1094; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1090
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1095
  *                                 phrase=hiero_phrase)
  *                     node.children[word_id] = new_node
  *                     node = new_node             # <<<<<<<<<<<<<<
@@ -48849,7 +48832,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_new_node);
         __pyx_cur_scope->__pyx_v_node = __pyx_cur_scope->__pyx_v_new_node;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1095
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1100
  *                     This should happen before we get to extraction (so that
  *                     the node will exist if needed)'''
  *                     if arity < self.max_nonterminals:             # <<<<<<<<<<<<<<
@@ -48859,14 +48842,14 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         __pyx_t_8 = (__pyx_cur_scope->__pyx_v_arity < __pyx_cur_scope->__pyx_v_self->max_nonterminals);
         if (__pyx_t_8) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1096
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1101
  *                     the node will exist if needed)'''
  *                     if arity < self.max_nonterminals:
  *                         xcat_index = arity+1             # <<<<<<<<<<<<<<
  *                         xcat = sym_setindex(self.category, xcat_index)
  *                         suffix_link_xcat_index = xcat_index
  */
-          __pyx_t_11 = PyInt_FromLong((__pyx_cur_scope->__pyx_v_arity + 1)); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1096; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyInt_FromLong((__pyx_cur_scope->__pyx_v_arity + 1)); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
           __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_xcat_index);
           __Pyx_XDECREF(__pyx_cur_scope->__pyx_v_xcat_index);
@@ -48874,17 +48857,17 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __pyx_cur_scope->__pyx_v_xcat_index = __pyx_t_11;
           __pyx_t_11 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1097
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1102
  *                     if arity < self.max_nonterminals:
  *                         xcat_index = arity+1
  *                         xcat = sym_setindex(self.category, xcat_index)             # <<<<<<<<<<<<<<
  *                         suffix_link_xcat_index = xcat_index
  *                         if is_shadow_path:
  */
-          __pyx_t_19 = __Pyx_PyInt_AsInt(__pyx_cur_scope->__pyx_v_xcat_index); if (unlikely((__pyx_t_19 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1097; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_19 = __Pyx_PyInt_AsInt(__pyx_cur_scope->__pyx_v_xcat_index); if (unlikely((__pyx_t_19 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __pyx_cur_scope->__pyx_v_xcat = __pyx_f_3_sa_sym_setindex(__pyx_cur_scope->__pyx_v_self->category, __pyx_t_19);
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1098
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1103
  *                         xcat_index = arity+1
  *                         xcat = sym_setindex(self.category, xcat_index)
  *                         suffix_link_xcat_index = xcat_index             # <<<<<<<<<<<<<<
@@ -48897,24 +48880,24 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_xcat_index);
           __pyx_cur_scope->__pyx_v_suffix_link_xcat_index = __pyx_cur_scope->__pyx_v_xcat_index;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1099
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1104
  *                         xcat = sym_setindex(self.category, xcat_index)
  *                         suffix_link_xcat_index = xcat_index
  *                         if is_shadow_path:             # <<<<<<<<<<<<<<
  *                             suffix_link_xcat_index = xcat_index-1
  *                         suffix_link_xcat = sym_setindex(self.category, suffix_link_xcat_index)
  */
-          __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_cur_scope->__pyx_v_is_shadow_path); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1099; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_cur_scope->__pyx_v_is_shadow_path); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           if (__pyx_t_8) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1100
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1105
  *                         suffix_link_xcat_index = xcat_index
  *                         if is_shadow_path:
  *                             suffix_link_xcat_index = xcat_index-1             # <<<<<<<<<<<<<<
  *                         suffix_link_xcat = sym_setindex(self.category, suffix_link_xcat_index)
  *                         node.children[xcat] = ExtendedTrieNode(phrase_location=node.phrase_location,
  */
-            __pyx_t_11 = PyNumber_Subtract(__pyx_cur_scope->__pyx_v_xcat_index, __pyx_int_1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_11 = PyNumber_Subtract(__pyx_cur_scope->__pyx_v_xcat_index, __pyx_int_1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_11);
             __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_suffix_link_xcat_index);
             __Pyx_DECREF(__pyx_cur_scope->__pyx_v_suffix_link_xcat_index);
@@ -48925,159 +48908,159 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           }
           __pyx_L39:;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1101
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1106
  *                         if is_shadow_path:
  *                             suffix_link_xcat_index = xcat_index-1
  *                         suffix_link_xcat = sym_setindex(self.category, suffix_link_xcat_index)             # <<<<<<<<<<<<<<
  *                         node.children[xcat] = ExtendedTrieNode(phrase_location=node.phrase_location,
  *                                 suffix_link=node.suffix_link.children[suffix_link_xcat],
  */
-          __pyx_t_19 = __Pyx_PyInt_AsInt(__pyx_cur_scope->__pyx_v_suffix_link_xcat_index); if (unlikely((__pyx_t_19 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_19 = __Pyx_PyInt_AsInt(__pyx_cur_scope->__pyx_v_suffix_link_xcat_index); if (unlikely((__pyx_t_19 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __pyx_cur_scope->__pyx_v_suffix_link_xcat = __pyx_f_3_sa_sym_setindex(__pyx_cur_scope->__pyx_v_self->category, __pyx_t_19);
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1102
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1107
  *                             suffix_link_xcat_index = xcat_index-1
  *                         suffix_link_xcat = sym_setindex(self.category, suffix_link_xcat_index)
  *                         node.children[xcat] = ExtendedTrieNode(phrase_location=node.phrase_location,             # <<<<<<<<<<<<<<
  *                                 suffix_link=node.suffix_link.children[suffix_link_xcat],
  *                                 phrase= Phrase(phrase + (xcat,)))
  */
-          __pyx_t_11 = PyDict_New(); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyDict_New(); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(((PyObject *)__pyx_t_11));
-          __pyx_t_9 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__phrase_location); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__phrase_location); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
-          if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__phrase_location), __pyx_t_9) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__phrase_location), __pyx_t_9) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1103
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1108
  *                         suffix_link_xcat = sym_setindex(self.category, suffix_link_xcat_index)
  *                         node.children[xcat] = ExtendedTrieNode(phrase_location=node.phrase_location,
  *                                 suffix_link=node.suffix_link.children[suffix_link_xcat],             # <<<<<<<<<<<<<<
  *                                 phrase= Phrase(phrase + (xcat,)))
  * 
  */
-          __pyx_t_9 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
-          __pyx_t_3 = PyObject_GetAttr(__pyx_t_9, __pyx_n_s__children); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_3 = PyObject_GetAttr(__pyx_t_9, __pyx_n_s__children); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_3);
           __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-          __pyx_t_9 = __Pyx_GetItemInt(__pyx_t_3, __pyx_cur_scope->__pyx_v_suffix_link_xcat, sizeof(int), PyInt_FromLong); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = __Pyx_GetItemInt(__pyx_t_3, __pyx_cur_scope->__pyx_v_suffix_link_xcat, sizeof(int), PyInt_FromLong); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-          if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__suffix_link), __pyx_t_9) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__suffix_link), __pyx_t_9) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1104
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1109
  *                         node.children[xcat] = ExtendedTrieNode(phrase_location=node.phrase_location,
  *                                 suffix_link=node.suffix_link.children[suffix_link_xcat],
  *                                 phrase= Phrase(phrase + (xcat,)))             # <<<<<<<<<<<<<<
  * 
  *                     # sample from range
  */
-          __pyx_t_9 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_xcat); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_xcat); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
-          __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_3);
           PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_9);
           __Pyx_GIVEREF(__pyx_t_9);
           __pyx_t_9 = 0;
-          __pyx_t_9 = PyNumber_Add(__pyx_cur_scope->__pyx_v_phrase, ((PyObject *)__pyx_t_3)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyNumber_Add(__pyx_cur_scope->__pyx_v_phrase, ((PyObject *)__pyx_t_3)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
           __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
-          __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_3);
           PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_9);
           __Pyx_GIVEREF(__pyx_t_9);
           __pyx_t_9 = 0;
-          __pyx_t_9 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
           __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
-          if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__phrase), __pyx_t_9) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__phrase), __pyx_t_9) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-          __pyx_t_9 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_ExtendedTrieNode)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_11)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_ExtendedTrieNode)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_11)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
           __Pyx_DECREF(((PyObject *)__pyx_t_11)); __pyx_t_11 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1102
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1107
  *                             suffix_link_xcat_index = xcat_index-1
  *                         suffix_link_xcat = sym_setindex(self.category, suffix_link_xcat_index)
  *                         node.children[xcat] = ExtendedTrieNode(phrase_location=node.phrase_location,             # <<<<<<<<<<<<<<
  *                                 suffix_link=node.suffix_link.children[suffix_link_xcat],
  *                                 phrase= Phrase(phrase + (xcat,)))
  */
-          __pyx_t_11 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
-          if (__Pyx_SetItemInt(__pyx_t_11, __pyx_cur_scope->__pyx_v_xcat, __pyx_t_9, sizeof(int), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          if (__Pyx_SetItemInt(__pyx_t_11, __pyx_cur_scope->__pyx_v_xcat, __pyx_t_9, sizeof(int), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
           __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
           goto __pyx_L38;
         }
         __pyx_L38:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1107
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1112
  * 
  *                     # sample from range
  *                     if not is_shadow_path:             # <<<<<<<<<<<<<<
  *                         sample = self.sampler.sample(node.phrase_location)
  *                         num_subpatterns = (<PhraseLocation> node.phrase_location).num_subpatterns
  */
-        __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_cur_scope->__pyx_v_is_shadow_path); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_cur_scope->__pyx_v_is_shadow_path); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __pyx_t_20 = (!__pyx_t_8);
         if (__pyx_t_20) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1108
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1113
  *                     # sample from range
  *                     if not is_shadow_path:
  *                         sample = self.sampler.sample(node.phrase_location)             # <<<<<<<<<<<<<<
  *                         num_subpatterns = (<PhraseLocation> node.phrase_location).num_subpatterns
  *                         chunklen = IntList(initial_len=num_subpatterns)
  */
-          __pyx_t_9 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self->sampler), __pyx_n_s__sample); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self->sampler), __pyx_n_s__sample); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
-          __pyx_t_11 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__phrase_location); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__phrase_location); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
-          __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_3);
           PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_11);
           __Pyx_GIVEREF(__pyx_t_11);
           __pyx_t_11 = 0;
-          __pyx_t_11 = PyObject_Call(__pyx_t_9, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyObject_Call(__pyx_t_9, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
           __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
           __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
-          if (!(likely(((__pyx_t_11) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_11, __pyx_ptype_3_sa_IntList))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          if (!(likely(((__pyx_t_11) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_11, __pyx_ptype_3_sa_IntList))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_XGOTREF(((PyObject *)__pyx_cur_scope->__pyx_v_sample));
           __Pyx_XDECREF(((PyObject *)__pyx_cur_scope->__pyx_v_sample));
           __Pyx_GIVEREF(__pyx_t_11);
           __pyx_cur_scope->__pyx_v_sample = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_11);
           __pyx_t_11 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1109
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1114
  *                     if not is_shadow_path:
  *                         sample = self.sampler.sample(node.phrase_location)
  *                         num_subpatterns = (<PhraseLocation> node.phrase_location).num_subpatterns             # <<<<<<<<<<<<<<
  *                         chunklen = IntList(initial_len=num_subpatterns)
  *                         for j from 0 <= j < num_subpatterns:
  */
-          __pyx_t_11 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__phrase_location); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__phrase_location); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
           __pyx_cur_scope->__pyx_v_num_subpatterns = ((struct __pyx_obj_3_sa_PhraseLocation *)__pyx_t_11)->num_subpatterns;
           __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1110
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1115
  *                         sample = self.sampler.sample(node.phrase_location)
  *                         num_subpatterns = (<PhraseLocation> node.phrase_location).num_subpatterns
  *                         chunklen = IntList(initial_len=num_subpatterns)             # <<<<<<<<<<<<<<
  *                         for j from 0 <= j < num_subpatterns:
  *                             chunklen.arr[j] = hiero_phrase.chunklen(j)
  */
-          __pyx_t_11 = PyDict_New(); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyDict_New(); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(((PyObject *)__pyx_t_11));
-          __pyx_t_3 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_num_subpatterns); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_3 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_num_subpatterns); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_3);
-          if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__initial_len), __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__initial_len), __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-          __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_11)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_11)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_3);
           __Pyx_DECREF(((PyObject *)__pyx_t_11)); __pyx_t_11 = 0;
           __Pyx_XGOTREF(((PyObject *)__pyx_cur_scope->__pyx_v_chunklen));
@@ -49086,7 +49069,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __pyx_cur_scope->__pyx_v_chunklen = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_3);
           __pyx_t_3 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1111
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1116
  *                         num_subpatterns = (<PhraseLocation> node.phrase_location).num_subpatterns
  *                         chunklen = IntList(initial_len=num_subpatterns)
  *                         for j from 0 <= j < num_subpatterns:             # <<<<<<<<<<<<<<
@@ -49096,7 +49079,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __pyx_t_19 = __pyx_cur_scope->__pyx_v_num_subpatterns;
           for (__pyx_cur_scope->__pyx_v_j = 0; __pyx_cur_scope->__pyx_v_j < __pyx_t_19; __pyx_cur_scope->__pyx_v_j++) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1112
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1117
  *                         chunklen = IntList(initial_len=num_subpatterns)
  *                         for j from 0 <= j < num_subpatterns:
  *                             chunklen.arr[j] = hiero_phrase.chunklen(j)             # <<<<<<<<<<<<<<
@@ -49106,14 +49089,14 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             (__pyx_cur_scope->__pyx_v_chunklen->arr[__pyx_cur_scope->__pyx_v_j]) = ((struct __pyx_vtabstruct_3_sa_Phrase *)__pyx_cur_scope->__pyx_v_hiero_phrase->__pyx_vtab)->chunklen(__pyx_cur_scope->__pyx_v_hiero_phrase, __pyx_cur_scope->__pyx_v_j);
           }
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1113
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1118
  *                         for j from 0 <= j < num_subpatterns:
  *                             chunklen.arr[j] = hiero_phrase.chunklen(j)
  *                         extracts = []             # <<<<<<<<<<<<<<
  *                         j = 0
  *                         extract_start = monitor_cpu()
  */
-          __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_3);
           __Pyx_XGOTREF(((PyObject *)__pyx_cur_scope->__pyx_v_extracts));
           __Pyx_XDECREF(((PyObject *)__pyx_cur_scope->__pyx_v_extracts));
@@ -49121,7 +49104,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __pyx_cur_scope->__pyx_v_extracts = __pyx_t_3;
           __pyx_t_3 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1114
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1119
  *                             chunklen.arr[j] = hiero_phrase.chunklen(j)
  *                         extracts = []
  *                         j = 0             # <<<<<<<<<<<<<<
@@ -49130,14 +49113,14 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
           __pyx_cur_scope->__pyx_v_j = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1115
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1120
  *                         extracts = []
  *                         j = 0
  *                         extract_start = monitor_cpu()             # <<<<<<<<<<<<<<
  *                         while j < sample.len:
  *                             extract = []
  */
-          __pyx_t_3 = PyFloat_FromDouble(__pyx_f_3_sa_monitor_cpu()); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_3 = PyFloat_FromDouble(__pyx_f_3_sa_monitor_cpu()); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_3);
           __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_extract_start);
           __Pyx_XDECREF(__pyx_cur_scope->__pyx_v_extract_start);
@@ -49145,7 +49128,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __pyx_cur_scope->__pyx_v_extract_start = __pyx_t_3;
           __pyx_t_3 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1116
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1121
  *                         j = 0
  *                         extract_start = monitor_cpu()
  *                         while j < sample.len:             # <<<<<<<<<<<<<<
@@ -49156,14 +49139,14 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __pyx_t_20 = (__pyx_cur_scope->__pyx_v_j < __pyx_cur_scope->__pyx_v_sample->len);
             if (!__pyx_t_20) break;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1117
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1122
  *                         extract_start = monitor_cpu()
  *                         while j < sample.len:
  *                             extract = []             # <<<<<<<<<<<<<<
  * 
  *                             assign_matching(&matching, sample.arr, j, num_subpatterns, self.fda.sent_id.arr)
  */
-            __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_3);
             __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_extract);
             __Pyx_XDECREF(__pyx_cur_scope->__pyx_v_extract);
@@ -49171,7 +49154,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __pyx_cur_scope->__pyx_v_extract = ((PyObject *)__pyx_t_3);
             __pyx_t_3 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1119
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1124
  *                             extract = []
  * 
  *                             assign_matching(&matching, sample.arr, j, num_subpatterns, self.fda.sent_id.arr)             # <<<<<<<<<<<<<<
@@ -49180,21 +49163,21 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
             __pyx_f_3_sa_assign_matching((&__pyx_cur_scope->__pyx_v_matching), __pyx_cur_scope->__pyx_v_sample->arr, __pyx_cur_scope->__pyx_v_j, __pyx_cur_scope->__pyx_v_num_subpatterns, __pyx_cur_scope->__pyx_v_self->fda->sent_id->arr);
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1120
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1125
  * 
  *                             assign_matching(&matching, sample.arr, j, num_subpatterns, self.fda.sent_id.arr)
  *                             loc = tuple(sample[j:j+num_subpatterns])             # <<<<<<<<<<<<<<
  *                             extract = self.extract(hiero_phrase, &matching, chunklen.arr, num_subpatterns)
  *                             extracts.extend([(e, loc) for e in extract])
  */
-            __pyx_t_3 = __Pyx_PySequence_GetSlice(((PyObject *)__pyx_cur_scope->__pyx_v_sample), __pyx_cur_scope->__pyx_v_j, (__pyx_cur_scope->__pyx_v_j + __pyx_cur_scope->__pyx_v_num_subpatterns)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = __Pyx_PySequence_GetSlice(((PyObject *)__pyx_cur_scope->__pyx_v_sample), __pyx_cur_scope->__pyx_v_j, (__pyx_cur_scope->__pyx_v_j + __pyx_cur_scope->__pyx_v_num_subpatterns)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_3);
-            __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_11);
             PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_3);
             __Pyx_GIVEREF(__pyx_t_3);
             __pyx_t_3 = 0;
-            __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_11), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_11), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_3);
             __Pyx_DECREF(((PyObject *)__pyx_t_11)); __pyx_t_11 = 0;
             __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_loc);
@@ -49203,14 +49186,14 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __pyx_cur_scope->__pyx_v_loc = __pyx_t_3;
             __pyx_t_3 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1121
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1126
  *                             assign_matching(&matching, sample.arr, j, num_subpatterns, self.fda.sent_id.arr)
  *                             loc = tuple(sample[j:j+num_subpatterns])
  *                             extract = self.extract(hiero_phrase, &matching, chunklen.arr, num_subpatterns)             # <<<<<<<<<<<<<<
  *                             extracts.extend([(e, loc) for e in extract])
  *                             j = j + num_subpatterns
  */
-            __pyx_t_3 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_cur_scope->__pyx_v_self->__pyx_vtab)->extract(__pyx_cur_scope->__pyx_v_self, __pyx_cur_scope->__pyx_v_hiero_phrase, (&__pyx_cur_scope->__pyx_v_matching), __pyx_cur_scope->__pyx_v_chunklen->arr, __pyx_cur_scope->__pyx_v_num_subpatterns); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_cur_scope->__pyx_v_self->__pyx_vtab)->extract(__pyx_cur_scope->__pyx_v_self, __pyx_cur_scope->__pyx_v_hiero_phrase, (&__pyx_cur_scope->__pyx_v_matching), __pyx_cur_scope->__pyx_v_chunklen->arr, __pyx_cur_scope->__pyx_v_num_subpatterns); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_3);
             __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_extract);
             __Pyx_DECREF(__pyx_cur_scope->__pyx_v_extract);
@@ -49218,22 +49201,22 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __pyx_cur_scope->__pyx_v_extract = __pyx_t_3;
             __pyx_t_3 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1122
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1127
  *                             loc = tuple(sample[j:j+num_subpatterns])
  *                             extract = self.extract(hiero_phrase, &matching, chunklen.arr, num_subpatterns)
  *                             extracts.extend([(e, loc) for e in extract])             # <<<<<<<<<<<<<<
  *                             j = j + num_subpatterns
  * 
  */
-            __pyx_t_3 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_extracts), __pyx_n_s__extend); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_extracts), __pyx_n_s__extend); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_3);
-            __pyx_t_11 = PyList_New(0); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_11 = PyList_New(0); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_11);
             if (PyList_CheckExact(__pyx_cur_scope->__pyx_v_extract) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_v_extract)) {
               __pyx_t_9 = __pyx_cur_scope->__pyx_v_extract; __Pyx_INCREF(__pyx_t_9); __pyx_t_5 = 0;
               __pyx_t_21 = NULL;
             } else {
-              __pyx_t_5 = -1; __pyx_t_9 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_extract); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_5 = -1; __pyx_t_9 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_extract); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_9);
               __pyx_t_21 = Py_TYPE(__pyx_t_9)->tp_iternext;
             }
@@ -49241,23 +49224,23 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
               if (!__pyx_t_21 && PyList_CheckExact(__pyx_t_9)) {
                 if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_9)) break;
                 #if CYTHON_COMPILING_IN_CPYTHON
-                __pyx_t_15 = PyList_GET_ITEM(__pyx_t_9, __pyx_t_5); __Pyx_INCREF(__pyx_t_15); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PyList_GET_ITEM(__pyx_t_9, __pyx_t_5); __Pyx_INCREF(__pyx_t_15); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 #else
-                __pyx_t_15 = PySequence_ITEM(__pyx_t_9, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PySequence_ITEM(__pyx_t_9, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 #endif
               } else if (!__pyx_t_21 && PyTuple_CheckExact(__pyx_t_9)) {
                 if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_9)) break;
                 #if CYTHON_COMPILING_IN_CPYTHON
-                __pyx_t_15 = PyTuple_GET_ITEM(__pyx_t_9, __pyx_t_5); __Pyx_INCREF(__pyx_t_15); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PyTuple_GET_ITEM(__pyx_t_9, __pyx_t_5); __Pyx_INCREF(__pyx_t_15); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 #else
-                __pyx_t_15 = PySequence_ITEM(__pyx_t_9, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PySequence_ITEM(__pyx_t_9, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 #endif
               } else {
                 __pyx_t_15 = __pyx_t_21(__pyx_t_9);
                 if (unlikely(!__pyx_t_15)) {
                   if (PyErr_Occurred()) {
                     if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-                    else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                    else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   }
                   break;
                 }
@@ -49268,7 +49251,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
               __Pyx_GIVEREF(__pyx_t_15);
               __pyx_cur_scope->__pyx_v_e = __pyx_t_15;
               __pyx_t_15 = 0;
-              __pyx_t_15 = PyTuple_New(2); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = PyTuple_New(2); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_15);
               __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e);
               PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_cur_scope->__pyx_v_e);
@@ -49276,23 +49259,23 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
               __Pyx_INCREF(__pyx_cur_scope->__pyx_v_loc);
               PyTuple_SET_ITEM(__pyx_t_15, 1, __pyx_cur_scope->__pyx_v_loc);
               __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_loc);
-              if (unlikely(__Pyx_PyList_Append(__pyx_t_11, (PyObject*)__pyx_t_15))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              if (unlikely(__Pyx_PyList_Append(__pyx_t_11, (PyObject*)__pyx_t_15))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
             }
             __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-            __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_9);
             __Pyx_INCREF(((PyObject *)__pyx_t_11));
             PyTuple_SET_ITEM(__pyx_t_9, 0, ((PyObject *)__pyx_t_11));
             __Pyx_GIVEREF(((PyObject *)__pyx_t_11));
             __Pyx_DECREF(((PyObject *)__pyx_t_11)); __pyx_t_11 = 0;
-            __pyx_t_11 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_11 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_11);
             __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
             __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
             __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1123
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1128
  *                             extract = self.extract(hiero_phrase, &matching, chunklen.arr, num_subpatterns)
  *                             extracts.extend([(e, loc) for e in extract])
  *                             j = j + num_subpatterns             # <<<<<<<<<<<<<<
@@ -49302,7 +49285,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __pyx_cur_scope->__pyx_v_j = (__pyx_cur_scope->__pyx_v_j + __pyx_cur_scope->__pyx_v_num_subpatterns);
           }
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1125
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1130
  *                             j = j + num_subpatterns
  * 
  *                         num_samples = sample.len/num_subpatterns             # <<<<<<<<<<<<<<
@@ -49311,22 +49294,22 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
           if (unlikely(__pyx_cur_scope->__pyx_v_num_subpatterns == 0)) {
             PyErr_Format(PyExc_ZeroDivisionError, "integer division or modulo by zero");
-            {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           }
           else if (sizeof(int) == sizeof(long) && unlikely(__pyx_cur_scope->__pyx_v_num_subpatterns == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_cur_scope->__pyx_v_sample->len))) {
             PyErr_Format(PyExc_OverflowError, "value too large to perform division");
-            {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           }
           __pyx_cur_scope->__pyx_v_num_samples = __Pyx_div_int(__pyx_cur_scope->__pyx_v_sample->len, __pyx_cur_scope->__pyx_v_num_subpatterns);
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1126
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1131
  * 
  *                         num_samples = sample.len/num_subpatterns
  *                         extract_stop = monitor_cpu()             # <<<<<<<<<<<<<<
  *                         self.extract_time = self.extract_time + extract_stop - extract_start
  *                         if len(extracts) > 0:
  */
-          __pyx_t_11 = PyFloat_FromDouble(__pyx_f_3_sa_monitor_cpu()); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyFloat_FromDouble(__pyx_f_3_sa_monitor_cpu()); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
           __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_extract_stop);
           __Pyx_XDECREF(__pyx_cur_scope->__pyx_v_extract_stop);
@@ -49334,46 +49317,46 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __pyx_cur_scope->__pyx_v_extract_stop = __pyx_t_11;
           __pyx_t_11 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1127
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1132
  *                         num_samples = sample.len/num_subpatterns
  *                         extract_stop = monitor_cpu()
  *                         self.extract_time = self.extract_time + extract_stop - extract_start             # <<<<<<<<<<<<<<
  *                         if len(extracts) > 0:
  *                             fcount = Counter()
  */
-          __pyx_t_11 = PyFloat_FromDouble(__pyx_cur_scope->__pyx_v_self->extract_time); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyFloat_FromDouble(__pyx_cur_scope->__pyx_v_self->extract_time); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
-          __pyx_t_9 = PyNumber_Add(__pyx_t_11, __pyx_cur_scope->__pyx_v_extract_stop); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyNumber_Add(__pyx_t_11, __pyx_cur_scope->__pyx_v_extract_stop); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
           __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-          __pyx_t_11 = PyNumber_Subtract(__pyx_t_9, __pyx_cur_scope->__pyx_v_extract_start); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyNumber_Subtract(__pyx_t_9, __pyx_cur_scope->__pyx_v_extract_start); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
           __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-          __pyx_t_22 = __pyx_PyFloat_AsFloat(__pyx_t_11); if (unlikely((__pyx_t_22 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_22 = __pyx_PyFloat_AsFloat(__pyx_t_11); if (unlikely((__pyx_t_22 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
           __pyx_cur_scope->__pyx_v_self->extract_time = __pyx_t_22;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1128
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1133
  *                         extract_stop = monitor_cpu()
  *                         self.extract_time = self.extract_time + extract_stop - extract_start
  *                         if len(extracts) > 0:             # <<<<<<<<<<<<<<
  *                             fcount = Counter()
  *                             fphrases = defaultdict(lambda: defaultdict(lambda: defaultdict(list)))
  */
-          __pyx_t_5 = PyList_GET_SIZE(((PyObject *)__pyx_cur_scope->__pyx_v_extracts)); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_5 = PyList_GET_SIZE(((PyObject *)__pyx_cur_scope->__pyx_v_extracts)); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __pyx_t_20 = (__pyx_t_5 > 0);
           if (__pyx_t_20) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1129
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1134
  *                         self.extract_time = self.extract_time + extract_stop - extract_start
  *                         if len(extracts) > 0:
  *                             fcount = Counter()             # <<<<<<<<<<<<<<
  *                             fphrases = defaultdict(lambda: defaultdict(lambda: defaultdict(list)))
  *                             for (f, e, count, als), loc in extracts:
  */
-            __pyx_t_11 = __Pyx_GetName(__pyx_m, __pyx_n_s__Counter); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_11 = __Pyx_GetName(__pyx_m, __pyx_n_s__Counter); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_11);
-            __pyx_t_9 = PyObject_Call(__pyx_t_11, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_9 = PyObject_Call(__pyx_t_11, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_9);
             __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
             __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_fcount);
@@ -49382,23 +49365,23 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __pyx_cur_scope->__pyx_v_fcount = __pyx_t_9;
             __pyx_t_9 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1130
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1135
  *                         if len(extracts) > 0:
  *                             fcount = Counter()
  *                             fphrases = defaultdict(lambda: defaultdict(lambda: defaultdict(list)))             # <<<<<<<<<<<<<<
  *                             for (f, e, count, als), loc in extracts:
  *                                 fcount[f] += count
  */
-            __pyx_t_9 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_9 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_9);
-            __pyx_t_11 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_5input_lambda4, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_11 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_5input_lambda4, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_11);
-            __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_3);
             PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_11);
             __Pyx_GIVEREF(__pyx_t_11);
             __pyx_t_11 = 0;
-            __pyx_t_11 = PyObject_Call(__pyx_t_9, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_11 = PyObject_Call(__pyx_t_9, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_11);
             __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
             __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
@@ -49408,7 +49391,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __pyx_cur_scope->__pyx_v_fphrases = __pyx_t_11;
             __pyx_t_11 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1131
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1136
  *                             fcount = Counter()
  *                             fphrases = defaultdict(lambda: defaultdict(lambda: defaultdict(list)))
  *                             for (f, e, count, als), loc in extracts:             # <<<<<<<<<<<<<<
@@ -49419,9 +49402,9 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             for (;;) {
               if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_11)) break;
               #if CYTHON_COMPILING_IN_CPYTHON
-              __pyx_t_3 = PyList_GET_ITEM(__pyx_t_11, __pyx_t_5); __Pyx_INCREF(__pyx_t_3); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_3 = PyList_GET_ITEM(__pyx_t_11, __pyx_t_5); __Pyx_INCREF(__pyx_t_3); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               #else
-              __pyx_t_3 = PySequence_ITEM(__pyx_t_11, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_3 = PySequence_ITEM(__pyx_t_11, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               #endif
               if ((likely(PyTuple_CheckExact(__pyx_t_3))) || (PyList_CheckExact(__pyx_t_3))) {
                 PyObject* sequence = __pyx_t_3;
@@ -49433,7 +49416,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 if (unlikely(size != 2)) {
                   if (size > 2) __Pyx_RaiseTooManyValuesError(2);
                   else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 }
                 #if CYTHON_COMPILING_IN_CPYTHON
                 if (likely(PyTuple_CheckExact(sequence))) {
@@ -49446,14 +49429,14 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 __Pyx_INCREF(__pyx_t_9);
                 __Pyx_INCREF(__pyx_t_15);
                 #else
-                __pyx_t_9 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-                __pyx_t_15 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_9 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 #endif
                 __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
               } else
               {
                 Py_ssize_t index = -1;
-                __pyx_t_16 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_16 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_16);
                 __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
                 __pyx_t_18 = Py_TYPE(__pyx_t_16)->tp_iternext;
@@ -49461,7 +49444,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 __Pyx_GOTREF(__pyx_t_9);
                 index = 1; __pyx_t_15 = __pyx_t_18(__pyx_t_16); if (unlikely(!__pyx_t_15)) goto __pyx_L50_unpacking_failed;
                 __Pyx_GOTREF(__pyx_t_15);
-                if (__Pyx_IternextUnpackEndCheck(__pyx_t_18(__pyx_t_16), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                if (__Pyx_IternextUnpackEndCheck(__pyx_t_18(__pyx_t_16), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __pyx_t_18 = NULL;
                 __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
                 goto __pyx_L51_unpacking_done;
@@ -49469,7 +49452,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
                 __pyx_t_18 = NULL;
                 if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-                {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __pyx_L51_unpacking_done:;
               }
               if ((likely(PyTuple_CheckExact(__pyx_t_9))) || (PyList_CheckExact(__pyx_t_9))) {
@@ -49482,7 +49465,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 if (unlikely(size != 4)) {
                   if (size > 4) __Pyx_RaiseTooManyValuesError(4);
                   else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 }
                 #if CYTHON_COMPILING_IN_CPYTHON
                 if (likely(PyTuple_CheckExact(sequence))) {
@@ -49504,7 +49487,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 Py_ssize_t i;
                 PyObject** temps[4] = {&__pyx_t_16,&__pyx_t_1,&__pyx_t_10,&__pyx_t_7};
                 for (i=0; i < 4; i++) {
-                  PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   *(temps[i]) = item;
                 }
                 #endif
@@ -49513,7 +49496,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
               {
                 Py_ssize_t index = -1;
                 PyObject** temps[4] = {&__pyx_t_16,&__pyx_t_1,&__pyx_t_10,&__pyx_t_7};
-                __pyx_t_14 = PyObject_GetIter(__pyx_t_9); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_14 = PyObject_GetIter(__pyx_t_9); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_14);
                 __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
                 __pyx_t_18 = Py_TYPE(__pyx_t_14)->tp_iternext;
@@ -49522,7 +49505,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                   __Pyx_GOTREF(item);
                   *(temps[index]) = item;
                 }
-                if (__Pyx_IternextUnpackEndCheck(__pyx_t_18(__pyx_t_14), 4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                if (__Pyx_IternextUnpackEndCheck(__pyx_t_18(__pyx_t_14), 4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __pyx_t_18 = NULL;
                 __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
                 goto __pyx_L53_unpacking_done;
@@ -49530,7 +49513,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
                 __pyx_t_18 = NULL;
                 if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-                {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __pyx_L53_unpacking_done:;
               }
               __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_f);
@@ -49559,7 +49542,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
               __pyx_cur_scope->__pyx_v_loc = __pyx_t_15;
               __pyx_t_15 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1132
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1137
  *                             fphrases = defaultdict(lambda: defaultdict(lambda: defaultdict(list)))
  *                             for (f, e, count, als), loc in extracts:
  *                                 fcount[f] += count             # <<<<<<<<<<<<<<
@@ -49568,38 +49551,38 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
               __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f);
               __pyx_t_3 = __pyx_cur_scope->__pyx_v_f;
-              __pyx_t_15 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fcount, __pyx_t_3); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fcount, __pyx_t_3); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_15);
-              __pyx_t_9 = PyNumber_InPlaceAdd(__pyx_t_15, __pyx_cur_scope->__pyx_v_count); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_9 = PyNumber_InPlaceAdd(__pyx_t_15, __pyx_cur_scope->__pyx_v_count); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_9);
               __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
-              if (PyObject_SetItem(__pyx_cur_scope->__pyx_v_fcount, __pyx_t_3, __pyx_t_9) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              if (PyObject_SetItem(__pyx_cur_scope->__pyx_v_fcount, __pyx_t_3, __pyx_t_9) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
               __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1133
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1138
  *                             for (f, e, count, als), loc in extracts:
  *                                 fcount[f] += count
  *                                 fphrases[f][e][als].append(loc)             # <<<<<<<<<<<<<<
  *                             for f, elist in fphrases.iteritems():
  *                                 for e, alslist in elist.iteritems():
  */
-              __pyx_t_3 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fphrases, __pyx_cur_scope->__pyx_v_f); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_3 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fphrases, __pyx_cur_scope->__pyx_v_f); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_3);
-              __pyx_t_9 = PyObject_GetItem(__pyx_t_3, __pyx_cur_scope->__pyx_v_e); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_9 = PyObject_GetItem(__pyx_t_3, __pyx_cur_scope->__pyx_v_e); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_9);
               __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-              __pyx_t_3 = PyObject_GetItem(__pyx_t_9, __pyx_cur_scope->__pyx_v_als); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_3 = PyObject_GetItem(__pyx_t_9, __pyx_cur_scope->__pyx_v_als); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_3);
               __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-              __pyx_t_9 = __Pyx_PyObject_Append(__pyx_t_3, __pyx_cur_scope->__pyx_v_loc); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_9 = __Pyx_PyObject_Append(__pyx_t_3, __pyx_cur_scope->__pyx_v_loc); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_9);
               __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
               __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
             }
             __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1134
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1139
  *                                 fcount[f] += count
  *                                 fphrases[f][e][als].append(loc)
  *                             for f, elist in fphrases.iteritems():             # <<<<<<<<<<<<<<
@@ -49609,9 +49592,9 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __pyx_t_5 = 0;
             if (unlikely(__pyx_cur_scope->__pyx_v_fphrases == Py_None)) {
               PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "iteritems");
-              {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             }
-            __pyx_t_9 = __Pyx_dict_iterator(__pyx_cur_scope->__pyx_v_fphrases, 0, ((PyObject *)__pyx_n_s__iteritems), (&__pyx_t_23), (&__pyx_t_19)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_9 = __Pyx_dict_iterator(__pyx_cur_scope->__pyx_v_fphrases, 0, ((PyObject *)__pyx_n_s__iteritems), (&__pyx_t_23), (&__pyx_t_19)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_9);
             __Pyx_XDECREF(__pyx_t_11);
             __pyx_t_11 = __pyx_t_9;
@@ -49619,7 +49602,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             while (1) {
               __pyx_t_6 = __Pyx_dict_iter_next(__pyx_t_11, __pyx_t_23, &__pyx_t_5, &__pyx_t_9, &__pyx_t_3, NULL, __pyx_t_19);
               if (unlikely(__pyx_t_6 == 0)) break;
-              if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_9);
               __Pyx_GOTREF(__pyx_t_3);
               __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_f);
@@ -49633,7 +49616,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
               __pyx_cur_scope->__pyx_v_elist = __pyx_t_3;
               __pyx_t_3 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1135
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1140
  *                                 fphrases[f][e][als].append(loc)
  *                             for f, elist in fphrases.iteritems():
  *                                 for e, alslist in elist.iteritems():             # <<<<<<<<<<<<<<
@@ -49643,9 +49626,9 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
               __pyx_t_24 = 0;
               if (unlikely(__pyx_cur_scope->__pyx_v_elist == Py_None)) {
                 PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "iteritems");
-                {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               }
-              __pyx_t_9 = __Pyx_dict_iterator(__pyx_cur_scope->__pyx_v_elist, 0, ((PyObject *)__pyx_n_s__iteritems), (&__pyx_t_25), (&__pyx_t_6)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_9 = __Pyx_dict_iterator(__pyx_cur_scope->__pyx_v_elist, 0, ((PyObject *)__pyx_n_s__iteritems), (&__pyx_t_25), (&__pyx_t_6)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_9);
               __Pyx_XDECREF(__pyx_t_3);
               __pyx_t_3 = __pyx_t_9;
@@ -49653,7 +49636,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
               while (1) {
                 __pyx_t_4 = __Pyx_dict_iter_next(__pyx_t_3, __pyx_t_25, &__pyx_t_24, &__pyx_t_9, &__pyx_t_15, NULL, __pyx_t_6);
                 if (unlikely(__pyx_t_4 == 0)) break;
-                if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_9);
                 __Pyx_GOTREF(__pyx_t_15);
                 __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_e);
@@ -49667,30 +49650,30 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 __pyx_cur_scope->__pyx_v_alslist = __pyx_t_15;
                 __pyx_t_15 = 0;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1136
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1141
  *                             for f, elist in fphrases.iteritems():
  *                                 for e, alslist in elist.iteritems():
  *                                     alignment, max_locs = max(alslist.iteritems(), key=lambda x: len(x[1]))             # <<<<<<<<<<<<<<
  *                                     locs = tuple(itertools.chain.from_iterable(alslist.itervalues()))
  *                                     count = len(locs)
  */
-                __pyx_t_15 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_alslist, __pyx_n_s__iteritems); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_alslist, __pyx_n_s__iteritems); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_15);
-                __pyx_t_9 = PyObject_Call(__pyx_t_15, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_9 = PyObject_Call(__pyx_t_15, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_9);
                 __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
-                __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_15);
                 PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_t_9);
                 __Pyx_GIVEREF(__pyx_t_9);
                 __pyx_t_9 = 0;
-                __pyx_t_9 = PyDict_New(); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_9 = PyDict_New(); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(((PyObject *)__pyx_t_9));
-                __pyx_t_7 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_5input_1lambda6, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_7 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_5input_1lambda6, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_7);
-                if (PyDict_SetItem(__pyx_t_9, ((PyObject *)__pyx_n_s__key), __pyx_t_7) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                if (PyDict_SetItem(__pyx_t_9, ((PyObject *)__pyx_n_s__key), __pyx_t_7) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-                __pyx_t_7 = PyObject_Call(__pyx_builtin_max, ((PyObject *)__pyx_t_15), ((PyObject *)__pyx_t_9)); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_7 = PyObject_Call(__pyx_builtin_max, ((PyObject *)__pyx_t_15), ((PyObject *)__pyx_t_9)); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_7);
                 __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
                 __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
@@ -49704,7 +49687,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                   if (unlikely(size != 2)) {
                     if (size > 2) __Pyx_RaiseTooManyValuesError(2);
                     else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-                    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   }
                   #if CYTHON_COMPILING_IN_CPYTHON
                   if (likely(PyTuple_CheckExact(sequence))) {
@@ -49717,14 +49700,14 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                   __Pyx_INCREF(__pyx_t_9);
                   __Pyx_INCREF(__pyx_t_15);
                   #else
-                  __pyx_t_9 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-                  __pyx_t_15 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_9 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_15 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #endif
                   __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
                 } else
                 {
                   Py_ssize_t index = -1;
-                  __pyx_t_10 = PyObject_GetIter(__pyx_t_7); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_10 = PyObject_GetIter(__pyx_t_7); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __Pyx_GOTREF(__pyx_t_10);
                   __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
                   __pyx_t_18 = Py_TYPE(__pyx_t_10)->tp_iternext;
@@ -49732,7 +49715,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                   __Pyx_GOTREF(__pyx_t_9);
                   index = 1; __pyx_t_15 = __pyx_t_18(__pyx_t_10); if (unlikely(!__pyx_t_15)) goto __pyx_L58_unpacking_failed;
                   __Pyx_GOTREF(__pyx_t_15);
-                  if (__Pyx_IternextUnpackEndCheck(__pyx_t_18(__pyx_t_10), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  if (__Pyx_IternextUnpackEndCheck(__pyx_t_18(__pyx_t_10), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __pyx_t_18 = NULL;
                   __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
                   goto __pyx_L59_unpacking_done;
@@ -49740,7 +49723,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                   __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
                   __pyx_t_18 = NULL;
                   if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __pyx_L59_unpacking_done:;
                 }
                 __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_alignment);
@@ -49754,41 +49737,41 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 __pyx_cur_scope->__pyx_v_max_locs = __pyx_t_15;
                 __pyx_t_15 = 0;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1137
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1142
  *                                 for e, alslist in elist.iteritems():
  *                                     alignment, max_locs = max(alslist.iteritems(), key=lambda x: len(x[1]))
  *                                     locs = tuple(itertools.chain.from_iterable(alslist.itervalues()))             # <<<<<<<<<<<<<<
  *                                     count = len(locs)
  *                                     scores = self.scorer.score(FeatureContext(
  */
-                __pyx_t_7 = __Pyx_GetName(__pyx_m, __pyx_n_s__itertools); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_7 = __Pyx_GetName(__pyx_m, __pyx_n_s__itertools); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_7);
-                __pyx_t_15 = PyObject_GetAttr(__pyx_t_7, __pyx_n_s__chain); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PyObject_GetAttr(__pyx_t_7, __pyx_n_s__chain); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_15);
                 __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-                __pyx_t_7 = PyObject_GetAttr(__pyx_t_15, __pyx_n_s__from_iterable); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_7 = PyObject_GetAttr(__pyx_t_15, __pyx_n_s__from_iterable); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_7);
                 __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
-                __pyx_t_15 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_alslist, __pyx_n_s__itervalues); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_alslist, __pyx_n_s__itervalues); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_15);
-                __pyx_t_9 = PyObject_Call(__pyx_t_15, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_9 = PyObject_Call(__pyx_t_15, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_9);
                 __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
-                __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_15);
                 PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_t_9);
                 __Pyx_GIVEREF(__pyx_t_9);
                 __pyx_t_9 = 0;
-                __pyx_t_9 = PyObject_Call(__pyx_t_7, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_9 = PyObject_Call(__pyx_t_7, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_9);
                 __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
                 __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
-                __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_15);
                 PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_t_9);
                 __Pyx_GIVEREF(__pyx_t_9);
                 __pyx_t_9 = 0;
-                __pyx_t_9 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_9 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_9);
                 __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
                 __Pyx_XGOTREF(((PyObject *)__pyx_cur_scope->__pyx_v_locs));
@@ -49797,15 +49780,15 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 __pyx_cur_scope->__pyx_v_locs = ((PyObject*)__pyx_t_9);
                 __pyx_t_9 = 0;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1138
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1143
  *                                     alignment, max_locs = max(alslist.iteritems(), key=lambda x: len(x[1]))
  *                                     locs = tuple(itertools.chain.from_iterable(alslist.itervalues()))
  *                                     count = len(locs)             # <<<<<<<<<<<<<<
  *                                     scores = self.scorer.score(FeatureContext(
  *                                                f, e, count, fcount[f], num_samples,
  */
-                __pyx_t_26 = PyTuple_GET_SIZE(((PyObject *)__pyx_cur_scope->__pyx_v_locs)); if (unlikely(__pyx_t_26 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-                __pyx_t_9 = PyInt_FromSsize_t(__pyx_t_26); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_26 = PyTuple_GET_SIZE(((PyObject *)__pyx_cur_scope->__pyx_v_locs)); if (unlikely(__pyx_t_26 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_9 = PyInt_FromSsize_t(__pyx_t_26); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_9);
                 __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_count);
                 __Pyx_XDECREF(__pyx_cur_scope->__pyx_v_count);
@@ -49813,43 +49796,43 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 __pyx_cur_scope->__pyx_v_count = __pyx_t_9;
                 __pyx_t_9 = 0;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1139
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1144
  *                                     locs = tuple(itertools.chain.from_iterable(alslist.itervalues()))
  *                                     count = len(locs)
  *                                     scores = self.scorer.score(FeatureContext(             # <<<<<<<<<<<<<<
  *                                                f, e, count, fcount[f], num_samples,
  *                                                (k,i+spanlen), locs, input_match,
  */
-                __pyx_t_9 = __Pyx_GetName(__pyx_m, __pyx_n_s__FeatureContext); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_9 = __Pyx_GetName(__pyx_m, __pyx_n_s__FeatureContext); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_9);
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1140
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1145
  *                                     count = len(locs)
  *                                     scores = self.scorer.score(FeatureContext(
  *                                                f, e, count, fcount[f], num_samples,             # <<<<<<<<<<<<<<
  *                                                (k,i+spanlen), locs, input_match,
  *                                                fwords, self.fda, self.eda,
  */
-                __pyx_t_15 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fcount, __pyx_cur_scope->__pyx_v_f); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fcount, __pyx_cur_scope->__pyx_v_f); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_15);
-                __pyx_t_7 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_num_samples); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_7 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_num_samples); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_7);
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1141
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1146
  *                                     scores = self.scorer.score(FeatureContext(
  *                                                f, e, count, fcount[f], num_samples,
  *                                                (k,i+spanlen), locs, input_match,             # <<<<<<<<<<<<<<
  *                                                fwords, self.fda, self.eda,
  *                                                meta,
  */
-                __pyx_t_10 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_k); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_10 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_k); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_10);
-                __pyx_t_1 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_1 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_1);
-                __pyx_t_16 = PyNumber_Add(__pyx_t_1, __pyx_cur_scope->__pyx_v_spanlen); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_16 = PyNumber_Add(__pyx_t_1, __pyx_cur_scope->__pyx_v_spanlen); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_16);
                 __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-                __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_1);
                 PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_10);
                 __Pyx_GIVEREF(__pyx_t_10);
@@ -49858,16 +49841,16 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 __pyx_t_10 = 0;
                 __pyx_t_16 = 0;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1145
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1150
  *                                                meta,
  *                                                # Include online stats.  None if none.
  *                                                self.online_ctx_lookup(f, e)))             # <<<<<<<<<<<<<<
  *                                     # Phrase pair processed
  *                                     if self.online:
  */
-                __pyx_t_16 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__online_ctx_lookup); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_16 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__online_ctx_lookup); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_16);
-                __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_10);
                 __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f);
                 PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_cur_scope->__pyx_v_f);
@@ -49875,11 +49858,11 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e);
                 PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_cur_scope->__pyx_v_e);
                 __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_e);
-                __pyx_t_14 = PyObject_Call(__pyx_t_16, ((PyObject *)__pyx_t_10), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_14 = PyObject_Call(__pyx_t_16, ((PyObject *)__pyx_t_10), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_14);
                 __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
                 __Pyx_DECREF(((PyObject *)__pyx_t_10)); __pyx_t_10 = 0;
-                __pyx_t_10 = PyTuple_New(13); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_10 = PyTuple_New(13); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_10);
                 __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f);
                 PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_cur_scope->__pyx_v_f);
@@ -49920,11 +49903,11 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 __pyx_t_7 = 0;
                 __pyx_t_1 = 0;
                 __pyx_t_14 = 0;
-                __pyx_t_14 = PyObject_Call(__pyx_t_9, ((PyObject *)__pyx_t_10), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_14 = PyObject_Call(__pyx_t_9, ((PyObject *)__pyx_t_10), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_14);
                 __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
                 __Pyx_DECREF(((PyObject *)__pyx_t_10)); __pyx_t_10 = 0;
-                __pyx_t_10 = ((PyObject *)((struct __pyx_vtabstruct_3_sa_Scorer *)__pyx_cur_scope->__pyx_v_self->scorer->__pyx_vtab)->score(__pyx_cur_scope->__pyx_v_self->scorer, __pyx_t_14)); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_10 = ((PyObject *)((struct __pyx_vtabstruct_3_sa_Scorer *)__pyx_cur_scope->__pyx_v_self->scorer->__pyx_vtab)->score(__pyx_cur_scope->__pyx_v_self->scorer, __pyx_t_14)); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_10);
                 __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
                 __Pyx_XGOTREF(((PyObject *)__pyx_cur_scope->__pyx_v_scores));
@@ -49933,7 +49916,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 __pyx_cur_scope->__pyx_v_scores = ((struct __pyx_obj_3_sa_FeatureVector *)__pyx_t_10);
                 __pyx_t_10 = 0;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1147
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1152
  *                                                self.online_ctx_lookup(f, e)))
  *                                     # Phrase pair processed
  *                                     if self.online:             # <<<<<<<<<<<<<<
@@ -49942,14 +49925,14 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
                 if (__pyx_cur_scope->__pyx_v_self->online) {
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1148
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1153
  *                                     # Phrase pair processed
  *                                     if self.online:
  *                                         seen_phrases.add((f, e))             # <<<<<<<<<<<<<<
  *                                     yield Rule(self.category, f, e, scores, alignment)
  * 
  */
-                  __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __Pyx_GOTREF(__pyx_t_10);
                   __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f);
                   PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_cur_scope->__pyx_v_f);
@@ -49957,22 +49940,22 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                   __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e);
                   PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_cur_scope->__pyx_v_e);
                   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_e);
-                  __pyx_t_12 = PySet_Add(__pyx_cur_scope->__pyx_v_seen_phrases, ((PyObject *)__pyx_t_10)); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_12 = PySet_Add(__pyx_cur_scope->__pyx_v_seen_phrases, ((PyObject *)__pyx_t_10)); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __Pyx_DECREF(((PyObject *)__pyx_t_10)); __pyx_t_10 = 0;
                   goto __pyx_L60;
                 }
                 __pyx_L60:;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1149
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1154
  *                                     if self.online:
  *                                         seen_phrases.add((f, e))
  *                                     yield Rule(self.category, f, e, scores, alignment)             # <<<<<<<<<<<<<<
  * 
  *                 if len(phrase) < self.max_length and i+spanlen < len(fwords) and pathlen+1 <= self.max_initial_size:
  */
-                __pyx_t_10 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->category); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_10 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->category); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_10);
-                __pyx_t_14 = PyTuple_New(5); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_14 = PyTuple_New(5); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_14);
                 PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_t_10);
                 __Pyx_GIVEREF(__pyx_t_10);
@@ -49989,7 +49972,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 PyTuple_SET_ITEM(__pyx_t_14, 4, __pyx_cur_scope->__pyx_v_alignment);
                 __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_alignment);
                 __pyx_t_10 = 0;
-                __pyx_t_10 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Rule)), ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_10 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Rule)), ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_10);
                 __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
                 __pyx_r = __pyx_t_10;
@@ -50029,7 +50012,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 __pyx_t_23 = __pyx_cur_scope->__pyx_t_7;
                 __pyx_t_24 = __pyx_cur_scope->__pyx_t_8;
                 __pyx_t_25 = __pyx_cur_scope->__pyx_t_9;
-                if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               }
               __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
             }
@@ -50044,41 +50027,41 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       }
       __pyx_L32:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1151
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1156
  *                                     yield Rule(self.category, f, e, scores, alignment)
  * 
  *                 if len(phrase) < self.max_length and i+spanlen < len(fwords) and pathlen+1 <= self.max_initial_size:             # <<<<<<<<<<<<<<
  *                     for alt_id in range(len(fwords[i+spanlen])):
  *                         new_frontier.append((k, i+spanlen, input_match, alt_id, pathlen + 1, node, phrase, is_shadow_path))
  */
-      __pyx_t_23 = PyObject_Length(__pyx_cur_scope->__pyx_v_phrase); if (unlikely(__pyx_t_23 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_23 = PyObject_Length(__pyx_cur_scope->__pyx_v_phrase); if (unlikely(__pyx_t_23 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_t_20 = (__pyx_t_23 < __pyx_cur_scope->__pyx_v_self->max_length);
       if (__pyx_t_20) {
-        __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_11);
-        __pyx_t_3 = PyNumber_Add(__pyx_t_11, __pyx_cur_scope->__pyx_v_spanlen); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = PyNumber_Add(__pyx_t_11, __pyx_cur_scope->__pyx_v_spanlen); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
         __pyx_t_11 = __pyx_cur_scope->__pyx_v_fwords;
         __Pyx_INCREF(__pyx_t_11);
-        __pyx_t_23 = PyObject_Length(__pyx_t_11); if (unlikely(__pyx_t_23 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_23 = PyObject_Length(__pyx_t_11); if (unlikely(__pyx_t_23 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-        __pyx_t_11 = PyInt_FromSsize_t(__pyx_t_23); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_11 = PyInt_FromSsize_t(__pyx_t_23); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_11);
-        __pyx_t_10 = PyObject_RichCompare(__pyx_t_3, __pyx_t_11, Py_LT); __Pyx_XGOTREF(__pyx_t_10); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_10 = PyObject_RichCompare(__pyx_t_3, __pyx_t_11, Py_LT); __Pyx_XGOTREF(__pyx_t_10); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-        __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
         if (__pyx_t_8) {
-          __pyx_t_10 = PyNumber_Add(__pyx_cur_scope->__pyx_v_pathlen, __pyx_int_1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_10 = PyNumber_Add(__pyx_cur_scope->__pyx_v_pathlen, __pyx_int_1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_10);
-          __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_initial_size); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_initial_size); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
-          __pyx_t_3 = PyObject_RichCompare(__pyx_t_10, __pyx_t_11, Py_LE); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_3 = PyObject_RichCompare(__pyx_t_10, __pyx_t_11, Py_LE); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
           __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-          __pyx_t_27 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_27 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_27 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_27 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
           __pyx_t_28 = __pyx_t_27;
         } else {
@@ -50090,45 +50073,45 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       }
       if (__pyx_t_8) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1152
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1157
  * 
  *                 if len(phrase) < self.max_length and i+spanlen < len(fwords) and pathlen+1 <= self.max_initial_size:
  *                     for alt_id in range(len(fwords[i+spanlen])):             # <<<<<<<<<<<<<<
  *                         new_frontier.append((k, i+spanlen, input_match, alt_id, pathlen + 1, node, phrase, is_shadow_path))
  *                     num_subpatterns = arity
  */
-        __pyx_t_3 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_3);
-        __pyx_t_11 = PyNumber_Add(__pyx_t_3, __pyx_cur_scope->__pyx_v_spanlen); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_11 = PyNumber_Add(__pyx_t_3, __pyx_cur_scope->__pyx_v_spanlen); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_11);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_3 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fwords, __pyx_t_11); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fwords, __pyx_t_11); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-        __pyx_t_23 = PyObject_Length(__pyx_t_3); if (unlikely(__pyx_t_23 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_23 = PyObject_Length(__pyx_t_3); if (unlikely(__pyx_t_23 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         for (__pyx_t_19 = 0; __pyx_t_19 < __pyx_t_23; __pyx_t_19+=1) {
           __pyx_cur_scope->__pyx_v_alt_id = __pyx_t_19;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1153
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1158
  *                 if len(phrase) < self.max_length and i+spanlen < len(fwords) and pathlen+1 <= self.max_initial_size:
  *                     for alt_id in range(len(fwords[i+spanlen])):
  *                         new_frontier.append((k, i+spanlen, input_match, alt_id, pathlen + 1, node, phrase, is_shadow_path))             # <<<<<<<<<<<<<<
  *                     num_subpatterns = arity
  *                     if not is_shadow_path:
  */
-          __pyx_t_3 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_k); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_3 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_k); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_3);
-          __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
-          __pyx_t_10 = PyNumber_Add(__pyx_t_11, __pyx_cur_scope->__pyx_v_spanlen); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_10 = PyNumber_Add(__pyx_t_11, __pyx_cur_scope->__pyx_v_spanlen); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_10);
           __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-          __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_alt_id); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_alt_id); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
-          __pyx_t_14 = PyNumber_Add(__pyx_cur_scope->__pyx_v_pathlen, __pyx_int_1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_14 = PyNumber_Add(__pyx_cur_scope->__pyx_v_pathlen, __pyx_int_1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_14);
-          __pyx_t_9 = PyTuple_New(8); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyTuple_New(8); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
           PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_3);
           __Pyx_GIVEREF(__pyx_t_3);
@@ -50154,11 +50137,11 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __pyx_t_10 = 0;
           __pyx_t_11 = 0;
           __pyx_t_14 = 0;
-          __pyx_t_12 = PyList_Append(__pyx_cur_scope->__pyx_v_new_frontier, ((PyObject *)__pyx_t_9)); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_12 = PyList_Append(__pyx_cur_scope->__pyx_v_new_frontier, ((PyObject *)__pyx_t_9)); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
         }
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1154
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1159
  *                     for alt_id in range(len(fwords[i+spanlen])):
  *                         new_frontier.append((k, i+spanlen, input_match, alt_id, pathlen + 1, node, phrase, is_shadow_path))
  *                     num_subpatterns = arity             # <<<<<<<<<<<<<<
@@ -50167,18 +50150,18 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
         __pyx_cur_scope->__pyx_v_num_subpatterns = __pyx_cur_scope->__pyx_v_arity;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1155
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1160
  *                         new_frontier.append((k, i+spanlen, input_match, alt_id, pathlen + 1, node, phrase, is_shadow_path))
  *                     num_subpatterns = arity
  *                     if not is_shadow_path:             # <<<<<<<<<<<<<<
  *                         num_subpatterns = num_subpatterns + 1
  *                     if len(phrase)+1 < self.max_length and arity < self.max_nonterminals and num_subpatterns < self.max_chunks:
  */
-        __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_cur_scope->__pyx_v_is_shadow_path); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_cur_scope->__pyx_v_is_shadow_path); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __pyx_t_20 = (!__pyx_t_8);
         if (__pyx_t_20) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1156
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1161
  *                     num_subpatterns = arity
  *                     if not is_shadow_path:
  *                         num_subpatterns = num_subpatterns + 1             # <<<<<<<<<<<<<<
@@ -50190,14 +50173,14 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         }
         __pyx_L65:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1157
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1162
  *                     if not is_shadow_path:
  *                         num_subpatterns = num_subpatterns + 1
  *                     if len(phrase)+1 < self.max_length and arity < self.max_nonterminals and num_subpatterns < self.max_chunks:             # <<<<<<<<<<<<<<
  *                         xcat = sym_setindex(self.category, arity+1)
  *                         xnode = node.children[xcat]
  */
-        __pyx_t_23 = PyObject_Length(__pyx_cur_scope->__pyx_v_phrase); if (unlikely(__pyx_t_23 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_23 = PyObject_Length(__pyx_cur_scope->__pyx_v_phrase); if (unlikely(__pyx_t_23 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __pyx_t_20 = ((__pyx_t_23 + 1) < __pyx_cur_scope->__pyx_v_self->max_length);
         if (__pyx_t_20) {
           __pyx_t_8 = (__pyx_cur_scope->__pyx_v_arity < __pyx_cur_scope->__pyx_v_self->max_nonterminals);
@@ -50213,7 +50196,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         }
         if (__pyx_t_8) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1158
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1163
  *                         num_subpatterns = num_subpatterns + 1
  *                     if len(phrase)+1 < self.max_length and arity < self.max_nonterminals and num_subpatterns < self.max_chunks:
  *                         xcat = sym_setindex(self.category, arity+1)             # <<<<<<<<<<<<<<
@@ -50222,16 +50205,16 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
           __pyx_cur_scope->__pyx_v_xcat = __pyx_f_3_sa_sym_setindex(__pyx_cur_scope->__pyx_v_self->category, (__pyx_cur_scope->__pyx_v_arity + 1));
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1159
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1164
  *                     if len(phrase)+1 < self.max_length and arity < self.max_nonterminals and num_subpatterns < self.max_chunks:
  *                         xcat = sym_setindex(self.category, arity+1)
  *                         xnode = node.children[xcat]             # <<<<<<<<<<<<<<
  *                         # I put spanlen=1 below
  *                         key = tuple([self.min_gap_size, i, 1, pathlen])
  */
-          __pyx_t_9 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
-          __pyx_t_14 = __Pyx_GetItemInt(__pyx_t_9, __pyx_cur_scope->__pyx_v_xcat, sizeof(int), PyInt_FromLong); if (!__pyx_t_14) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_14 = __Pyx_GetItemInt(__pyx_t_9, __pyx_cur_scope->__pyx_v_xcat, sizeof(int), PyInt_FromLong); if (!__pyx_t_14) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_14);
           __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
           __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_xnode);
@@ -50240,18 +50223,18 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __pyx_cur_scope->__pyx_v_xnode = __pyx_t_14;
           __pyx_t_14 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1161
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1166
  *                         xnode = node.children[xcat]
  *                         # I put spanlen=1 below
  *                         key = tuple([self.min_gap_size, i, 1, pathlen])             # <<<<<<<<<<<<<<
  *                         frontier_nodes = []
  *                         if (key in nodes_isteps_away_buffer):
  */
-          __pyx_t_14 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->min_gap_size); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_14 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->min_gap_size); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_14);
-          __pyx_t_9 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
-          __pyx_t_11 = PyList_New(4); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyList_New(4); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
           PyList_SET_ITEM(__pyx_t_11, 0, __pyx_t_14);
           __Pyx_GIVEREF(__pyx_t_14);
@@ -50265,7 +50248,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_pathlen);
           __pyx_t_14 = 0;
           __pyx_t_9 = 0;
-          __pyx_t_9 = ((PyObject *)PyList_AsTuple(__pyx_t_11)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = ((PyObject *)PyList_AsTuple(__pyx_t_11)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(((PyObject *)__pyx_t_9));
           __Pyx_DECREF(((PyObject *)__pyx_t_11)); __pyx_t_11 = 0;
           __Pyx_XGOTREF(((PyObject *)__pyx_cur_scope->__pyx_v_key));
@@ -50274,14 +50257,14 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __pyx_cur_scope->__pyx_v_key = __pyx_t_9;
           __pyx_t_9 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1162
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1167
  *                         # I put spanlen=1 below
  *                         key = tuple([self.min_gap_size, i, 1, pathlen])
  *                         frontier_nodes = []             # <<<<<<<<<<<<<<
  *                         if (key in nodes_isteps_away_buffer):
  *                             frontier_nodes = nodes_isteps_away_buffer[key]
  */
-          __pyx_t_9 = PyList_New(0); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyList_New(0); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
           __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_frontier_nodes);
           __Pyx_XDECREF(__pyx_cur_scope->__pyx_v_frontier_nodes);
@@ -50289,24 +50272,24 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __pyx_cur_scope->__pyx_v_frontier_nodes = ((PyObject *)__pyx_t_9);
           __pyx_t_9 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1163
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1168
  *                         key = tuple([self.min_gap_size, i, 1, pathlen])
  *                         frontier_nodes = []
  *                         if (key in nodes_isteps_away_buffer):             # <<<<<<<<<<<<<<
  *                             frontier_nodes = nodes_isteps_away_buffer[key]
  *                         else:
  */
-          __pyx_t_8 = (__Pyx_PyDict_Contains(((PyObject *)__pyx_cur_scope->__pyx_v_key), ((PyObject *)__pyx_cur_scope->__pyx_v_nodes_isteps_away_buffer), Py_EQ)); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_8 = (__Pyx_PyDict_Contains(((PyObject *)__pyx_cur_scope->__pyx_v_key), ((PyObject *)__pyx_cur_scope->__pyx_v_nodes_isteps_away_buffer), Py_EQ)); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           if (__pyx_t_8) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1164
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1169
  *                         frontier_nodes = []
  *                         if (key in nodes_isteps_away_buffer):
  *                             frontier_nodes = nodes_isteps_away_buffer[key]             # <<<<<<<<<<<<<<
  *                         else:
  *                             frontier_nodes = self.get_all_nodes_isteps_away(self.min_gap_size, i, 1, pathlen, fwords, next_states, reachable_buffer)
  */
-            __pyx_t_9 = __Pyx_PyDict_GetItem(((PyObject *)__pyx_cur_scope->__pyx_v_nodes_isteps_away_buffer), ((PyObject *)__pyx_cur_scope->__pyx_v_key)); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_9 = __Pyx_PyDict_GetItem(((PyObject *)__pyx_cur_scope->__pyx_v_nodes_isteps_away_buffer), ((PyObject *)__pyx_cur_scope->__pyx_v_key)); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_9);
             __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_frontier_nodes);
             __Pyx_DECREF(__pyx_cur_scope->__pyx_v_frontier_nodes);
@@ -50317,20 +50300,20 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           }
           /*else*/ {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1166
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1171
  *                             frontier_nodes = nodes_isteps_away_buffer[key]
  *                         else:
  *                             frontier_nodes = self.get_all_nodes_isteps_away(self.min_gap_size, i, 1, pathlen, fwords, next_states, reachable_buffer)             # <<<<<<<<<<<<<<
  *                             nodes_isteps_away_buffer[key] = frontier_nodes
  * 
  */
-            __pyx_t_9 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s_123); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_9 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s_123); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_9);
-            __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->min_gap_size); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->min_gap_size); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_11);
-            __pyx_t_14 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_14 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_14);
-            __pyx_t_10 = PyTuple_New(7); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_10 = PyTuple_New(7); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_10);
             PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_11);
             __Pyx_GIVEREF(__pyx_t_11);
@@ -50353,7 +50336,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __Pyx_GIVEREF(((PyObject *)__pyx_cur_scope->__pyx_v_reachable_buffer));
             __pyx_t_11 = 0;
             __pyx_t_14 = 0;
-            __pyx_t_14 = PyObject_Call(__pyx_t_9, ((PyObject *)__pyx_t_10), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_14 = PyObject_Call(__pyx_t_9, ((PyObject *)__pyx_t_10), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_14);
             __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
             __Pyx_DECREF(((PyObject *)__pyx_t_10)); __pyx_t_10 = 0;
@@ -50363,18 +50346,18 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __pyx_cur_scope->__pyx_v_frontier_nodes = __pyx_t_14;
             __pyx_t_14 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1167
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1172
  *                         else:
  *                             frontier_nodes = self.get_all_nodes_isteps_away(self.min_gap_size, i, 1, pathlen, fwords, next_states, reachable_buffer)
  *                             nodes_isteps_away_buffer[key] = frontier_nodes             # <<<<<<<<<<<<<<
  * 
  *                         for (i, alt, pathlen) in frontier_nodes:
  */
-            if (PyDict_SetItem(((PyObject *)__pyx_cur_scope->__pyx_v_nodes_isteps_away_buffer), ((PyObject *)__pyx_cur_scope->__pyx_v_key), __pyx_cur_scope->__pyx_v_frontier_nodes) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            if (PyDict_SetItem(((PyObject *)__pyx_cur_scope->__pyx_v_nodes_isteps_away_buffer), ((PyObject *)__pyx_cur_scope->__pyx_v_key), __pyx_cur_scope->__pyx_v_frontier_nodes) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           }
           __pyx_L67:;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1169
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1174
  *                             nodes_isteps_away_buffer[key] = frontier_nodes
  * 
  *                         for (i, alt, pathlen) in frontier_nodes:             # <<<<<<<<<<<<<<
@@ -50385,7 +50368,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __pyx_t_14 = __pyx_cur_scope->__pyx_v_frontier_nodes; __Pyx_INCREF(__pyx_t_14); __pyx_t_23 = 0;
             __pyx_t_21 = NULL;
           } else {
-            __pyx_t_23 = -1; __pyx_t_14 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_frontier_nodes); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_23 = -1; __pyx_t_14 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_frontier_nodes); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_14);
             __pyx_t_21 = Py_TYPE(__pyx_t_14)->tp_iternext;
           }
@@ -50393,23 +50376,23 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             if (!__pyx_t_21 && PyList_CheckExact(__pyx_t_14)) {
               if (__pyx_t_23 >= PyList_GET_SIZE(__pyx_t_14)) break;
               #if CYTHON_COMPILING_IN_CPYTHON
-              __pyx_t_10 = PyList_GET_ITEM(__pyx_t_14, __pyx_t_23); __Pyx_INCREF(__pyx_t_10); __pyx_t_23++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_10 = PyList_GET_ITEM(__pyx_t_14, __pyx_t_23); __Pyx_INCREF(__pyx_t_10); __pyx_t_23++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               #else
-              __pyx_t_10 = PySequence_ITEM(__pyx_t_14, __pyx_t_23); __pyx_t_23++; if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_10 = PySequence_ITEM(__pyx_t_14, __pyx_t_23); __pyx_t_23++; if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               #endif
             } else if (!__pyx_t_21 && PyTuple_CheckExact(__pyx_t_14)) {
               if (__pyx_t_23 >= PyTuple_GET_SIZE(__pyx_t_14)) break;
               #if CYTHON_COMPILING_IN_CPYTHON
-              __pyx_t_10 = PyTuple_GET_ITEM(__pyx_t_14, __pyx_t_23); __Pyx_INCREF(__pyx_t_10); __pyx_t_23++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_10 = PyTuple_GET_ITEM(__pyx_t_14, __pyx_t_23); __Pyx_INCREF(__pyx_t_10); __pyx_t_23++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               #else
-              __pyx_t_10 = PySequence_ITEM(__pyx_t_14, __pyx_t_23); __pyx_t_23++; if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_10 = PySequence_ITEM(__pyx_t_14, __pyx_t_23); __pyx_t_23++; if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               #endif
             } else {
               __pyx_t_10 = __pyx_t_21(__pyx_t_14);
               if (unlikely(!__pyx_t_10)) {
                 if (PyErr_Occurred()) {
                   if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-                  else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 }
                 break;
               }
@@ -50425,7 +50408,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
               if (unlikely(size != 3)) {
                 if (size > 3) __Pyx_RaiseTooManyValuesError(3);
                 else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-                {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               }
               #if CYTHON_COMPILING_IN_CPYTHON
               if (likely(PyTuple_CheckExact(sequence))) {
@@ -50441,15 +50424,15 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
               __Pyx_INCREF(__pyx_t_11);
               __Pyx_INCREF(__pyx_t_3);
               #else
-              __pyx_t_9 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-              __pyx_t_11 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-              __pyx_t_3 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_9 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_11 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_3 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               #endif
               __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
             } else
             {
               Py_ssize_t index = -1;
-              __pyx_t_1 = PyObject_GetIter(__pyx_t_10); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_1 = PyObject_GetIter(__pyx_t_10); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_1);
               __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
               __pyx_t_18 = Py_TYPE(__pyx_t_1)->tp_iternext;
@@ -50459,7 +50442,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
               __Pyx_GOTREF(__pyx_t_11);
               index = 2; __pyx_t_3 = __pyx_t_18(__pyx_t_1); if (unlikely(!__pyx_t_3)) goto __pyx_L70_unpacking_failed;
               __Pyx_GOTREF(__pyx_t_3);
-              if (__Pyx_IternextUnpackEndCheck(__pyx_t_18(__pyx_t_1), 3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              if (__Pyx_IternextUnpackEndCheck(__pyx_t_18(__pyx_t_1), 3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __pyx_t_18 = NULL;
               __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
               goto __pyx_L71_unpacking_done;
@@ -50467,12 +50450,12 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
               __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
               __pyx_t_18 = NULL;
               if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-              {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __pyx_L71_unpacking_done:;
             }
-            __pyx_t_19 = __Pyx_PyInt_AsInt(__pyx_t_9); if (unlikely((__pyx_t_19 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_19 = __Pyx_PyInt_AsInt(__pyx_t_9); if (unlikely((__pyx_t_19 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-            __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_t_11); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_t_11); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
             __pyx_cur_scope->__pyx_v_i = __pyx_t_19;
             __pyx_cur_scope->__pyx_v_alt = __pyx_t_6;
@@ -50482,40 +50465,40 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __pyx_cur_scope->__pyx_v_pathlen = __pyx_t_3;
             __pyx_t_3 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1170
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1175
  * 
  *                         for (i, alt, pathlen) in frontier_nodes:
  *                             new_frontier.append((k, i, input_match + (i,), alt, pathlen, xnode, phrase +(xcat,), is_shadow_path))             # <<<<<<<<<<<<<<
  *             frontier = new_frontier
  * 
  */
-            __pyx_t_10 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_k); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_10 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_k); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_10);
-            __pyx_t_3 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_3);
-            __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_11);
-            __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_9);
             PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_11);
             __Pyx_GIVEREF(__pyx_t_11);
             __pyx_t_11 = 0;
-            __pyx_t_11 = PyNumber_Add(__pyx_cur_scope->__pyx_v_input_match, ((PyObject *)__pyx_t_9)); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_11 = PyNumber_Add(__pyx_cur_scope->__pyx_v_input_match, ((PyObject *)__pyx_t_9)); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_11);
             __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
-            __pyx_t_9 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_alt); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_9 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_alt); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_9);
-            __pyx_t_1 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_xcat); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_1 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_xcat); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_1);
-            __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_7);
             PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_1);
             __Pyx_GIVEREF(__pyx_t_1);
             __pyx_t_1 = 0;
-            __pyx_t_1 = PyNumber_Add(__pyx_cur_scope->__pyx_v_phrase, ((PyObject *)__pyx_t_7)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_1 = PyNumber_Add(__pyx_cur_scope->__pyx_v_phrase, ((PyObject *)__pyx_t_7)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_1);
             __Pyx_DECREF(((PyObject *)__pyx_t_7)); __pyx_t_7 = 0;
-            __pyx_t_7 = PyTuple_New(8); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_7 = PyTuple_New(8); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_7);
             PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_10);
             __Pyx_GIVEREF(__pyx_t_10);
@@ -50541,7 +50524,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __pyx_t_11 = 0;
             __pyx_t_9 = 0;
             __pyx_t_1 = 0;
-            __pyx_t_12 = PyList_Append(__pyx_cur_scope->__pyx_v_new_frontier, ((PyObject *)__pyx_t_7)); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_12 = PyList_Append(__pyx_cur_scope->__pyx_v_new_frontier, ((PyObject *)__pyx_t_7)); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_DECREF(((PyObject *)__pyx_t_7)); __pyx_t_7 = 0;
           }
           __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
@@ -50555,7 +50538,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
     }
     __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1171
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1176
  *                         for (i, alt, pathlen) in frontier_nodes:
  *                             new_frontier.append((k, i, input_match + (i,), alt, pathlen, xnode, phrase +(xcat,), is_shadow_path))
  *             frontier = new_frontier             # <<<<<<<<<<<<<<
@@ -50569,54 +50552,51 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
     __pyx_cur_scope->__pyx_v_frontier = __pyx_cur_scope->__pyx_v_new_frontier;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1174
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1179
  * 
  *         # Online rule extraction and scoring
  *         if self.online:             # <<<<<<<<<<<<<<
  *             f_syms = tuple(word[0][0] for word in fwords)
- *             for (f, e, spanlen) in self.online_match(f_syms, seen_phrases):
+ *             for (f, lex_i, lex_j) in self.get_f_phrases(f_syms):
  */
   if (__pyx_cur_scope->__pyx_v_self->online) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1175
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1180
  *         # Online rule extraction and scoring
  *         if self.online:
  *             f_syms = tuple(word[0][0] for word in fwords)             # <<<<<<<<<<<<<<
- *             for (f, e, spanlen) in self.online_match(f_syms, seen_phrases):
- *                 scores = self.scorer.score(FeatureContext(
+ *             for (f, lex_i, lex_j) in self.get_f_phrases(f_syms):
+ *                 spanlen = (lex_j - lex_i) + 1
  */
-    __pyx_t_13 = __pyx_pf_3_sa_23HieroCachingRuleFactory_5input_2genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_13 = __pyx_pf_3_sa_23HieroCachingRuleFactory_5input_2genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_13);
-    __pyx_t_14 = PyTuple_New(1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_14 = PyTuple_New(1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_14);
     PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_t_13);
     __Pyx_GIVEREF(__pyx_t_13);
     __pyx_t_13 = 0;
-    __pyx_t_13 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_13 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_13);
     __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
     __Pyx_GIVEREF(__pyx_t_13);
     __pyx_cur_scope->__pyx_v_f_syms = ((PyObject*)__pyx_t_13);
     __pyx_t_13 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1176
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1181
  *         if self.online:
  *             f_syms = tuple(word[0][0] for word in fwords)
- *             for (f, e, spanlen) in self.online_match(f_syms, seen_phrases):             # <<<<<<<<<<<<<<
- *                 scores = self.scorer.score(FeatureContext(
- *                         f, e, 0, 0, 0,
+ *             for (f, lex_i, lex_j) in self.get_f_phrases(f_syms):             # <<<<<<<<<<<<<<
+ *                 spanlen = (lex_j - lex_i) + 1
+ *                 if not sym_isvar(f[0]):
  */
-    __pyx_t_13 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__online_match); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_13 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__get_f_phrases); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_13);
-    __pyx_t_14 = PyTuple_New(2); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_14 = PyTuple_New(1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_14);
     __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_v_f_syms));
     PyTuple_SET_ITEM(__pyx_t_14, 0, ((PyObject *)__pyx_cur_scope->__pyx_v_f_syms));
     __Pyx_GIVEREF(((PyObject *)__pyx_cur_scope->__pyx_v_f_syms));
-    __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_v_seen_phrases));
-    PyTuple_SET_ITEM(__pyx_t_14, 1, ((PyObject *)__pyx_cur_scope->__pyx_v_seen_phrases));
-    __Pyx_GIVEREF(((PyObject *)__pyx_cur_scope->__pyx_v_seen_phrases));
-    __pyx_t_7 = PyObject_Call(__pyx_t_13, ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyObject_Call(__pyx_t_13, ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_7);
     __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
@@ -50624,7 +50604,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       __pyx_t_14 = __pyx_t_7; __Pyx_INCREF(__pyx_t_14); __pyx_t_2 = 0;
       __pyx_t_21 = NULL;
     } else {
-      __pyx_t_2 = -1; __pyx_t_14 = PyObject_GetIter(__pyx_t_7); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = -1; __pyx_t_14 = PyObject_GetIter(__pyx_t_7); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_14);
       __pyx_t_21 = Py_TYPE(__pyx_t_14)->tp_iternext;
     }
@@ -50633,23 +50613,23 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       if (!__pyx_t_21 && PyList_CheckExact(__pyx_t_14)) {
         if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_14)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_7 = PyList_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_7); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PyList_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_7); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_7 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else if (!__pyx_t_21 && PyTuple_CheckExact(__pyx_t_14)) {
         if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_14)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_7); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_7); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_7 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else {
         __pyx_t_7 = __pyx_t_21(__pyx_t_14);
         if (unlikely(!__pyx_t_7)) {
           if (PyErr_Occurred()) {
             if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           }
           break;
         }
@@ -50665,7 +50645,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         if (unlikely(size != 3)) {
           if (size > 3) __Pyx_RaiseTooManyValuesError(3);
           else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-          {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         #if CYTHON_COMPILING_IN_CPYTHON
         if (likely(PyTuple_CheckExact(sequence))) {
@@ -50681,15 +50661,15 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         __Pyx_INCREF(__pyx_t_1);
         __Pyx_INCREF(__pyx_t_9);
         #else
-        __pyx_t_13 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __pyx_t_1 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __pyx_t_9 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_13 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_9 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
         __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       } else
       {
         Py_ssize_t index = -1;
-        __pyx_t_11 = PyObject_GetIter(__pyx_t_7); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_11 = PyObject_GetIter(__pyx_t_7); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_11);
         __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
         __pyx_t_18 = Py_TYPE(__pyx_t_11)->tp_iternext;
@@ -50699,7 +50679,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         __Pyx_GOTREF(__pyx_t_1);
         index = 2; __pyx_t_9 = __pyx_t_18(__pyx_t_11); if (unlikely(!__pyx_t_9)) goto __pyx_L75_unpacking_failed;
         __Pyx_GOTREF(__pyx_t_9);
-        if (__Pyx_IternextUnpackEndCheck(__pyx_t_18(__pyx_t_11), 3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (__Pyx_IternextUnpackEndCheck(__pyx_t_18(__pyx_t_11), 3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __pyx_t_18 = NULL;
         __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
         goto __pyx_L76_unpacking_done;
@@ -50707,7 +50687,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
         __pyx_t_18 = NULL;
         if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __pyx_L76_unpacking_done:;
       }
       __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_f);
@@ -50715,261 +50695,456 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       __Pyx_GIVEREF(__pyx_t_13);
       __pyx_cur_scope->__pyx_v_f = __pyx_t_13;
       __pyx_t_13 = 0;
-      __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_e);
-      __Pyx_XDECREF(__pyx_cur_scope->__pyx_v_e);
+      __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_lex_i);
+      __Pyx_XDECREF(__pyx_cur_scope->__pyx_v_lex_i);
       __Pyx_GIVEREF(__pyx_t_1);
-      __pyx_cur_scope->__pyx_v_e = __pyx_t_1;
+      __pyx_cur_scope->__pyx_v_lex_i = __pyx_t_1;
       __pyx_t_1 = 0;
+      __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_lex_j);
+      __Pyx_XDECREF(__pyx_cur_scope->__pyx_v_lex_j);
+      __Pyx_GIVEREF(__pyx_t_9);
+      __pyx_cur_scope->__pyx_v_lex_j = __pyx_t_9;
+      __pyx_t_9 = 0;
+
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1182
+ *             f_syms = tuple(word[0][0] for word in fwords)
+ *             for (f, lex_i, lex_j) in self.get_f_phrases(f_syms):
+ *                 spanlen = (lex_j - lex_i) + 1             # <<<<<<<<<<<<<<
+ *                 if not sym_isvar(f[0]):
+ *                     spanlen += 1
+ */
+      __pyx_t_7 = PyNumber_Subtract(__pyx_cur_scope->__pyx_v_lex_j, __pyx_cur_scope->__pyx_v_lex_i); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __pyx_t_9 = PyNumber_Add(__pyx_t_7, __pyx_int_1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_spanlen);
       __Pyx_XDECREF(__pyx_cur_scope->__pyx_v_spanlen);
       __Pyx_GIVEREF(__pyx_t_9);
       __pyx_cur_scope->__pyx_v_spanlen = __pyx_t_9;
       __pyx_t_9 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1177
- *             f_syms = tuple(word[0][0] for word in fwords)
- *             for (f, e, spanlen) in self.online_match(f_syms, seen_phrases):
- *                 scores = self.scorer.score(FeatureContext(             # <<<<<<<<<<<<<<
- *                         f, e, 0, 0, 0,
- *                         spanlen, None, None,
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1183
+ *             for (f, lex_i, lex_j) in self.get_f_phrases(f_syms):
+ *                 spanlen = (lex_j - lex_i) + 1
+ *                 if not sym_isvar(f[0]):             # <<<<<<<<<<<<<<
+ *                     spanlen += 1
+ *                 if not sym_isvar(f[1]):
  */
-      __pyx_t_7 = __Pyx_GetName(__pyx_m, __pyx_n_s__FeatureContext); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_7);
+      __pyx_t_9 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_f, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+      __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_t_9); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+      __pyx_t_8 = (!__pyx_f_3_sa_sym_isvar(__pyx_t_6));
+      if (__pyx_t_8) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1182
- *                         fwords, self.fda, self.eda,
- *                         meta,
- *                         self.online_ctx_lookup(f, e)))             # <<<<<<<<<<<<<<
- *                 alignment = self.phrases_al[f][e]
- *                 yield Rule(self.category, f, e, scores, alignment)
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1184
+ *                 spanlen = (lex_j - lex_i) + 1
+ *                 if not sym_isvar(f[0]):
+ *                     spanlen += 1             # <<<<<<<<<<<<<<
+ *                 if not sym_isvar(f[1]):
+ *                     spanlen += 1
+ */
+        __pyx_t_9 = PyNumber_InPlaceAdd(__pyx_cur_scope->__pyx_v_spanlen, __pyx_int_1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_9);
+        __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_spanlen);
+        __Pyx_DECREF(__pyx_cur_scope->__pyx_v_spanlen);
+        __Pyx_GIVEREF(__pyx_t_9);
+        __pyx_cur_scope->__pyx_v_spanlen = __pyx_t_9;
+        __pyx_t_9 = 0;
+        goto __pyx_L77;
+      }
+      __pyx_L77:;
+
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1185
+ *                 if not sym_isvar(f[0]):
+ *                     spanlen += 1
+ *                 if not sym_isvar(f[1]):             # <<<<<<<<<<<<<<
+ *                     spanlen += 1
+ *                 for e in self.phrases_fe.get(f, ()):
  */
-      __pyx_t_9 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__online_ctx_lookup); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_9 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_f, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_9);
-      __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_1);
-      __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f);
-      PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_cur_scope->__pyx_v_f);
-      __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_f);
-      __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e);
-      PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_cur_scope->__pyx_v_e);
-      __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_e);
-      __pyx_t_13 = PyObject_Call(__pyx_t_9, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_13);
+      __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_t_9); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-      __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-      __pyx_t_1 = PyTuple_New(13); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_1);
+      __pyx_t_8 = (!__pyx_f_3_sa_sym_isvar(__pyx_t_6));
+      if (__pyx_t_8) {
+
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1186
+ *                     spanlen += 1
+ *                 if not sym_isvar(f[1]):
+ *                     spanlen += 1             # <<<<<<<<<<<<<<
+ *                 for e in self.phrases_fe.get(f, ()):
+ *                     if (f, e) not in seen_phrases:
+ */
+        __pyx_t_9 = PyNumber_InPlaceAdd(__pyx_cur_scope->__pyx_v_spanlen, __pyx_int_1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_9);
+        __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_spanlen);
+        __Pyx_DECREF(__pyx_cur_scope->__pyx_v_spanlen);
+        __Pyx_GIVEREF(__pyx_t_9);
+        __pyx_cur_scope->__pyx_v_spanlen = __pyx_t_9;
+        __pyx_t_9 = 0;
+        goto __pyx_L78;
+      }
+      __pyx_L78:;
+
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1187
+ *                 if not sym_isvar(f[1]):
+ *                     spanlen += 1
+ *                 for e in self.phrases_fe.get(f, ()):             # <<<<<<<<<<<<<<
+ *                     if (f, e) not in seen_phrases:
+ *                         # Don't add multiple instances of the same phrase here
+ */
+      __pyx_t_9 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_self->phrases_fe, __pyx_n_s__get); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+      __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
       __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f);
-      PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_cur_scope->__pyx_v_f);
+      PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_cur_scope->__pyx_v_f);
       __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_f);
-      __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e);
-      PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_cur_scope->__pyx_v_e);
-      __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_e);
-      __Pyx_INCREF(__pyx_int_0);
-      PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_int_0);
-      __Pyx_GIVEREF(__pyx_int_0);
-      __Pyx_INCREF(__pyx_int_0);
-      PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_int_0);
-      __Pyx_GIVEREF(__pyx_int_0);
-      __Pyx_INCREF(__pyx_int_0);
-      PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_int_0);
-      __Pyx_GIVEREF(__pyx_int_0);
-      __Pyx_INCREF(__pyx_cur_scope->__pyx_v_spanlen);
-      PyTuple_SET_ITEM(__pyx_t_1, 5, __pyx_cur_scope->__pyx_v_spanlen);
-      __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_spanlen);
-      __Pyx_INCREF(Py_None);
-      PyTuple_SET_ITEM(__pyx_t_1, 6, Py_None);
-      __Pyx_GIVEREF(Py_None);
-      __Pyx_INCREF(Py_None);
-      PyTuple_SET_ITEM(__pyx_t_1, 7, Py_None);
-      __Pyx_GIVEREF(Py_None);
-      __Pyx_INCREF(__pyx_cur_scope->__pyx_v_fwords);
-      PyTuple_SET_ITEM(__pyx_t_1, 8, __pyx_cur_scope->__pyx_v_fwords);
-      __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_fwords);
-      __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_v_self->fda));
-      PyTuple_SET_ITEM(__pyx_t_1, 9, ((PyObject *)__pyx_cur_scope->__pyx_v_self->fda));
-      __Pyx_GIVEREF(((PyObject *)__pyx_cur_scope->__pyx_v_self->fda));
-      __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_v_self->eda));
-      PyTuple_SET_ITEM(__pyx_t_1, 10, ((PyObject *)__pyx_cur_scope->__pyx_v_self->eda));
-      __Pyx_GIVEREF(((PyObject *)__pyx_cur_scope->__pyx_v_self->eda));
-      __Pyx_INCREF(__pyx_cur_scope->__pyx_v_meta);
-      PyTuple_SET_ITEM(__pyx_t_1, 11, __pyx_cur_scope->__pyx_v_meta);
-      __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_meta);
-      PyTuple_SET_ITEM(__pyx_t_1, 12, __pyx_t_13);
-      __Pyx_GIVEREF(__pyx_t_13);
-      __pyx_t_13 = 0;
-      __pyx_t_13 = PyObject_Call(__pyx_t_7, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_13);
-      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-      __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-      __pyx_t_1 = ((PyObject *)((struct __pyx_vtabstruct_3_sa_Scorer *)__pyx_cur_scope->__pyx_v_self->scorer->__pyx_vtab)->score(__pyx_cur_scope->__pyx_v_self->scorer, __pyx_t_13)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_INCREF(((PyObject *)__pyx_empty_tuple));
+      PyTuple_SET_ITEM(__pyx_t_7, 1, ((PyObject *)__pyx_empty_tuple));
+      __Pyx_GIVEREF(((PyObject *)__pyx_empty_tuple));
+      __pyx_t_1 = PyObject_Call(__pyx_t_9, ((PyObject *)__pyx_t_7), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
-      __Pyx_XGOTREF(((PyObject *)__pyx_cur_scope->__pyx_v_scores));
-      __Pyx_XDECREF(((PyObject *)__pyx_cur_scope->__pyx_v_scores));
-      __Pyx_GIVEREF(__pyx_t_1);
-      __pyx_cur_scope->__pyx_v_scores = ((struct __pyx_obj_3_sa_FeatureVector *)__pyx_t_1);
-      __pyx_t_1 = 0;
+      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+      __Pyx_DECREF(((PyObject *)__pyx_t_7)); __pyx_t_7 = 0;
+      if (PyList_CheckExact(__pyx_t_1) || PyTuple_CheckExact(__pyx_t_1)) {
+        __pyx_t_7 = __pyx_t_1; __Pyx_INCREF(__pyx_t_7); __pyx_t_23 = 0;
+        __pyx_t_29 = NULL;
+      } else {
+        __pyx_t_23 = -1; __pyx_t_7 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_7);
+        __pyx_t_29 = Py_TYPE(__pyx_t_7)->tp_iternext;
+      }
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      for (;;) {
+        if (!__pyx_t_29 && PyList_CheckExact(__pyx_t_7)) {
+          if (__pyx_t_23 >= PyList_GET_SIZE(__pyx_t_7)) break;
+          #if CYTHON_COMPILING_IN_CPYTHON
+          __pyx_t_1 = PyList_GET_ITEM(__pyx_t_7, __pyx_t_23); __Pyx_INCREF(__pyx_t_1); __pyx_t_23++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #else
+          __pyx_t_1 = PySequence_ITEM(__pyx_t_7, __pyx_t_23); __pyx_t_23++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #endif
+        } else if (!__pyx_t_29 && PyTuple_CheckExact(__pyx_t_7)) {
+          if (__pyx_t_23 >= PyTuple_GET_SIZE(__pyx_t_7)) break;
+          #if CYTHON_COMPILING_IN_CPYTHON
+          __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_7, __pyx_t_23); __Pyx_INCREF(__pyx_t_1); __pyx_t_23++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #else
+          __pyx_t_1 = PySequence_ITEM(__pyx_t_7, __pyx_t_23); __pyx_t_23++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #endif
+        } else {
+          __pyx_t_1 = __pyx_t_29(__pyx_t_7);
+          if (unlikely(!__pyx_t_1)) {
+            if (PyErr_Occurred()) {
+              if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
+              else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            }
+            break;
+          }
+          __Pyx_GOTREF(__pyx_t_1);
+        }
+        __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_e);
+        __Pyx_XDECREF(__pyx_cur_scope->__pyx_v_e);
+        __Pyx_GIVEREF(__pyx_t_1);
+        __pyx_cur_scope->__pyx_v_e = __pyx_t_1;
+        __pyx_t_1 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1183
- *                         meta,
- *                         self.online_ctx_lookup(f, e)))
- *                 alignment = self.phrases_al[f][e]             # <<<<<<<<<<<<<<
- *                 yield Rule(self.category, f, e, scores, alignment)
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1188
+ *                     spanlen += 1
+ *                 for e in self.phrases_fe.get(f, ()):
+ *                     if (f, e) not in seen_phrases:             # <<<<<<<<<<<<<<
+ *                         # Don't add multiple instances of the same phrase here
+ *                         seen_phrases.add((f, e))
+ */
+        __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f);
+        PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_cur_scope->__pyx_v_f);
+        __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_f);
+        __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e);
+        PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_cur_scope->__pyx_v_e);
+        __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_e);
+        __pyx_t_8 = (__Pyx_PySequence_Contains(((PyObject *)__pyx_t_1), ((PyObject *)__pyx_cur_scope->__pyx_v_seen_phrases), Py_NE)); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+        if (__pyx_t_8) {
+
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1190
+ *                     if (f, e) not in seen_phrases:
+ *                         # Don't add multiple instances of the same phrase here
+ *                         seen_phrases.add((f, e))             # <<<<<<<<<<<<<<
+ *                         scores = self.scorer.score(FeatureContext(
+ *                                 f, e, 0, 0, 0,
+ */
+          __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_1);
+          __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f);
+          PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_cur_scope->__pyx_v_f);
+          __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_f);
+          __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e);
+          PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_cur_scope->__pyx_v_e);
+          __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_e);
+          __pyx_t_12 = PySet_Add(__pyx_cur_scope->__pyx_v_seen_phrases, ((PyObject *)__pyx_t_1)); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1191
+ *                         # Don't add multiple instances of the same phrase here
+ *                         seen_phrases.add((f, e))
+ *                         scores = self.scorer.score(FeatureContext(             # <<<<<<<<<<<<<<
+ *                                 f, e, 0, 0, 0,
+ *                                 spanlen, None, None,
+ */
+          __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__FeatureContext); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_1);
+
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1196
+ *                                 fwords, self.fda, self.eda,
+ *                                 meta,
+ *                                 self.online_ctx_lookup(f, e)))             # <<<<<<<<<<<<<<
+ *                         alignment = self.phrases_al[f][e]
+ *                         yield Rule(self.category, f, e, scores, alignment)
+ */
+          __pyx_t_9 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__online_ctx_lookup); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_9);
+          __pyx_t_13 = PyTuple_New(2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_13);
+          __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f);
+          PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_cur_scope->__pyx_v_f);
+          __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_f);
+          __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e);
+          PyTuple_SET_ITEM(__pyx_t_13, 1, __pyx_cur_scope->__pyx_v_e);
+          __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_e);
+          __pyx_t_11 = PyObject_Call(__pyx_t_9, ((PyObject *)__pyx_t_13), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_11);
+          __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+          __Pyx_DECREF(((PyObject *)__pyx_t_13)); __pyx_t_13 = 0;
+          __pyx_t_13 = PyTuple_New(13); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_13);
+          __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f);
+          PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_cur_scope->__pyx_v_f);
+          __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_f);
+          __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e);
+          PyTuple_SET_ITEM(__pyx_t_13, 1, __pyx_cur_scope->__pyx_v_e);
+          __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_e);
+          __Pyx_INCREF(__pyx_int_0);
+          PyTuple_SET_ITEM(__pyx_t_13, 2, __pyx_int_0);
+          __Pyx_GIVEREF(__pyx_int_0);
+          __Pyx_INCREF(__pyx_int_0);
+          PyTuple_SET_ITEM(__pyx_t_13, 3, __pyx_int_0);
+          __Pyx_GIVEREF(__pyx_int_0);
+          __Pyx_INCREF(__pyx_int_0);
+          PyTuple_SET_ITEM(__pyx_t_13, 4, __pyx_int_0);
+          __Pyx_GIVEREF(__pyx_int_0);
+          __Pyx_INCREF(__pyx_cur_scope->__pyx_v_spanlen);
+          PyTuple_SET_ITEM(__pyx_t_13, 5, __pyx_cur_scope->__pyx_v_spanlen);
+          __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_spanlen);
+          __Pyx_INCREF(Py_None);
+          PyTuple_SET_ITEM(__pyx_t_13, 6, Py_None);
+          __Pyx_GIVEREF(Py_None);
+          __Pyx_INCREF(Py_None);
+          PyTuple_SET_ITEM(__pyx_t_13, 7, Py_None);
+          __Pyx_GIVEREF(Py_None);
+          __Pyx_INCREF(__pyx_cur_scope->__pyx_v_fwords);
+          PyTuple_SET_ITEM(__pyx_t_13, 8, __pyx_cur_scope->__pyx_v_fwords);
+          __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_fwords);
+          __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_v_self->fda));
+          PyTuple_SET_ITEM(__pyx_t_13, 9, ((PyObject *)__pyx_cur_scope->__pyx_v_self->fda));
+          __Pyx_GIVEREF(((PyObject *)__pyx_cur_scope->__pyx_v_self->fda));
+          __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_v_self->eda));
+          PyTuple_SET_ITEM(__pyx_t_13, 10, ((PyObject *)__pyx_cur_scope->__pyx_v_self->eda));
+          __Pyx_GIVEREF(((PyObject *)__pyx_cur_scope->__pyx_v_self->eda));
+          __Pyx_INCREF(__pyx_cur_scope->__pyx_v_meta);
+          PyTuple_SET_ITEM(__pyx_t_13, 11, __pyx_cur_scope->__pyx_v_meta);
+          __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_meta);
+          PyTuple_SET_ITEM(__pyx_t_13, 12, __pyx_t_11);
+          __Pyx_GIVEREF(__pyx_t_11);
+          __pyx_t_11 = 0;
+          __pyx_t_11 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_13), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_11);
+          __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+          __Pyx_DECREF(((PyObject *)__pyx_t_13)); __pyx_t_13 = 0;
+          __pyx_t_13 = ((PyObject *)((struct __pyx_vtabstruct_3_sa_Scorer *)__pyx_cur_scope->__pyx_v_self->scorer->__pyx_vtab)->score(__pyx_cur_scope->__pyx_v_self->scorer, __pyx_t_11)); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_13);
+          __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+          __Pyx_XGOTREF(((PyObject *)__pyx_cur_scope->__pyx_v_scores));
+          __Pyx_XDECREF(((PyObject *)__pyx_cur_scope->__pyx_v_scores));
+          __Pyx_GIVEREF(__pyx_t_13);
+          __pyx_cur_scope->__pyx_v_scores = ((struct __pyx_obj_3_sa_FeatureVector *)__pyx_t_13);
+          __pyx_t_13 = 0;
+
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1197
+ *                                 meta,
+ *                                 self.online_ctx_lookup(f, e)))
+ *                         alignment = self.phrases_al[f][e]             # <<<<<<<<<<<<<<
+ *                         yield Rule(self.category, f, e, scores, alignment)
  * 
  */
-      __pyx_t_1 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_self->phrases_al, __pyx_cur_scope->__pyx_v_f); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_13 = PyObject_GetItem(__pyx_t_1, __pyx_cur_scope->__pyx_v_e); if (!__pyx_t_13) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_13);
-      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_alignment);
-      __Pyx_XDECREF(__pyx_cur_scope->__pyx_v_alignment);
-      __Pyx_GIVEREF(__pyx_t_13);
-      __pyx_cur_scope->__pyx_v_alignment = __pyx_t_13;
-      __pyx_t_13 = 0;
+          __pyx_t_13 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_self->phrases_al, __pyx_cur_scope->__pyx_v_f); if (!__pyx_t_13) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_13);
+          __pyx_t_11 = PyObject_GetItem(__pyx_t_13, __pyx_cur_scope->__pyx_v_e); if (!__pyx_t_11) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_11);
+          __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+          __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_alignment);
+          __Pyx_XDECREF(__pyx_cur_scope->__pyx_v_alignment);
+          __Pyx_GIVEREF(__pyx_t_11);
+          __pyx_cur_scope->__pyx_v_alignment = __pyx_t_11;
+          __pyx_t_11 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1184
- *                         self.online_ctx_lookup(f, e)))
- *                 alignment = self.phrases_al[f][e]
- *                 yield Rule(self.category, f, e, scores, alignment)             # <<<<<<<<<<<<<<
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1198
+ *                                 self.online_ctx_lookup(f, e)))
+ *                         alignment = self.phrases_al[f][e]
+ *                         yield Rule(self.category, f, e, scores, alignment)             # <<<<<<<<<<<<<<
  * 
  *         stop_time = monitor_cpu()
  */
-      __pyx_t_13 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->category); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_13);
-      __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_1);
-      PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_13);
-      __Pyx_GIVEREF(__pyx_t_13);
-      __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f);
-      PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_cur_scope->__pyx_v_f);
-      __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_f);
-      __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e);
-      PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_cur_scope->__pyx_v_e);
-      __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_e);
-      __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_v_scores));
-      PyTuple_SET_ITEM(__pyx_t_1, 3, ((PyObject *)__pyx_cur_scope->__pyx_v_scores));
-      __Pyx_GIVEREF(((PyObject *)__pyx_cur_scope->__pyx_v_scores));
-      __Pyx_INCREF(__pyx_cur_scope->__pyx_v_alignment);
-      PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_cur_scope->__pyx_v_alignment);
-      __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_alignment);
-      __pyx_t_13 = 0;
-      __pyx_t_13 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Rule)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_13);
-      __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-      __pyx_r = __pyx_t_13;
-      __pyx_t_13 = 0;
-      __pyx_cur_scope->__pyx_t_0 = __pyx_t_2;
-      __Pyx_XGIVEREF(__pyx_t_14);
-      __pyx_cur_scope->__pyx_t_1 = __pyx_t_14;
-      __pyx_cur_scope->__pyx_t_10 = __pyx_t_21;
-      __Pyx_XGIVEREF(__pyx_r);
-      __Pyx_RefNannyFinishContext();
-      /* return from generator, yielding value */
-      __pyx_generator->resume_label = 2;
-      return __pyx_r;
-      __pyx_L77_resume_from_yield:;
-      __pyx_t_2 = __pyx_cur_scope->__pyx_t_0;
-      __pyx_t_14 = __pyx_cur_scope->__pyx_t_1;
-      __pyx_cur_scope->__pyx_t_1 = 0;
-      __Pyx_XGOTREF(__pyx_t_14);
-      __pyx_t_21 = __pyx_cur_scope->__pyx_t_10;
-      if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->category); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1198; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_11);
+          __pyx_t_13 = PyTuple_New(5); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1198; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_13);
+          PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_11);
+          __Pyx_GIVEREF(__pyx_t_11);
+          __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f);
+          PyTuple_SET_ITEM(__pyx_t_13, 1, __pyx_cur_scope->__pyx_v_f);
+          __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_f);
+          __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e);
+          PyTuple_SET_ITEM(__pyx_t_13, 2, __pyx_cur_scope->__pyx_v_e);
+          __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_e);
+          __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_v_scores));
+          PyTuple_SET_ITEM(__pyx_t_13, 3, ((PyObject *)__pyx_cur_scope->__pyx_v_scores));
+          __Pyx_GIVEREF(((PyObject *)__pyx_cur_scope->__pyx_v_scores));
+          __Pyx_INCREF(__pyx_cur_scope->__pyx_v_alignment);
+          PyTuple_SET_ITEM(__pyx_t_13, 4, __pyx_cur_scope->__pyx_v_alignment);
+          __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_alignment);
+          __pyx_t_11 = 0;
+          __pyx_t_11 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Rule)), ((PyObject *)__pyx_t_13), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1198; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_11);
+          __Pyx_DECREF(((PyObject *)__pyx_t_13)); __pyx_t_13 = 0;
+          __pyx_r = __pyx_t_11;
+          __pyx_t_11 = 0;
+          __pyx_cur_scope->__pyx_t_0 = __pyx_t_2;
+          __Pyx_XGIVEREF(__pyx_t_7);
+          __pyx_cur_scope->__pyx_t_1 = __pyx_t_7;
+          __Pyx_XGIVEREF(__pyx_t_14);
+          __pyx_cur_scope->__pyx_t_4 = __pyx_t_14;
+          __pyx_cur_scope->__pyx_t_10 = __pyx_t_21;
+          __pyx_cur_scope->__pyx_t_2 = __pyx_t_23;
+          __pyx_cur_scope->__pyx_t_11 = __pyx_t_29;
+          __Pyx_XGIVEREF(__pyx_r);
+          __Pyx_RefNannyFinishContext();
+          /* return from generator, yielding value */
+          __pyx_generator->resume_label = 2;
+          return __pyx_r;
+          __pyx_L82_resume_from_yield:;
+          __pyx_t_2 = __pyx_cur_scope->__pyx_t_0;
+          __pyx_t_7 = __pyx_cur_scope->__pyx_t_1;
+          __pyx_cur_scope->__pyx_t_1 = 0;
+          __Pyx_XGOTREF(__pyx_t_7);
+          __pyx_t_14 = __pyx_cur_scope->__pyx_t_4;
+          __pyx_cur_scope->__pyx_t_4 = 0;
+          __Pyx_XGOTREF(__pyx_t_14);
+          __pyx_t_21 = __pyx_cur_scope->__pyx_t_10;
+          __pyx_t_23 = __pyx_cur_scope->__pyx_t_2;
+          __pyx_t_29 = __pyx_cur_scope->__pyx_t_11;
+          if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1198; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          goto __pyx_L81;
+        }
+        __pyx_L81:;
+      }
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     }
     __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
     goto __pyx_L72;
   }
   __pyx_L72:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1186
- *                 yield Rule(self.category, f, e, scores, alignment)
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1200
+ *                         yield Rule(self.category, f, e, scores, alignment)
  * 
  *         stop_time = monitor_cpu()             # <<<<<<<<<<<<<<
  *         logger.info("Total time for rule lookup, extraction, and scoring = %f seconds", (stop_time - start_time))
  *         gc.collect()
  */
-  __pyx_t_14 = PyFloat_FromDouble(__pyx_f_3_sa_monitor_cpu()); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_14 = PyFloat_FromDouble(__pyx_f_3_sa_monitor_cpu()); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_14);
   __Pyx_GIVEREF(__pyx_t_14);
   __pyx_cur_scope->__pyx_v_stop_time = __pyx_t_14;
   __pyx_t_14 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1187
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1201
  * 
  *         stop_time = monitor_cpu()
  *         logger.info("Total time for rule lookup, extraction, and scoring = %f seconds", (stop_time - start_time))             # <<<<<<<<<<<<<<
  *         gc.collect()
  *         logger.info("    Extract time = %f seconds", self.extract_time)
  */
-  __pyx_t_14 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_14 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_14);
-  __pyx_t_13 = PyObject_GetAttr(__pyx_t_14, __pyx_n_s__info); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_13);
+  __pyx_t_7 = PyObject_GetAttr(__pyx_t_14, __pyx_n_s__info); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
   __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
-  __pyx_t_14 = PyFloat_FromDouble(__pyx_cur_scope->__pyx_v_start_time); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_14 = PyFloat_FromDouble(__pyx_cur_scope->__pyx_v_start_time); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_14);
-  __pyx_t_1 = PyNumber_Subtract(__pyx_cur_scope->__pyx_v_stop_time, __pyx_t_14); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_11 = PyNumber_Subtract(__pyx_cur_scope->__pyx_v_stop_time, __pyx_t_14); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_11);
   __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
-  __pyx_t_14 = PyTuple_New(2); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_14 = PyTuple_New(2); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_14);
   __Pyx_INCREF(((PyObject *)__pyx_kp_s_124));
   PyTuple_SET_ITEM(__pyx_t_14, 0, ((PyObject *)__pyx_kp_s_124));
   __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_124));
-  PyTuple_SET_ITEM(__pyx_t_14, 1, __pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_1);
-  __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_t_13, ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+  PyTuple_SET_ITEM(__pyx_t_14, 1, __pyx_t_11);
+  __Pyx_GIVEREF(__pyx_t_11);
+  __pyx_t_11 = 0;
+  __pyx_t_11 = PyObject_Call(__pyx_t_7, ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_11);
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1188
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1202
  *         stop_time = monitor_cpu()
  *         logger.info("Total time for rule lookup, extraction, and scoring = %f seconds", (stop_time - start_time))
  *         gc.collect()             # <<<<<<<<<<<<<<
  *         logger.info("    Extract time = %f seconds", self.extract_time)
  * 
  */
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__gc); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_14 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__collect); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_11 = __Pyx_GetName(__pyx_m, __pyx_n_s__gc); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1202; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_11);
+  __pyx_t_14 = PyObject_GetAttr(__pyx_t_11, __pyx_n_s__collect); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1202; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_14);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_t_14, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+  __pyx_t_11 = PyObject_Call(__pyx_t_14, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1202; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_11);
   __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1189
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1203
  *         logger.info("Total time for rule lookup, extraction, and scoring = %f seconds", (stop_time - start_time))
  *         gc.collect()
  *         logger.info("    Extract time = %f seconds", self.extract_time)             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_14 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_11 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_11);
+  __pyx_t_14 = PyObject_GetAttr(__pyx_t_11, __pyx_n_s__info); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_14);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyFloat_FromDouble(__pyx_cur_scope->__pyx_v_self->extract_time); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_13 = PyTuple_New(2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_13);
+  __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+  __pyx_t_11 = PyFloat_FromDouble(__pyx_cur_scope->__pyx_v_self->extract_time); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_11);
+  __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_7);
   __Pyx_INCREF(((PyObject *)__pyx_kp_s_125));
-  PyTuple_SET_ITEM(__pyx_t_13, 0, ((PyObject *)__pyx_kp_s_125));
+  PyTuple_SET_ITEM(__pyx_t_7, 0, ((PyObject *)__pyx_kp_s_125));
   __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_125));
-  PyTuple_SET_ITEM(__pyx_t_13, 1, __pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_1);
-  __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_t_14, ((PyObject *)__pyx_t_13), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_11);
+  __Pyx_GIVEREF(__pyx_t_11);
+  __pyx_t_11 = 0;
+  __pyx_t_11 = PyObject_Call(__pyx_t_14, ((PyObject *)__pyx_t_7), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_11);
   __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
-  __Pyx_DECREF(((PyObject *)__pyx_t_13)); __pyx_t_13 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_7)); __pyx_t_7 = 0;
+  __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
   PyErr_SetNone(PyExc_StopIteration);
   goto __pyx_L0;
   __pyx_L1_error:;
@@ -50993,7 +51168,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
   return NULL;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1192
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1206
  * 
  * 
  *     cdef int find_fixpoint(self,             # <<<<<<<<<<<<<<
@@ -51023,7 +51198,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("find_fixpoint", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1207
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1221
  *         cdef int e_low_prev, e_high_prev, f_low_prev, f_high_prev, new_x, new_low_x, new_high_x
  * 
  *         e_low[0] = e_in_low             # <<<<<<<<<<<<<<
@@ -51032,7 +51207,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
   (__pyx_v_e_low[0]) = __pyx_v_e_in_low;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1208
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1222
  * 
  *         e_low[0] = e_in_low
  *         e_high[0] = e_in_high             # <<<<<<<<<<<<<<
@@ -51041,19 +51216,19 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
   (__pyx_v_e_high[0]) = __pyx_v_e_in_high;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1209
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1223
  *         e_low[0] = e_in_low
  *         e_high[0] = e_in_high
  *         self.find_projection(f_low, f_high, f_links_low, f_links_high, e_low, e_high)             # <<<<<<<<<<<<<<
  *         if e_low[0] == -1:
  *             # low-priority corner case: if phrase w is unaligned,
  */
-  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_f_high); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_2 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->find_projection(__pyx_v_self, __pyx_v_f_low, __pyx_t_1, __pyx_v_f_links_low, __pyx_v_f_links_high, __pyx_v_e_low, __pyx_v_e_high); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_f_high); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1223; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->find_projection(__pyx_v_self, __pyx_v_f_low, __pyx_t_1, __pyx_v_f_links_low, __pyx_v_f_links_high, __pyx_v_e_low, __pyx_v_e_high); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1223; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1210
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1224
  *         e_high[0] = e_in_high
  *         self.find_projection(f_low, f_high, f_links_low, f_links_high, e_low, e_high)
  *         if e_low[0] == -1:             # <<<<<<<<<<<<<<
@@ -51063,7 +51238,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
   __pyx_t_3 = ((__pyx_v_e_low[0]) == -1);
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1216
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1230
  *             # rule X -> X_1 w X_2 / X_1 X_2.    This is probably
  *             # not worth the bother, though.
  *             return 0             # <<<<<<<<<<<<<<
@@ -51075,7 +51250,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     goto __pyx_L3;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1217
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1231
  *             # not worth the bother, though.
  *             return 0
  *         elif e_in_low != -1 and e_low[0] != e_in_low:             # <<<<<<<<<<<<<<
@@ -51091,7 +51266,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
   }
   if (__pyx_t_5) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1218
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1232
  *             return 0
  *         elif e_in_low != -1 and e_low[0] != e_in_low:
  *             if e_in_low - e_low[0] < min_ex_size:             # <<<<<<<<<<<<<<
@@ -51101,7 +51276,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     __pyx_t_5 = ((__pyx_v_e_in_low - (__pyx_v_e_low[0])) < __pyx_v_min_ex_size);
     if (__pyx_t_5) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1219
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1233
  *         elif e_in_low != -1 and e_low[0] != e_in_low:
  *             if e_in_low - e_low[0] < min_ex_size:
  *                 e_low[0] = e_in_low - min_ex_size             # <<<<<<<<<<<<<<
@@ -51110,7 +51285,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
       (__pyx_v_e_low[0]) = (__pyx_v_e_in_low - __pyx_v_min_ex_size);
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1220
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1234
  *             if e_in_low - e_low[0] < min_ex_size:
  *                 e_low[0] = e_in_low - min_ex_size
  *                 if e_low[0] < 0:             # <<<<<<<<<<<<<<
@@ -51120,7 +51295,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
       __pyx_t_5 = ((__pyx_v_e_low[0]) < 0);
       if (__pyx_t_5) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1221
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1235
  *                 e_low[0] = e_in_low - min_ex_size
  *                 if e_low[0] < 0:
  *                     return 0             # <<<<<<<<<<<<<<
@@ -51139,7 +51314,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1223
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1237
  *                     return 0
  * 
  *         if e_high[0] - e_low[0] > max_e_len:             # <<<<<<<<<<<<<<
@@ -51149,7 +51324,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
   __pyx_t_5 = (((__pyx_v_e_high[0]) - (__pyx_v_e_low[0])) > __pyx_v_max_e_len);
   if (__pyx_t_5) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1224
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1238
  * 
  *         if e_high[0] - e_low[0] > max_e_len:
  *             return 0             # <<<<<<<<<<<<<<
@@ -51161,7 +51336,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     goto __pyx_L6;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1225
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1239
  *         if e_high[0] - e_low[0] > max_e_len:
  *             return 0
  *         elif e_in_high != -1 and e_high[0] != e_in_high:             # <<<<<<<<<<<<<<
@@ -51177,7 +51352,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
   }
   if (__pyx_t_4) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1226
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1240
  *             return 0
  *         elif e_in_high != -1 and e_high[0] != e_in_high:
  *             if e_high[0] - e_in_high < min_ex_size:             # <<<<<<<<<<<<<<
@@ -51187,7 +51362,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     __pyx_t_4 = (((__pyx_v_e_high[0]) - __pyx_v_e_in_high) < __pyx_v_min_ex_size);
     if (__pyx_t_4) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1227
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1241
  *         elif e_in_high != -1 and e_high[0] != e_in_high:
  *             if e_high[0] - e_in_high < min_ex_size:
  *                 e_high[0] = e_in_high + min_ex_size             # <<<<<<<<<<<<<<
@@ -51196,7 +51371,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
       (__pyx_v_e_high[0]) = (__pyx_v_e_in_high + __pyx_v_min_ex_size);
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1228
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1242
  *             if e_high[0] - e_in_high < min_ex_size:
  *                 e_high[0] = e_in_high + min_ex_size
  *                 if e_high[0] > e_sent_len:             # <<<<<<<<<<<<<<
@@ -51206,7 +51381,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
       __pyx_t_4 = ((__pyx_v_e_high[0]) > __pyx_v_e_sent_len);
       if (__pyx_t_4) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1229
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1243
  *                 e_high[0] = e_in_high + min_ex_size
  *                 if e_high[0] > e_sent_len:
  *                     return 0             # <<<<<<<<<<<<<<
@@ -51225,7 +51400,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
   }
   __pyx_L6:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1231
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1245
  *                     return 0
  * 
  *         f_back_low[0] = -1             # <<<<<<<<<<<<<<
@@ -51234,7 +51409,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
   (__pyx_v_f_back_low[0]) = -1;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1232
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1246
  * 
  *         f_back_low[0] = -1
  *         f_back_high[0] = -1             # <<<<<<<<<<<<<<
@@ -51243,7 +51418,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
   (__pyx_v_f_back_high[0]) = -1;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1233
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1247
  *         f_back_low[0] = -1
  *         f_back_high[0] = -1
  *         f_low_prev = f_low             # <<<<<<<<<<<<<<
@@ -51252,17 +51427,17 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
   __pyx_v_f_low_prev = __pyx_v_f_low;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1234
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1248
  *         f_back_high[0] = -1
  *         f_low_prev = f_low
  *         f_high_prev = f_high             # <<<<<<<<<<<<<<
  *         new_x = 0
  *         new_low_x = 0
  */
-  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_f_high); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1234; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_f_high); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1248; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_v_f_high_prev = __pyx_t_1;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1235
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1249
  *         f_low_prev = f_low
  *         f_high_prev = f_high
  *         new_x = 0             # <<<<<<<<<<<<<<
@@ -51271,7 +51446,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
   __pyx_v_new_x = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1236
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1250
  *         f_high_prev = f_high
  *         new_x = 0
  *         new_low_x = 0             # <<<<<<<<<<<<<<
@@ -51280,7 +51455,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
   __pyx_v_new_low_x = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1237
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1251
  *         new_x = 0
  *         new_low_x = 0
  *         new_high_x = 0             # <<<<<<<<<<<<<<
@@ -51289,7 +51464,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
   __pyx_v_new_high_x = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1239
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1253
  *         new_high_x = 0
  * 
  *         while True:             # <<<<<<<<<<<<<<
@@ -51299,7 +51474,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
   while (1) {
     if (!1) break;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1241
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1255
  *         while True:
  * 
  *             if f_back_low[0] == -1:             # <<<<<<<<<<<<<<
@@ -51309,45 +51484,45 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     __pyx_t_4 = ((__pyx_v_f_back_low[0]) == -1);
     if (__pyx_t_4) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1242
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1256
  * 
  *             if f_back_low[0] == -1:
  *                 self.find_projection(e_low[0], e_high[0], e_links_low, e_links_high, f_back_low, f_back_high)             # <<<<<<<<<<<<<<
  *             else:
  *                 self.find_projection(e_low[0], e_low_prev, e_links_low, e_links_high, f_back_low, f_back_high)
  */
-      __pyx_t_2 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->find_projection(__pyx_v_self, (__pyx_v_e_low[0]), (__pyx_v_e_high[0]), __pyx_v_e_links_low, __pyx_v_e_links_high, __pyx_v_f_back_low, __pyx_v_f_back_high); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->find_projection(__pyx_v_self, (__pyx_v_e_low[0]), (__pyx_v_e_high[0]), __pyx_v_e_links_low, __pyx_v_e_links_high, __pyx_v_f_back_low, __pyx_v_f_back_high); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       goto __pyx_L11;
     }
     /*else*/ {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1244
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1258
  *                 self.find_projection(e_low[0], e_high[0], e_links_low, e_links_high, f_back_low, f_back_high)
  *             else:
  *                 self.find_projection(e_low[0], e_low_prev, e_links_low, e_links_high, f_back_low, f_back_high)             # <<<<<<<<<<<<<<
  *                 self.find_projection(e_high_prev, e_high[0], e_links_low, e_links_high, f_back_low, f_back_high)
  * 
  */
-      __pyx_t_2 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->find_projection(__pyx_v_self, (__pyx_v_e_low[0]), __pyx_v_e_low_prev, __pyx_v_e_links_low, __pyx_v_e_links_high, __pyx_v_f_back_low, __pyx_v_f_back_high); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1244; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->find_projection(__pyx_v_self, (__pyx_v_e_low[0]), __pyx_v_e_low_prev, __pyx_v_e_links_low, __pyx_v_e_links_high, __pyx_v_f_back_low, __pyx_v_f_back_high); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1245
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1259
  *             else:
  *                 self.find_projection(e_low[0], e_low_prev, e_links_low, e_links_high, f_back_low, f_back_high)
  *                 self.find_projection(e_high_prev, e_high[0], e_links_low, e_links_high, f_back_low, f_back_high)             # <<<<<<<<<<<<<<
  * 
  *             if f_back_low[0] > f_low:
  */
-      __pyx_t_2 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->find_projection(__pyx_v_self, __pyx_v_e_high_prev, (__pyx_v_e_high[0]), __pyx_v_e_links_low, __pyx_v_e_links_high, __pyx_v_f_back_low, __pyx_v_f_back_high); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1245; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->find_projection(__pyx_v_self, __pyx_v_e_high_prev, (__pyx_v_e_high[0]), __pyx_v_e_links_low, __pyx_v_e_links_high, __pyx_v_f_back_low, __pyx_v_f_back_high); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     }
     __pyx_L11:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1247
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1261
  *                 self.find_projection(e_high_prev, e_high[0], e_links_low, e_links_high, f_back_low, f_back_high)
  * 
  *             if f_back_low[0] > f_low:             # <<<<<<<<<<<<<<
@@ -51357,7 +51532,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     __pyx_t_4 = ((__pyx_v_f_back_low[0]) > __pyx_v_f_low);
     if (__pyx_t_4) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1248
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1262
  * 
  *             if f_back_low[0] > f_low:
  *                 f_back_low[0] = f_low             # <<<<<<<<<<<<<<
@@ -51369,35 +51544,35 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     }
     __pyx_L12:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1250
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1264
  *                 f_back_low[0] = f_low
  * 
  *             if f_back_high[0] < f_high:             # <<<<<<<<<<<<<<
  *                 f_back_high[0] = f_high
  * 
  */
-    __pyx_t_2 = PyInt_FromLong((__pyx_v_f_back_high[0])); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1250; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyInt_FromLong((__pyx_v_f_back_high[0])); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_6 = PyObject_RichCompare(__pyx_t_2, __pyx_v_f_high, Py_LT); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1250; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyObject_RichCompare(__pyx_t_2, __pyx_v_f_high, Py_LT); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1250; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     if (__pyx_t_4) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1251
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1265
  * 
  *             if f_back_high[0] < f_high:
  *                 f_back_high[0] = f_high             # <<<<<<<<<<<<<<
  * 
  *             if f_back_low[0] == f_low_prev and f_back_high[0] == f_high_prev:
  */
-      __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_f_high); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_f_high); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1265; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       (__pyx_v_f_back_high[0]) = __pyx_t_1;
       goto __pyx_L13;
     }
     __pyx_L13:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1253
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1267
  *                 f_back_high[0] = f_high
  * 
  *             if f_back_low[0] == f_low_prev and f_back_high[0] == f_high_prev:             # <<<<<<<<<<<<<<
@@ -51413,7 +51588,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     }
     if (__pyx_t_3) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1254
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1268
  * 
  *             if f_back_low[0] == f_low_prev and f_back_high[0] == f_high_prev:
  *                 return 1             # <<<<<<<<<<<<<<
@@ -51426,7 +51601,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     }
     __pyx_L14:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1256
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1270
  *                 return 1
  * 
  *             if allow_low_x == 0 and f_back_low[0] < f_low:             # <<<<<<<<<<<<<<
@@ -51442,7 +51617,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     }
     if (__pyx_t_5) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1258
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1272
  *             if allow_low_x == 0 and f_back_low[0] < f_low:
  *                 # FAIL: f phrase is not tight
  *                 return 0             # <<<<<<<<<<<<<<
@@ -51455,7 +51630,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     }
     __pyx_L15:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1260
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1274
  *                 return 0
  * 
  *             if f_back_high[0] - f_back_low[0] > max_f_len:             # <<<<<<<<<<<<<<
@@ -51465,7 +51640,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     __pyx_t_5 = (((__pyx_v_f_back_high[0]) - (__pyx_v_f_back_low[0])) > __pyx_v_max_f_len);
     if (__pyx_t_5) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1262
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1276
  *             if f_back_high[0] - f_back_low[0] > max_f_len:
  *                 # FAIL: f back projection is too wide
  *                 return 0             # <<<<<<<<<<<<<<
@@ -51478,7 +51653,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     }
     __pyx_L16:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1264
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1278
  *                 return 0
  * 
  *             if allow_high_x == 0 and f_back_high[0] > f_high:             # <<<<<<<<<<<<<<
@@ -51487,11 +51662,11 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
     __pyx_t_5 = (__pyx_v_allow_high_x == 0);
     if (__pyx_t_5) {
-      __pyx_t_6 = PyInt_FromLong((__pyx_v_f_back_high[0])); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PyInt_FromLong((__pyx_v_f_back_high[0])); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_6);
-      __pyx_t_2 = PyObject_RichCompare(__pyx_t_6, __pyx_v_f_high, Py_GT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_RichCompare(__pyx_t_6, __pyx_v_f_high, Py_GT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-      __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __pyx_t_4 = __pyx_t_3;
     } else {
@@ -51499,7 +51674,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     }
     if (__pyx_t_4) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1266
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1280
  *             if allow_high_x == 0 and f_back_high[0] > f_high:
  *                 # FAIL: extension on high side not allowed
  *                 return 0             # <<<<<<<<<<<<<<
@@ -51512,7 +51687,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     }
     __pyx_L17:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1268
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1282
  *                 return 0
  * 
  *             if f_low != f_back_low[0]:             # <<<<<<<<<<<<<<
@@ -51522,7 +51697,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     __pyx_t_4 = (__pyx_v_f_low != (__pyx_v_f_back_low[0]));
     if (__pyx_t_4) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1269
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1283
  * 
  *             if f_low != f_back_low[0]:
  *                 if new_low_x == 0:             # <<<<<<<<<<<<<<
@@ -51532,7 +51707,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
       __pyx_t_4 = (__pyx_v_new_low_x == 0);
       if (__pyx_t_4) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1270
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1284
  *             if f_low != f_back_low[0]:
  *                 if new_low_x == 0:
  *                     if new_x >= max_new_x:             # <<<<<<<<<<<<<<
@@ -51542,7 +51717,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
         __pyx_t_4 = (__pyx_v_new_x >= __pyx_v_max_new_x);
         if (__pyx_t_4) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1272
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1286
  *                     if new_x >= max_new_x:
  *                         # FAIL: extension required on low side violates max # of gaps
  *                         return 0             # <<<<<<<<<<<<<<
@@ -51555,7 +51730,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
         }
         /*else*/ {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1274
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1288
  *                         return 0
  *                     else:
  *                         new_x = new_x + 1             # <<<<<<<<<<<<<<
@@ -51564,7 +51739,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
           __pyx_v_new_x = (__pyx_v_new_x + 1);
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1275
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1289
  *                     else:
  *                         new_x = new_x + 1
  *                         new_low_x = 1             # <<<<<<<<<<<<<<
@@ -51578,7 +51753,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
       }
       __pyx_L19:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1276
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1290
  *                         new_x = new_x + 1
  *                         new_low_x = 1
  *                 if f_low - f_back_low[0] < min_fx_size:             # <<<<<<<<<<<<<<
@@ -51588,7 +51763,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
       __pyx_t_4 = ((__pyx_v_f_low - (__pyx_v_f_back_low[0])) < __pyx_v_min_fx_size);
       if (__pyx_t_4) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1277
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1291
  *                         new_low_x = 1
  *                 if f_low - f_back_low[0] < min_fx_size:
  *                     f_back_low[0] = f_low - min_fx_size             # <<<<<<<<<<<<<<
@@ -51597,7 +51772,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
         (__pyx_v_f_back_low[0]) = (__pyx_v_f_low - __pyx_v_min_fx_size);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1278
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1292
  *                 if f_low - f_back_low[0] < min_fx_size:
  *                     f_back_low[0] = f_low - min_fx_size
  *                     if f_back_high[0] - f_back_low[0] > max_f_len:             # <<<<<<<<<<<<<<
@@ -51607,7 +51782,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
         __pyx_t_4 = (((__pyx_v_f_back_high[0]) - (__pyx_v_f_back_low[0])) > __pyx_v_max_f_len);
         if (__pyx_t_4) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1280
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1294
  *                     if f_back_high[0] - f_back_low[0] > max_f_len:
  *                         # FAIL: extension required on low side violates max initial length
  *                         return 0             # <<<<<<<<<<<<<<
@@ -51620,7 +51795,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
         }
         __pyx_L22:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1281
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1295
  *                         # FAIL: extension required on low side violates max initial length
  *                         return 0
  *                     if f_back_low[0] < 0:             # <<<<<<<<<<<<<<
@@ -51630,7 +51805,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
         __pyx_t_4 = ((__pyx_v_f_back_low[0]) < 0);
         if (__pyx_t_4) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1283
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1297
  *                     if f_back_low[0] < 0:
  *                         # FAIL: extension required on low side violates sentence boundary
  *                         return 0             # <<<<<<<<<<<<<<
@@ -51649,22 +51824,22 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     }
     __pyx_L18:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1285
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1299
  *                         return 0
  * 
  *             if f_high != f_back_high[0]:             # <<<<<<<<<<<<<<
  *                 if new_high_x == 0:
  *                     if new_x >= max_new_x:
  */
-    __pyx_t_2 = PyInt_FromLong((__pyx_v_f_back_high[0])); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyInt_FromLong((__pyx_v_f_back_high[0])); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_6 = PyObject_RichCompare(__pyx_v_f_high, __pyx_t_2, Py_NE); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyObject_RichCompare(__pyx_v_f_high, __pyx_t_2, Py_NE); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     if (__pyx_t_4) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1286
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1300
  * 
  *             if f_high != f_back_high[0]:
  *                 if new_high_x == 0:             # <<<<<<<<<<<<<<
@@ -51674,7 +51849,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
       __pyx_t_4 = (__pyx_v_new_high_x == 0);
       if (__pyx_t_4) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1287
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1301
  *             if f_high != f_back_high[0]:
  *                 if new_high_x == 0:
  *                     if new_x >= max_new_x:             # <<<<<<<<<<<<<<
@@ -51684,7 +51859,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
         __pyx_t_4 = (__pyx_v_new_x >= __pyx_v_max_new_x);
         if (__pyx_t_4) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1289
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1303
  *                     if new_x >= max_new_x:
  *                         # FAIL: extension required on high side violates max # of gaps
  *                         return 0             # <<<<<<<<<<<<<<
@@ -51697,7 +51872,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
         }
         /*else*/ {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1291
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1305
  *                         return 0
  *                     else:
  *                         new_x = new_x + 1             # <<<<<<<<<<<<<<
@@ -51706,7 +51881,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
           __pyx_v_new_x = (__pyx_v_new_x + 1);
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1292
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1306
  *                     else:
  *                         new_x = new_x + 1
  *                         new_high_x = 1             # <<<<<<<<<<<<<<
@@ -51720,44 +51895,44 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
       }
       __pyx_L25:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1293
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1307
  *                         new_x = new_x + 1
  *                         new_high_x = 1
  *                 if f_back_high[0] - f_high < min_fx_size:             # <<<<<<<<<<<<<<
  *                     f_back_high[0] = f_high + min_fx_size
  *                     if f_back_high[0] - f_back_low[0] > max_f_len:
  */
-      __pyx_t_6 = PyInt_FromLong((__pyx_v_f_back_high[0])); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PyInt_FromLong((__pyx_v_f_back_high[0])); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_6);
-      __pyx_t_2 = PyNumber_Subtract(__pyx_t_6, __pyx_v_f_high); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_Subtract(__pyx_t_6, __pyx_v_f_high); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-      __pyx_t_6 = PyInt_FromLong(__pyx_v_min_fx_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PyInt_FromLong(__pyx_v_min_fx_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_6);
-      __pyx_t_7 = PyObject_RichCompare(__pyx_t_2, __pyx_t_6, Py_LT); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyObject_RichCompare(__pyx_t_2, __pyx_t_6, Py_LT); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-      __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       if (__pyx_t_4) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1294
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1308
  *                         new_high_x = 1
  *                 if f_back_high[0] - f_high < min_fx_size:
  *                     f_back_high[0] = f_high + min_fx_size             # <<<<<<<<<<<<<<
  *                     if f_back_high[0] - f_back_low[0] > max_f_len:
  *                         # FAIL: extension required on high side violates max initial length
  */
-        __pyx_t_7 = PyInt_FromLong(__pyx_v_min_fx_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1294; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PyInt_FromLong(__pyx_v_min_fx_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_7);
-        __pyx_t_6 = PyNumber_Add(__pyx_v_f_high, __pyx_t_7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1294; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_6 = PyNumber_Add(__pyx_v_f_high, __pyx_t_7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_6);
         __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-        __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_t_6); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1294; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_t_6); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
         (__pyx_v_f_back_high[0]) = __pyx_t_1;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1295
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1309
  *                 if f_back_high[0] - f_high < min_fx_size:
  *                     f_back_high[0] = f_high + min_fx_size
  *                     if f_back_high[0] - f_back_low[0] > max_f_len:             # <<<<<<<<<<<<<<
@@ -51767,7 +51942,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
         __pyx_t_4 = (((__pyx_v_f_back_high[0]) - (__pyx_v_f_back_low[0])) > __pyx_v_max_f_len);
         if (__pyx_t_4) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1297
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1311
  *                     if f_back_high[0] - f_back_low[0] > max_f_len:
  *                         # FAIL: extension required on high side violates max initial length
  *                         return 0             # <<<<<<<<<<<<<<
@@ -51780,7 +51955,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
         }
         __pyx_L28:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1298
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1312
  *                         # FAIL: extension required on high side violates max initial length
  *                         return 0
  *                     if f_back_high[0] > f_sent_len:             # <<<<<<<<<<<<<<
@@ -51790,7 +51965,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
         __pyx_t_4 = ((__pyx_v_f_back_high[0]) > __pyx_v_f_sent_len);
         if (__pyx_t_4) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1300
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1314
  *                     if f_back_high[0] > f_sent_len:
  *                         # FAIL: extension required on high side violates sentence boundary
  *                         return 0             # <<<<<<<<<<<<<<
@@ -51809,7 +51984,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     }
     __pyx_L24:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1302
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1316
  *                         return 0
  * 
  *             e_low_prev = e_low[0]             # <<<<<<<<<<<<<<
@@ -51818,7 +51993,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
     __pyx_v_e_low_prev = (__pyx_v_e_low[0]);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1303
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1317
  * 
  *             e_low_prev = e_low[0]
  *             e_high_prev = e_high[0]             # <<<<<<<<<<<<<<
@@ -51827,29 +52002,29 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
     __pyx_v_e_high_prev = (__pyx_v_e_high[0]);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1305
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1319
  *             e_high_prev = e_high[0]
  * 
  *             self.find_projection(f_back_low[0], f_low_prev, f_links_low, f_links_high, e_low, e_high)             # <<<<<<<<<<<<<<
  *             self.find_projection(f_high_prev, f_back_high[0], f_links_low, f_links_high, e_low, e_high)
  *             if e_low[0] == e_low_prev and e_high[0] == e_high_prev:
  */
-    __pyx_t_6 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->find_projection(__pyx_v_self, (__pyx_v_f_back_low[0]), __pyx_v_f_low_prev, __pyx_v_f_links_low, __pyx_v_f_links_high, __pyx_v_e_low, __pyx_v_e_high); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->find_projection(__pyx_v_self, (__pyx_v_f_back_low[0]), __pyx_v_f_low_prev, __pyx_v_f_links_low, __pyx_v_f_links_high, __pyx_v_e_low, __pyx_v_e_high); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1319; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1306
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1320
  * 
  *             self.find_projection(f_back_low[0], f_low_prev, f_links_low, f_links_high, e_low, e_high)
  *             self.find_projection(f_high_prev, f_back_high[0], f_links_low, f_links_high, e_low, e_high)             # <<<<<<<<<<<<<<
  *             if e_low[0] == e_low_prev and e_high[0] == e_high_prev:
  *                 return 1
  */
-    __pyx_t_6 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->find_projection(__pyx_v_self, __pyx_v_f_high_prev, (__pyx_v_f_back_high[0]), __pyx_v_f_links_low, __pyx_v_f_links_high, __pyx_v_e_low, __pyx_v_e_high); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1306; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->find_projection(__pyx_v_self, __pyx_v_f_high_prev, (__pyx_v_f_back_high[0]), __pyx_v_f_links_low, __pyx_v_f_links_high, __pyx_v_e_low, __pyx_v_e_high); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1320; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1307
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1321
  *             self.find_projection(f_back_low[0], f_low_prev, f_links_low, f_links_high, e_low, e_high)
  *             self.find_projection(f_high_prev, f_back_high[0], f_links_low, f_links_high, e_low, e_high)
  *             if e_low[0] == e_low_prev and e_high[0] == e_high_prev:             # <<<<<<<<<<<<<<
@@ -51865,7 +52040,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     }
     if (__pyx_t_3) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1308
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1322
  *             self.find_projection(f_high_prev, f_back_high[0], f_links_low, f_links_high, e_low, e_high)
  *             if e_low[0] == e_low_prev and e_high[0] == e_high_prev:
  *                 return 1             # <<<<<<<<<<<<<<
@@ -51878,7 +52053,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     }
     __pyx_L30:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1309
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1323
  *             if e_low[0] == e_low_prev and e_high[0] == e_high_prev:
  *                 return 1
  *             if allow_arbitrary_x == 0:             # <<<<<<<<<<<<<<
@@ -51888,7 +52063,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     __pyx_t_3 = (__pyx_v_allow_arbitrary_x == 0);
     if (__pyx_t_3) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1311
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1325
  *             if allow_arbitrary_x == 0:
  *                 # FAIL: arbitrary expansion not permitted
  *                 return 0             # <<<<<<<<<<<<<<
@@ -51901,7 +52076,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     }
     __pyx_L31:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1312
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1326
  *                 # FAIL: arbitrary expansion not permitted
  *                 return 0
  *             if e_high[0] - e_low[0] > max_e_len:             # <<<<<<<<<<<<<<
@@ -51911,7 +52086,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     __pyx_t_3 = (((__pyx_v_e_high[0]) - (__pyx_v_e_low[0])) > __pyx_v_max_e_len);
     if (__pyx_t_3) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1314
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1328
  *             if e_high[0] - e_low[0] > max_e_len:
  *                 # FAIL: re-projection violates sentence max phrase length
  *                 return 0             # <<<<<<<<<<<<<<
@@ -51924,7 +52099,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     }
     __pyx_L32:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1315
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1329
  *                 # FAIL: re-projection violates sentence max phrase length
  *                 return 0
  *             f_low_prev = f_back_low[0]             # <<<<<<<<<<<<<<
@@ -51933,7 +52108,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
     __pyx_v_f_low_prev = (__pyx_v_f_back_low[0]);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1316
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1330
  *                 return 0
  *             f_low_prev = f_back_low[0]
  *             f_high_prev = f_back_high[0]             # <<<<<<<<<<<<<<
@@ -51956,7 +52131,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1319
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1333
  * 
  * 
  *     cdef find_projection(self, int in_low, int in_high, int* in_links_low, int* in_links_high,             # <<<<<<<<<<<<<<
@@ -51974,7 +52149,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_find_projection(CYTHON_U
   int __pyx_t_4;
   __Pyx_RefNannySetupContext("find_projection", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1322
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1336
  *                         int* out_low, int* out_high):
  *         cdef int i
  *         for i from in_low <= i < in_high:             # <<<<<<<<<<<<<<
@@ -51984,7 +52159,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_find_projection(CYTHON_U
   __pyx_t_1 = __pyx_v_in_high;
   for (__pyx_v_i = __pyx_v_in_low; __pyx_v_i < __pyx_t_1; __pyx_v_i++) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1323
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1337
  *         cdef int i
  *         for i from in_low <= i < in_high:
  *             if in_links_low[i] != -1:             # <<<<<<<<<<<<<<
@@ -51994,7 +52169,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_find_projection(CYTHON_U
     __pyx_t_2 = ((__pyx_v_in_links_low[__pyx_v_i]) != -1);
     if (__pyx_t_2) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1324
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1338
  *         for i from in_low <= i < in_high:
  *             if in_links_low[i] != -1:
  *                 if out_low[0] == -1 or in_links_low[i] < out_low[0]:             # <<<<<<<<<<<<<<
@@ -52010,7 +52185,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_find_projection(CYTHON_U
       }
       if (__pyx_t_4) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1325
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1339
  *             if in_links_low[i] != -1:
  *                 if out_low[0] == -1 or in_links_low[i] < out_low[0]:
  *                     out_low[0] = in_links_low[i]             # <<<<<<<<<<<<<<
@@ -52022,7 +52197,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_find_projection(CYTHON_U
       }
       __pyx_L6:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1326
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1340
  *                 if out_low[0] == -1 or in_links_low[i] < out_low[0]:
  *                     out_low[0] = in_links_low[i]
  *                 if out_high[0] == -1 or in_links_high[i] > out_high[0]:             # <<<<<<<<<<<<<<
@@ -52038,7 +52213,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_find_projection(CYTHON_U
       }
       if (__pyx_t_3) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1327
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1341
  *                     out_low[0] = in_links_low[i]
  *                 if out_high[0] == -1 or in_links_high[i] > out_high[0]:
  *                     out_high[0] = in_links_high[i]             # <<<<<<<<<<<<<<
@@ -52060,7 +52235,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_find_projection(CYTHON_U
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1330
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1344
  * 
  * 
  *     cdef int* int_arr_extend(self, int* arr, int* arr_len, int* data, int data_len):             # <<<<<<<<<<<<<<
@@ -52074,7 +52249,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_int_arr_extend(CYTHON_UNUSED
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("int_arr_extend", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1332
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1346
  *     cdef int* int_arr_extend(self, int* arr, int* arr_len, int* data, int data_len):
  *         cdef int new_len
  *         new_len = arr_len[0] + data_len             # <<<<<<<<<<<<<<
@@ -52083,7 +52258,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_int_arr_extend(CYTHON_UNUSED
  */
   __pyx_v_new_len = ((__pyx_v_arr_len[0]) + __pyx_v_data_len);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1333
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1347
  *         cdef int new_len
  *         new_len = arr_len[0] + data_len
  *         arr = <int*> realloc(arr, new_len*sizeof(int))             # <<<<<<<<<<<<<<
@@ -52092,7 +52267,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_int_arr_extend(CYTHON_UNUSED
  */
   __pyx_v_arr = ((int *)realloc(__pyx_v_arr, (__pyx_v_new_len * (sizeof(int)))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1334
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1348
  *         new_len = arr_len[0] + data_len
  *         arr = <int*> realloc(arr, new_len*sizeof(int))
  *         memcpy(arr+arr_len[0], data, data_len*sizeof(int))             # <<<<<<<<<<<<<<
@@ -52101,7 +52276,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_int_arr_extend(CYTHON_UNUSED
  */
   memcpy((__pyx_v_arr + (__pyx_v_arr_len[0])), __pyx_v_data, (__pyx_v_data_len * (sizeof(int))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1335
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1349
  *         arr = <int*> realloc(arr, new_len*sizeof(int))
  *         memcpy(arr+arr_len[0], data, data_len*sizeof(int))
  *         arr_len[0] = new_len             # <<<<<<<<<<<<<<
@@ -52110,7 +52285,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_int_arr_extend(CYTHON_UNUSED
  */
   (__pyx_v_arr_len[0]) = __pyx_v_new_len;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1336
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1350
  *         memcpy(arr+arr_len[0], data, data_len*sizeof(int))
  *         arr_len[0] = new_len
  *         return arr             # <<<<<<<<<<<<<<
@@ -52126,7 +52301,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_int_arr_extend(CYTHON_UNUSED
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1339
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1353
  * 
  * 
  *     cdef extract_phrases(self, int e_low, int e_high, int* e_gap_low, int* e_gap_high, int* e_links_low, int num_gaps,             # <<<<<<<<<<<<<<
@@ -52172,19 +52347,19 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("extract_phrases", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1347
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1361
  *         cdef result
  * 
  *         result = []             # <<<<<<<<<<<<<<
  *         len1 = 0
  *         e_gaps1 = <int*> malloc(0)
  */
-  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1347; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1361; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_result = ((PyObject *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1348
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1362
  * 
  *         result = []
  *         len1 = 0             # <<<<<<<<<<<<<<
@@ -52193,7 +52368,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
   __pyx_v_len1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1349
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1363
  *         result = []
  *         len1 = 0
  *         e_gaps1 = <int*> malloc(0)             # <<<<<<<<<<<<<<
@@ -52202,19 +52377,19 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
   __pyx_v_e_gaps1 = ((int *)malloc(0));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1350
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1364
  *         len1 = 0
  *         e_gaps1 = <int*> malloc(0)
  *         ephr_arr = IntList()             # <<<<<<<<<<<<<<
  * 
  *         e_gap_order = <int*> malloc(num_gaps*sizeof(int))
  */
-  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1364; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_ephr_arr = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1352
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1366
  *         ephr_arr = IntList()
  * 
  *         e_gap_order = <int*> malloc(num_gaps*sizeof(int))             # <<<<<<<<<<<<<<
@@ -52223,7 +52398,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
   __pyx_v_e_gap_order = ((int *)malloc((__pyx_v_num_gaps * (sizeof(int)))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1353
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1367
  * 
  *         e_gap_order = <int*> malloc(num_gaps*sizeof(int))
  *         if num_gaps > 0:             # <<<<<<<<<<<<<<
@@ -52233,7 +52408,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
   __pyx_t_2 = (__pyx_v_num_gaps > 0);
   if (__pyx_t_2) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1354
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1368
  *         e_gap_order = <int*> malloc(num_gaps*sizeof(int))
  *         if num_gaps > 0:
  *             e_gap_order[0] = 0             # <<<<<<<<<<<<<<
@@ -52242,7 +52417,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
     (__pyx_v_e_gap_order[0]) = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1355
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1369
  *         if num_gaps > 0:
  *             e_gap_order[0] = 0
  *             for i from 1 <= i < num_gaps:             # <<<<<<<<<<<<<<
@@ -52252,7 +52427,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
     __pyx_t_3 = __pyx_v_num_gaps;
     for (__pyx_v_i = 1; __pyx_v_i < __pyx_t_3; __pyx_v_i++) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1356
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1370
  *             e_gap_order[0] = 0
  *             for i from 1 <= i < num_gaps:
  *                 for j from 0 <= j < i:             # <<<<<<<<<<<<<<
@@ -52262,7 +52437,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       __pyx_t_4 = __pyx_v_i;
       for (__pyx_v_j = 0; __pyx_v_j < __pyx_t_4; __pyx_v_j++) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1357
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1371
  *             for i from 1 <= i < num_gaps:
  *                 for j from 0 <= j < i:
  *                     if e_gap_low[i] < e_gap_low[j]:             # <<<<<<<<<<<<<<
@@ -52272,7 +52447,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
         __pyx_t_2 = ((__pyx_v_e_gap_low[__pyx_v_i]) < (__pyx_v_e_gap_low[__pyx_v_j]));
         if (__pyx_t_2) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1358
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1372
  *                 for j from 0 <= j < i:
  *                     if e_gap_low[i] < e_gap_low[j]:
  *                         for k from j <= k < i:             # <<<<<<<<<<<<<<
@@ -52282,7 +52457,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
           __pyx_t_5 = __pyx_v_i;
           for (__pyx_v_k = __pyx_v_j; __pyx_v_k < __pyx_t_5; __pyx_v_k++) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1359
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1373
  *                     if e_gap_low[i] < e_gap_low[j]:
  *                         for k from j <= k < i:
  *                             e_gap_order[k+1] = e_gap_order[k]             # <<<<<<<<<<<<<<
@@ -52292,7 +52467,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
             (__pyx_v_e_gap_order[(__pyx_v_k + 1)]) = (__pyx_v_e_gap_order[__pyx_v_k]);
           }
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1360
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1374
  *                         for k from j <= k < i:
  *                             e_gap_order[k+1] = e_gap_order[k]
  *                         e_gap_order[j] = i             # <<<<<<<<<<<<<<
@@ -52301,7 +52476,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
           (__pyx_v_e_gap_order[__pyx_v_j]) = __pyx_v_i;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1361
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1375
  *                             e_gap_order[k+1] = e_gap_order[k]
  *                         e_gap_order[j] = i
  *                         break             # <<<<<<<<<<<<<<
@@ -52315,7 +52490,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       }
       /*else*/ {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1363
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1377
  *                         break
  *                 else:
  *                     e_gap_order[i] = i             # <<<<<<<<<<<<<<
@@ -52330,7 +52505,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1365
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1379
  *                     e_gap_order[i] = i
  * 
  *         e_x_low = e_low             # <<<<<<<<<<<<<<
@@ -52339,7 +52514,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
   __pyx_v_e_x_low = __pyx_v_e_low;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1366
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1380
  * 
  *         e_x_low = e_low
  *         e_x_high = e_high             # <<<<<<<<<<<<<<
@@ -52348,7 +52523,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
   __pyx_v_e_x_high = __pyx_v_e_high;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1367
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1381
  *         e_x_low = e_low
  *         e_x_high = e_high
  *         if not self.tight_phrases:             # <<<<<<<<<<<<<<
@@ -52358,7 +52533,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
   __pyx_t_2 = (!__pyx_v_self->tight_phrases);
   if (__pyx_t_2) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1368
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1382
  *         e_x_high = e_high
  *         if not self.tight_phrases:
  *             while e_x_low > 0 and e_high - e_x_low < self.train_max_initial_size and e_links_low[e_x_low-1] == -1:             # <<<<<<<<<<<<<<
@@ -52381,7 +52556,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       }
       if (!__pyx_t_6) break;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1369
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1383
  *         if not self.tight_phrases:
  *             while e_x_low > 0 and e_high - e_x_low < self.train_max_initial_size and e_links_low[e_x_low-1] == -1:
  *                 e_x_low = e_x_low - 1             # <<<<<<<<<<<<<<
@@ -52391,7 +52566,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       __pyx_v_e_x_low = (__pyx_v_e_x_low - 1);
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1370
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1384
  *             while e_x_low > 0 and e_high - e_x_low < self.train_max_initial_size and e_links_low[e_x_low-1] == -1:
  *                 e_x_low = e_x_low - 1
  *             while e_x_high < e_sent_len and e_x_high - e_low < self.train_max_initial_size and e_links_low[e_x_high] == -1:             # <<<<<<<<<<<<<<
@@ -52414,7 +52589,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       }
       if (!__pyx_t_2) break;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1371
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1385
  *                 e_x_low = e_x_low - 1
  *             while e_x_high < e_sent_len and e_x_high - e_low < self.train_max_initial_size and e_links_low[e_x_high] == -1:
  *                 e_x_high = e_x_high + 1             # <<<<<<<<<<<<<<
@@ -52427,7 +52602,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
   }
   __pyx_L11:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1373
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1387
  *                 e_x_high = e_x_high + 1
  * 
  *         for i from e_x_low <= i <= e_low:             # <<<<<<<<<<<<<<
@@ -52437,7 +52612,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
   __pyx_t_3 = __pyx_v_e_low;
   for (__pyx_v_i = __pyx_v_e_x_low; __pyx_v_i <= __pyx_t_3; __pyx_v_i++) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1374
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1388
  * 
  *         for i from e_x_low <= i <= e_low:
  *             e_gaps1 = self.int_arr_extend(e_gaps1, &len1, &i, 1)             # <<<<<<<<<<<<<<
@@ -52447,7 +52622,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
     __pyx_v_e_gaps1 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->int_arr_extend(__pyx_v_self, __pyx_v_e_gaps1, (&__pyx_v_len1), (&__pyx_v_i), 1);
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1376
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1390
  *             e_gaps1 = self.int_arr_extend(e_gaps1, &len1, &i, 1)
  * 
  *         for i from 0 <= i < num_gaps:             # <<<<<<<<<<<<<<
@@ -52457,7 +52632,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
   __pyx_t_3 = __pyx_v_num_gaps;
   for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_3; __pyx_v_i++) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1377
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1391
  * 
  *         for i from 0 <= i < num_gaps:
  *             e_gaps2 = <int*> malloc(0)             # <<<<<<<<<<<<<<
@@ -52466,7 +52641,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
     __pyx_v_e_gaps2 = ((int *)malloc(0));
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1378
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1392
  *         for i from 0 <= i < num_gaps:
  *             e_gaps2 = <int*> malloc(0)
  *             len2 = 0             # <<<<<<<<<<<<<<
@@ -52475,7 +52650,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
     __pyx_v_len2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1380
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1394
  *             len2 = 0
  * 
  *             j = e_gap_order[i]             # <<<<<<<<<<<<<<
@@ -52484,7 +52659,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
     __pyx_v_j = (__pyx_v_e_gap_order[__pyx_v_i]);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1381
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1395
  * 
  *             j = e_gap_order[i]
  *             e_x_gap_low = e_gap_low[j]             # <<<<<<<<<<<<<<
@@ -52493,7 +52668,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
     __pyx_v_e_x_gap_low = (__pyx_v_e_gap_low[__pyx_v_j]);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1382
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1396
  *             j = e_gap_order[i]
  *             e_x_gap_low = e_gap_low[j]
  *             e_x_gap_high = e_gap_high[j]             # <<<<<<<<<<<<<<
@@ -52502,7 +52677,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
     __pyx_v_e_x_gap_high = (__pyx_v_e_gap_high[__pyx_v_j]);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1383
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1397
  *             e_x_gap_low = e_gap_low[j]
  *             e_x_gap_high = e_gap_high[j]
  *             if not self.tight_phrases:             # <<<<<<<<<<<<<<
@@ -52512,7 +52687,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
     __pyx_t_2 = (!__pyx_v_self->tight_phrases);
     if (__pyx_t_2) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1384
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1398
  *             e_x_gap_high = e_gap_high[j]
  *             if not self.tight_phrases:
  *                 while e_x_gap_low > e_x_low and e_links_low[e_x_gap_low-1] == -1:             # <<<<<<<<<<<<<<
@@ -52529,7 +52704,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
         }
         if (!__pyx_t_7) break;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1385
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1399
  *             if not self.tight_phrases:
  *                 while e_x_gap_low > e_x_low and e_links_low[e_x_gap_low-1] == -1:
  *                     e_x_gap_low = e_x_gap_low - 1             # <<<<<<<<<<<<<<
@@ -52539,7 +52714,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
         __pyx_v_e_x_gap_low = (__pyx_v_e_x_gap_low - 1);
       }
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1386
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1400
  *                 while e_x_gap_low > e_x_low and e_links_low[e_x_gap_low-1] == -1:
  *                     e_x_gap_low = e_x_gap_low - 1
  *                 while e_x_gap_high < e_x_high and e_links_low[e_x_gap_high] == -1:             # <<<<<<<<<<<<<<
@@ -52556,7 +52731,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
         }
         if (!__pyx_t_6) break;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1387
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1401
  *                     e_x_gap_low = e_x_gap_low - 1
  *                 while e_x_gap_high < e_x_high and e_links_low[e_x_gap_high] == -1:
  *                     e_x_gap_high = e_x_gap_high + 1             # <<<<<<<<<<<<<<
@@ -52569,7 +52744,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
     }
     __pyx_L20:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1389
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1403
  *                     e_x_gap_high = e_x_gap_high + 1
  * 
  *             k = 0             # <<<<<<<<<<<<<<
@@ -52578,7 +52753,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
     __pyx_v_k = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1390
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1404
  * 
  *             k = 0
  *             step = 1+(i*2)             # <<<<<<<<<<<<<<
@@ -52587,7 +52762,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
     __pyx_v_step = (1 + (__pyx_v_i * 2));
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1391
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1405
  *             k = 0
  *             step = 1+(i*2)
  *             while k < len1:             # <<<<<<<<<<<<<<
@@ -52598,7 +52773,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       __pyx_t_6 = (__pyx_v_k < __pyx_v_len1);
       if (!__pyx_t_6) break;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1392
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1406
  *             step = 1+(i*2)
  *             while k < len1:
  *                 for m from e_x_gap_low <= m <= e_gap_low[j]:             # <<<<<<<<<<<<<<
@@ -52608,7 +52783,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       __pyx_t_4 = (__pyx_v_e_gap_low[__pyx_v_j]);
       for (__pyx_v_m = __pyx_v_e_x_gap_low; __pyx_v_m <= __pyx_t_4; __pyx_v_m++) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1393
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1407
  *             while k < len1:
  *                 for m from e_x_gap_low <= m <= e_gap_low[j]:
  *                     if m >= e_gaps1[k+step-1]:             # <<<<<<<<<<<<<<
@@ -52618,7 +52793,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
         __pyx_t_6 = (__pyx_v_m >= (__pyx_v_e_gaps1[((__pyx_v_k + __pyx_v_step) - 1)]));
         if (__pyx_t_6) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1394
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1408
  *                 for m from e_x_gap_low <= m <= e_gap_low[j]:
  *                     if m >= e_gaps1[k+step-1]:
  *                         for n from e_gap_high[j] <= n <= e_x_gap_high:             # <<<<<<<<<<<<<<
@@ -52628,7 +52803,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
           __pyx_t_5 = __pyx_v_e_x_gap_high;
           for (__pyx_v_n = (__pyx_v_e_gap_high[__pyx_v_j]); __pyx_v_n <= __pyx_t_5; __pyx_v_n++) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1395
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1409
  *                     if m >= e_gaps1[k+step-1]:
  *                         for n from e_gap_high[j] <= n <= e_x_gap_high:
  *                             if n-m >= 1:    # extractor.py doesn't restrict target-side gap length             # <<<<<<<<<<<<<<
@@ -52638,7 +52813,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
             __pyx_t_6 = ((__pyx_v_n - __pyx_v_m) >= 1);
             if (__pyx_t_6) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1396
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1410
  *                         for n from e_gap_high[j] <= n <= e_x_gap_high:
  *                             if n-m >= 1:    # extractor.py doesn't restrict target-side gap length
  *                                 e_gaps2 = self.int_arr_extend(e_gaps2, &len2, e_gaps1+k, step)             # <<<<<<<<<<<<<<
@@ -52647,7 +52822,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
               __pyx_v_e_gaps2 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->int_arr_extend(__pyx_v_self, __pyx_v_e_gaps2, (&__pyx_v_len2), (__pyx_v_e_gaps1 + __pyx_v_k), __pyx_v_step);
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1397
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1411
  *                             if n-m >= 1:    # extractor.py doesn't restrict target-side gap length
  *                                 e_gaps2 = self.int_arr_extend(e_gaps2, &len2, e_gaps1+k, step)
  *                                 e_gaps2 = self.int_arr_extend(e_gaps2, &len2, &m, 1)             # <<<<<<<<<<<<<<
@@ -52656,7 +52831,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
               __pyx_v_e_gaps2 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->int_arr_extend(__pyx_v_self, __pyx_v_e_gaps2, (&__pyx_v_len2), (&__pyx_v_m), 1);
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1398
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1412
  *                                 e_gaps2 = self.int_arr_extend(e_gaps2, &len2, e_gaps1+k, step)
  *                                 e_gaps2 = self.int_arr_extend(e_gaps2, &len2, &m, 1)
  *                                 e_gaps2 = self.int_arr_extend(e_gaps2, &len2, &n, 1)             # <<<<<<<<<<<<<<
@@ -52673,7 +52848,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
         __pyx_L29:;
       }
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1399
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1413
  *                                 e_gaps2 = self.int_arr_extend(e_gaps2, &len2, &m, 1)
  *                                 e_gaps2 = self.int_arr_extend(e_gaps2, &len2, &n, 1)
  *                 k = k + step             # <<<<<<<<<<<<<<
@@ -52683,7 +52858,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       __pyx_v_k = (__pyx_v_k + __pyx_v_step);
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1400
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1414
  *                                 e_gaps2 = self.int_arr_extend(e_gaps2, &len2, &n, 1)
  *                 k = k + step
  *             free(e_gaps1)             # <<<<<<<<<<<<<<
@@ -52692,7 +52867,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
     free(__pyx_v_e_gaps1);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1401
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1415
  *                 k = k + step
  *             free(e_gaps1)
  *             e_gaps1 = e_gaps2             # <<<<<<<<<<<<<<
@@ -52701,7 +52876,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
     __pyx_v_e_gaps1 = __pyx_v_e_gaps2;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1402
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1416
  *             free(e_gaps1)
  *             e_gaps1 = e_gaps2
  *             len1 = len2             # <<<<<<<<<<<<<<
@@ -52711,7 +52886,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
     __pyx_v_len1 = __pyx_v_len2;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1404
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1418
  *             len1 = len2
  * 
  *         step = 1+(num_gaps*2)             # <<<<<<<<<<<<<<
@@ -52720,7 +52895,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
   __pyx_v_step = (1 + (__pyx_v_num_gaps * 2));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1405
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1419
  * 
  *         step = 1+(num_gaps*2)
  *         e_gaps2 = <int*> malloc(0)             # <<<<<<<<<<<<<<
@@ -52729,7 +52904,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
   __pyx_v_e_gaps2 = ((int *)malloc(0));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1406
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1420
  *         step = 1+(num_gaps*2)
  *         e_gaps2 = <int*> malloc(0)
  *         len2 = 0             # <<<<<<<<<<<<<<
@@ -52738,7 +52913,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
   __pyx_v_len2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1407
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1421
  *         e_gaps2 = <int*> malloc(0)
  *         len2 = 0
  *         for i from e_high <= i <= e_x_high:             # <<<<<<<<<<<<<<
@@ -52748,7 +52923,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
   __pyx_t_3 = __pyx_v_e_x_high;
   for (__pyx_v_i = __pyx_v_e_high; __pyx_v_i <= __pyx_t_3; __pyx_v_i++) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1408
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1422
  *         len2 = 0
  *         for i from e_high <= i <= e_x_high:
  *             j = 0             # <<<<<<<<<<<<<<
@@ -52757,7 +52932,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
     __pyx_v_j = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1409
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1423
  *         for i from e_high <= i <= e_x_high:
  *             j = 0
  *             while j < len1:             # <<<<<<<<<<<<<<
@@ -52768,7 +52943,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       __pyx_t_6 = (__pyx_v_j < __pyx_v_len1);
       if (!__pyx_t_6) break;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1410
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1424
  *             j = 0
  *             while j < len1:
  *                 if i - e_gaps1[j] <= self.train_max_initial_size and i >= e_gaps1[j+step-1]:             # <<<<<<<<<<<<<<
@@ -52784,7 +52959,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       }
       if (__pyx_t_2) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1411
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1425
  *             while j < len1:
  *                 if i - e_gaps1[j] <= self.train_max_initial_size and i >= e_gaps1[j+step-1]:
  *                     e_gaps2 = self.int_arr_extend(e_gaps2, &len2, e_gaps1+j, step)             # <<<<<<<<<<<<<<
@@ -52793,7 +52968,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
         __pyx_v_e_gaps2 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->int_arr_extend(__pyx_v_self, __pyx_v_e_gaps2, (&__pyx_v_len2), (__pyx_v_e_gaps1 + __pyx_v_j), __pyx_v_step);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1412
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1426
  *                 if i - e_gaps1[j] <= self.train_max_initial_size and i >= e_gaps1[j+step-1]:
  *                     e_gaps2 = self.int_arr_extend(e_gaps2, &len2, e_gaps1+j, step)
  *                     e_gaps2 = self.int_arr_extend(e_gaps2, &len2, &i, 1)             # <<<<<<<<<<<<<<
@@ -52805,7 +52980,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       }
       __pyx_L37:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1413
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1427
  *                     e_gaps2 = self.int_arr_extend(e_gaps2, &len2, e_gaps1+j, step)
  *                     e_gaps2 = self.int_arr_extend(e_gaps2, &len2, &i, 1)
  *                 j = j + step             # <<<<<<<<<<<<<<
@@ -52816,7 +52991,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
     }
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1414
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1428
  *                     e_gaps2 = self.int_arr_extend(e_gaps2, &len2, &i, 1)
  *                 j = j + step
  *         free(e_gaps1)             # <<<<<<<<<<<<<<
@@ -52825,7 +53000,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
   free(__pyx_v_e_gaps1);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1415
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1429
  *                 j = j + step
  *         free(e_gaps1)
  *         e_gaps1 = e_gaps2             # <<<<<<<<<<<<<<
@@ -52834,7 +53009,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
   __pyx_v_e_gaps1 = __pyx_v_e_gaps2;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1416
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1430
  *         free(e_gaps1)
  *         e_gaps1 = e_gaps2
  *         len1 = len2             # <<<<<<<<<<<<<<
@@ -52843,7 +53018,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
   __pyx_v_len1 = __pyx_v_len2;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1418
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1432
  *         len1 = len2
  * 
  *         step = (num_gaps+1)*2             # <<<<<<<<<<<<<<
@@ -52852,7 +53027,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
   __pyx_v_step = ((__pyx_v_num_gaps + 1) * 2);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1419
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1433
  * 
  *         step = (num_gaps+1)*2
  *         i = 0             # <<<<<<<<<<<<<<
@@ -52861,7 +53036,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
   __pyx_v_i = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1421
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1435
  *         i = 0
  * 
  *         while i < len1:             # <<<<<<<<<<<<<<
@@ -52872,7 +53047,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
     __pyx_t_2 = (__pyx_v_i < __pyx_v_len1);
     if (!__pyx_t_2) break;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1422
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1436
  * 
  *         while i < len1:
  *             ephr_arr._clear()             # <<<<<<<<<<<<<<
@@ -52881,7 +53056,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
     ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_ephr_arr->__pyx_vtab)->_clear(__pyx_v_ephr_arr);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1423
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1437
  *         while i < len1:
  *             ephr_arr._clear()
  *             num_chunks = 0             # <<<<<<<<<<<<<<
@@ -52890,20 +53065,20 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
     __pyx_v_num_chunks = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1424
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1438
  *             ephr_arr._clear()
  *             num_chunks = 0
  *             indexes = []             # <<<<<<<<<<<<<<
  *             for j from 0 <= j < num_gaps+1:
  *                 if e_gaps1[i+2*j] < e_gaps1[i+(2*j)+1]:
  */
-    __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1438; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_XDECREF(((PyObject *)__pyx_v_indexes));
     __pyx_v_indexes = __pyx_t_1;
     __pyx_t_1 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1425
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1439
  *             num_chunks = 0
  *             indexes = []
  *             for j from 0 <= j < num_gaps+1:             # <<<<<<<<<<<<<<
@@ -52913,7 +53088,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
     __pyx_t_9 = (__pyx_v_num_gaps + 1);
     for (__pyx_v_j = 0; __pyx_v_j < __pyx_t_9; __pyx_v_j++) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1426
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1440
  *             indexes = []
  *             for j from 0 <= j < num_gaps+1:
  *                 if e_gaps1[i+2*j] < e_gaps1[i+(2*j)+1]:             # <<<<<<<<<<<<<<
@@ -52923,7 +53098,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       __pyx_t_2 = ((__pyx_v_e_gaps1[(__pyx_v_i + (2 * __pyx_v_j))]) < (__pyx_v_e_gaps1[((__pyx_v_i + (2 * __pyx_v_j)) + 1)]));
       if (__pyx_t_2) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1427
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1441
  *             for j from 0 <= j < num_gaps+1:
  *                 if e_gaps1[i+2*j] < e_gaps1[i+(2*j)+1]:
  *                     num_chunks = num_chunks + 1             # <<<<<<<<<<<<<<
@@ -52935,7 +53110,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       }
       __pyx_L42:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1428
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1442
  *                 if e_gaps1[i+2*j] < e_gaps1[i+(2*j)+1]:
  *                     num_chunks = num_chunks + 1
  *                 for k from e_gaps1[i+2*j] <= k < e_gaps1[i+(2*j)+1]:             # <<<<<<<<<<<<<<
@@ -52945,19 +53120,19 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       __pyx_t_3 = (__pyx_v_e_gaps1[((__pyx_v_i + (2 * __pyx_v_j)) + 1)]);
       for (__pyx_v_k = (__pyx_v_e_gaps1[(__pyx_v_i + (2 * __pyx_v_j))]); __pyx_v_k < __pyx_t_3; __pyx_v_k++) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1429
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1443
  *                     num_chunks = num_chunks + 1
  *                 for k from e_gaps1[i+2*j] <= k < e_gaps1[i+(2*j)+1]:
  *                     indexes.append(k)             # <<<<<<<<<<<<<<
  *                     ephr_arr._append(self.eid2symid[self.eda.data.arr[e_sent_start+k]])
  *                 if j < num_gaps:
  */
-        __pyx_t_1 = PyInt_FromLong(__pyx_v_k); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyInt_FromLong(__pyx_v_k); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1443; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
-        __pyx_t_10 = PyList_Append(__pyx_v_indexes, __pyx_t_1); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_10 = PyList_Append(__pyx_v_indexes, __pyx_t_1); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1443; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1430
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1444
  *                 for k from e_gaps1[i+2*j] <= k < e_gaps1[i+(2*j)+1]:
  *                     indexes.append(k)
  *                     ephr_arr._append(self.eid2symid[self.eda.data.arr[e_sent_start+k]])             # <<<<<<<<<<<<<<
@@ -52965,14 +53140,14 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  *                     indexes.append(sym_setindex(self.category, e_gap_order[j]+1))
  */
         __pyx_t_4 = (__pyx_v_self->eda->data->arr[(__pyx_v_e_sent_start + __pyx_v_k)]);
-        __pyx_t_1 = __Pyx_GetItemInt(((PyObject *)__pyx_v_self->eid2symid), __pyx_t_4, sizeof(int), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1430; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = __Pyx_GetItemInt(((PyObject *)__pyx_v_self->eid2symid), __pyx_t_4, sizeof(int), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1444; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
-        __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1430; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1444; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
         ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_ephr_arr->__pyx_vtab)->_append(__pyx_v_ephr_arr, __pyx_t_4);
       }
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1431
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1445
  *                     indexes.append(k)
  *                     ephr_arr._append(self.eid2symid[self.eda.data.arr[e_sent_start+k]])
  *                 if j < num_gaps:             # <<<<<<<<<<<<<<
@@ -52982,19 +53157,19 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       __pyx_t_2 = (__pyx_v_j < __pyx_v_num_gaps);
       if (__pyx_t_2) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1432
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1446
  *                     ephr_arr._append(self.eid2symid[self.eda.data.arr[e_sent_start+k]])
  *                 if j < num_gaps:
  *                     indexes.append(sym_setindex(self.category, e_gap_order[j]+1))             # <<<<<<<<<<<<<<
  *                     ephr_arr._append(sym_setindex(self.category, e_gap_order[j]+1))
  *             i = i + step
  */
-        __pyx_t_1 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, ((__pyx_v_e_gap_order[__pyx_v_j]) + 1))); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1432; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, ((__pyx_v_e_gap_order[__pyx_v_j]) + 1))); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
-        __pyx_t_10 = PyList_Append(__pyx_v_indexes, __pyx_t_1); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1432; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_10 = PyList_Append(__pyx_v_indexes, __pyx_t_1); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1433
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1447
  *                 if j < num_gaps:
  *                     indexes.append(sym_setindex(self.category, e_gap_order[j]+1))
  *                     ephr_arr._append(sym_setindex(self.category, e_gap_order[j]+1))             # <<<<<<<<<<<<<<
@@ -53007,7 +53182,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       __pyx_L45:;
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1434
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1448
  *                     indexes.append(sym_setindex(self.category, e_gap_order[j]+1))
  *                     ephr_arr._append(sym_setindex(self.category, e_gap_order[j]+1))
  *             i = i + step             # <<<<<<<<<<<<<<
@@ -53016,7 +53191,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
     __pyx_v_i = (__pyx_v_i + __pyx_v_step);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1435
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1449
  *                     ephr_arr._append(sym_setindex(self.category, e_gap_order[j]+1))
  *             i = i + step
  *             if ephr_arr.len <= self.max_target_length and num_chunks <= self.max_target_chunks:             # <<<<<<<<<<<<<<
@@ -53032,22 +53207,22 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
     }
     if (__pyx_t_7) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1436
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1450
  *             i = i + step
  *             if ephr_arr.len <= self.max_target_length and num_chunks <= self.max_target_chunks:
  *                 result.append((Phrase(ephr_arr),indexes))             # <<<<<<<<<<<<<<
  * 
  *         free(e_gaps1)
  */
-      __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1436; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_INCREF(((PyObject *)__pyx_v_ephr_arr));
       PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_v_ephr_arr));
       __Pyx_GIVEREF(((PyObject *)__pyx_v_ephr_arr));
-      __pyx_t_11 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1436; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_11 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_11);
       __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-      __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1436; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_11);
       __Pyx_GIVEREF(__pyx_t_11);
@@ -53055,7 +53230,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       PyTuple_SET_ITEM(__pyx_t_1, 1, ((PyObject *)__pyx_v_indexes));
       __Pyx_GIVEREF(((PyObject *)__pyx_v_indexes));
       __pyx_t_11 = 0;
-      __pyx_t_11 = __Pyx_PyObject_Append(__pyx_v_result, ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1436; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_11 = __Pyx_PyObject_Append(__pyx_v_result, ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_11);
       __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
       __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
@@ -53064,7 +53239,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
     __pyx_L46:;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1438
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1452
  *                 result.append((Phrase(ephr_arr),indexes))
  * 
  *         free(e_gaps1)             # <<<<<<<<<<<<<<
@@ -53073,7 +53248,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
   free(__pyx_v_e_gaps1);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1439
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1453
  * 
  *         free(e_gaps1)
  *         free(e_gap_order)             # <<<<<<<<<<<<<<
@@ -53082,7 +53257,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
   free(__pyx_v_e_gap_order);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1440
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1454
  *         free(e_gaps1)
  *         free(e_gap_order)
  *         return result             # <<<<<<<<<<<<<<
@@ -53110,7 +53285,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1442
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1456
  *         return result
  * 
  *     cdef IntList create_alignments(self, int* sent_links, int num_links, findexes, eindexes):             # <<<<<<<<<<<<<<
@@ -53138,55 +53313,55 @@ static struct __pyx_obj_3_sa_IntList *__pyx_f_3_sa_23HieroCachingRuleFactory_cre
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("create_alignments", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1444
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1458
  *     cdef IntList create_alignments(self, int* sent_links, int num_links, findexes, eindexes):
  *         cdef unsigned i
  *         cdef IntList ret = IntList()             # <<<<<<<<<<<<<<
  *         for i in range(len(findexes)):
  *             s = findexes[i]
  */
-  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1444; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1458; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_ret = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1445
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1459
  *         cdef unsigned i
  *         cdef IntList ret = IntList()
  *         for i in range(len(findexes)):             # <<<<<<<<<<<<<<
  *             s = findexes[i]
  *             if (s<0):
  */
-  __pyx_t_2 = PyObject_Length(__pyx_v_findexes); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1445; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Length(__pyx_v_findexes); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
     __pyx_v_i = __pyx_t_3;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1446
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1460
  *         cdef IntList ret = IntList()
  *         for i in range(len(findexes)):
  *             s = findexes[i]             # <<<<<<<<<<<<<<
  *             if (s<0):
  *                 continue
  */
-    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_findexes, __pyx_v_i, sizeof(unsigned int)+1, PyLong_FromUnsignedLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_findexes, __pyx_v_i, sizeof(unsigned int)+1, PyLong_FromUnsignedLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_XDECREF(__pyx_v_s);
     __pyx_v_s = __pyx_t_1;
     __pyx_t_1 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1447
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1461
  *         for i in range(len(findexes)):
  *             s = findexes[i]
  *             if (s<0):             # <<<<<<<<<<<<<<
  *                 continue
  *             idx = 0
  */
-    __pyx_t_1 = PyObject_RichCompare(__pyx_v_s, __pyx_int_0, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_RichCompare(__pyx_v_s, __pyx_int_0, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1461; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1461; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     if (__pyx_t_4) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1448
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1462
  *             s = findexes[i]
  *             if (s<0):
  *                 continue             # <<<<<<<<<<<<<<
@@ -53198,7 +53373,7 @@ static struct __pyx_obj_3_sa_IntList *__pyx_f_3_sa_23HieroCachingRuleFactory_cre
     }
     __pyx_L5:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1449
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1463
  *             if (s<0):
  *                 continue
  *             idx = 0             # <<<<<<<<<<<<<<
@@ -53209,7 +53384,7 @@ static struct __pyx_obj_3_sa_IntList *__pyx_f_3_sa_23HieroCachingRuleFactory_cre
     __Pyx_XDECREF(__pyx_v_idx);
     __pyx_v_idx = __pyx_int_0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1450
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1464
  *                 continue
  *             idx = 0
  *             while (idx < num_links*2):             # <<<<<<<<<<<<<<
@@ -53217,51 +53392,51 @@ static struct __pyx_obj_3_sa_IntList *__pyx_f_3_sa_23HieroCachingRuleFactory_cre
  *                     j = eindexes.index(sent_links[idx+1])
  */
     while (1) {
-      __pyx_t_1 = PyInt_FromLong((__pyx_v_num_links * 2)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyInt_FromLong((__pyx_v_num_links * 2)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_5 = PyObject_RichCompare(__pyx_v_idx, __pyx_t_1, Py_LT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyObject_RichCompare(__pyx_v_idx, __pyx_t_1, Py_LT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       if (!__pyx_t_4) break;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1451
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1465
  *             idx = 0
  *             while (idx < num_links*2):
  *                 if (sent_links[idx] == s):             # <<<<<<<<<<<<<<
  *                     j = eindexes.index(sent_links[idx+1])
  *                     ret.append(i*65536+j)
  */
-      __pyx_t_6 = __Pyx_PyIndex_AsSsize_t(__pyx_v_idx); if (unlikely((__pyx_t_6 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1451; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_5 = PyInt_FromLong((__pyx_v_sent_links[__pyx_t_6])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1451; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyIndex_AsSsize_t(__pyx_v_idx); if (unlikely((__pyx_t_6 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyInt_FromLong((__pyx_v_sent_links[__pyx_t_6])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_1 = PyObject_RichCompare(__pyx_t_5, __pyx_v_s, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1451; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_RichCompare(__pyx_t_5, __pyx_v_s, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1451; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       if (__pyx_t_4) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1452
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1466
  *             while (idx < num_links*2):
  *                 if (sent_links[idx] == s):
  *                     j = eindexes.index(sent_links[idx+1])             # <<<<<<<<<<<<<<
  *                     ret.append(i*65536+j)
  *                 idx += 2
  */
-        __pyx_t_1 = PyObject_GetAttr(__pyx_v_eindexes, __pyx_n_s__index); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1452; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyObject_GetAttr(__pyx_v_eindexes, __pyx_n_s__index); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
-        __pyx_t_5 = PyNumber_Add(__pyx_v_idx, __pyx_int_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1452; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = PyNumber_Add(__pyx_v_idx, __pyx_int_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_5);
-        __pyx_t_6 = __Pyx_PyIndex_AsSsize_t(__pyx_t_5); if (unlikely((__pyx_t_6 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1452; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_6 = __Pyx_PyIndex_AsSsize_t(__pyx_t_5); if (unlikely((__pyx_t_6 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-        __pyx_t_5 = PyInt_FromLong((__pyx_v_sent_links[__pyx_t_6])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1452; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = PyInt_FromLong((__pyx_v_sent_links[__pyx_t_6])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_5);
-        __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1452; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_7);
         PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5);
         __Pyx_GIVEREF(__pyx_t_5);
         __pyx_t_5 = 0;
-        __pyx_t_5 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_7), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1452; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_7), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_5);
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
         __Pyx_DECREF(((PyObject *)__pyx_t_7)); __pyx_t_7 = 0;
@@ -53269,19 +53444,19 @@ static struct __pyx_obj_3_sa_IntList *__pyx_f_3_sa_23HieroCachingRuleFactory_cre
         __pyx_v_j = __pyx_t_5;
         __pyx_t_5 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1453
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1467
  *                 if (sent_links[idx] == s):
  *                     j = eindexes.index(sent_links[idx+1])
  *                     ret.append(i*65536+j)             # <<<<<<<<<<<<<<
  *                 idx += 2
  *         return ret
  */
-        __pyx_t_5 = PyInt_FromLong((__pyx_v_i * 65536)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1453; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = PyInt_FromLong((__pyx_v_i * 65536)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_5);
-        __pyx_t_7 = PyNumber_Add(__pyx_t_5, __pyx_v_j); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1453; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PyNumber_Add(__pyx_t_5, __pyx_v_j); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_7);
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-        __pyx_t_5 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_ret), __pyx_t_7); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1453; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_ret), __pyx_t_7); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_5);
         __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
@@ -53289,14 +53464,14 @@ static struct __pyx_obj_3_sa_IntList *__pyx_f_3_sa_23HieroCachingRuleFactory_cre
       }
       __pyx_L8:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1454
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1468
  *                     j = eindexes.index(sent_links[idx+1])
  *                     ret.append(i*65536+j)
  *                 idx += 2             # <<<<<<<<<<<<<<
  *         return ret
  * 
  */
-      __pyx_t_5 = PyNumber_InPlaceAdd(__pyx_v_idx, __pyx_int_2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1454; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyNumber_InPlaceAdd(__pyx_v_idx, __pyx_int_2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_DECREF(__pyx_v_idx);
       __pyx_v_idx = __pyx_t_5;
@@ -53305,7 +53480,7 @@ static struct __pyx_obj_3_sa_IntList *__pyx_f_3_sa_23HieroCachingRuleFactory_cre
     __pyx_L3_continue:;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1455
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1469
  *                     ret.append(i*65536+j)
  *                 idx += 2
  *         return ret             # <<<<<<<<<<<<<<
@@ -53335,7 +53510,7 @@ static struct __pyx_obj_3_sa_IntList *__pyx_f_3_sa_23HieroCachingRuleFactory_cre
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1457
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1471
  *         return ret
  * 
  *     cdef extract(self, Phrase phrase, Matching* matching, int* chunklen, int num_chunks):             # <<<<<<<<<<<<<<
@@ -53429,19 +53604,19 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("extract", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1470
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1484
  *         cdef reason_for_failure
  * 
  *         fphr_arr = IntList()             # <<<<<<<<<<<<<<
  *         phrase_len = phrase.n
  *         extracts = []
  */
-  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1470; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1484; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_fphr_arr = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1471
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1485
  * 
  *         fphr_arr = IntList()
  *         phrase_len = phrase.n             # <<<<<<<<<<<<<<
@@ -53450,19 +53625,19 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_phrase_len = __pyx_v_phrase->n;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1472
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1486
  *         fphr_arr = IntList()
  *         phrase_len = phrase.n
  *         extracts = []             # <<<<<<<<<<<<<<
  *         sent_links = self.alignment._get_sent_links(matching.sent_id, &num_links)
  * 
  */
-  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1472; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1486; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_extracts = ((PyObject *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1473
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1487
  *         phrase_len = phrase.n
  *         extracts = []
  *         sent_links = self.alignment._get_sent_links(matching.sent_id, &num_links)             # <<<<<<<<<<<<<<
@@ -53471,7 +53646,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_sent_links = ((struct __pyx_vtabstruct_3_sa_Alignment *)__pyx_v_self->alignment->__pyx_vtab)->_get_sent_links(__pyx_v_self->alignment, __pyx_v_matching->sent_id, (&__pyx_v_num_links));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1475
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1489
  *         sent_links = self.alignment._get_sent_links(matching.sent_id, &num_links)
  * 
  *         e_sent_start = self.eda.sent_index.arr[matching.sent_id]             # <<<<<<<<<<<<<<
@@ -53480,7 +53655,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_e_sent_start = (__pyx_v_self->eda->sent_index->arr[__pyx_v_matching->sent_id]);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1476
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1490
  * 
  *         e_sent_start = self.eda.sent_index.arr[matching.sent_id]
  *         e_sent_end = self.eda.sent_index.arr[matching.sent_id+1]             # <<<<<<<<<<<<<<
@@ -53489,7 +53664,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_e_sent_end = (__pyx_v_self->eda->sent_index->arr[(__pyx_v_matching->sent_id + 1)]);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1477
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1491
  *         e_sent_start = self.eda.sent_index.arr[matching.sent_id]
  *         e_sent_end = self.eda.sent_index.arr[matching.sent_id+1]
  *         e_sent_len = e_sent_end - e_sent_start - 1             # <<<<<<<<<<<<<<
@@ -53498,7 +53673,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_e_sent_len = ((__pyx_v_e_sent_end - __pyx_v_e_sent_start) - 1);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1478
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1492
  *         e_sent_end = self.eda.sent_index.arr[matching.sent_id+1]
  *         e_sent_len = e_sent_end - e_sent_start - 1
  *         f_sent_start = self.fda.sent_index.arr[matching.sent_id]             # <<<<<<<<<<<<<<
@@ -53507,7 +53682,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_f_sent_start = (__pyx_v_self->fda->sent_index->arr[__pyx_v_matching->sent_id]);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1479
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1493
  *         e_sent_len = e_sent_end - e_sent_start - 1
  *         f_sent_start = self.fda.sent_index.arr[matching.sent_id]
  *         f_sent_end = self.fda.sent_index.arr[matching.sent_id+1]             # <<<<<<<<<<<<<<
@@ -53516,7 +53691,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_f_sent_end = (__pyx_v_self->fda->sent_index->arr[(__pyx_v_matching->sent_id + 1)]);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1480
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1494
  *         f_sent_start = self.fda.sent_index.arr[matching.sent_id]
  *         f_sent_end = self.fda.sent_index.arr[matching.sent_id+1]
  *         f_sent_len = f_sent_end - f_sent_start - 1             # <<<<<<<<<<<<<<
@@ -53525,21 +53700,21 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_f_sent_len = ((__pyx_v_f_sent_end - __pyx_v_f_sent_start) - 1);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1482
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1496
  *         f_sent_len = f_sent_end - f_sent_start - 1
  * 
  *         self.findexes1.reset()             # <<<<<<<<<<<<<<
  *         sofar = 0
  *         for i in range(num_chunks):
  */
-  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes1), __pyx_n_s__reset); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1482; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes1), __pyx_n_s__reset); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1482; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1483
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1497
  * 
  *         self.findexes1.reset()
  *         sofar = 0             # <<<<<<<<<<<<<<
@@ -53549,7 +53724,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
   __Pyx_INCREF(__pyx_int_0);
   __pyx_v_sofar = __pyx_int_0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1484
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1498
  *         self.findexes1.reset()
  *         sofar = 0
  *         for i in range(num_chunks):             # <<<<<<<<<<<<<<
@@ -53560,7 +53735,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
   for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
     __pyx_v_i = __pyx_t_4;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1485
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1499
  *         sofar = 0
  *         for i in range(num_chunks):
  *             for j in range(chunklen[i]):             # <<<<<<<<<<<<<<
@@ -53571,35 +53746,35 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
       __pyx_v_j = __pyx_t_6;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1486
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1500
  *         for i in range(num_chunks):
  *             for j in range(chunklen[i]):
  *                 self.findexes1.append(matching.arr[matching.start+i]+j-f_sent_start);             # <<<<<<<<<<<<<<
  *                 sofar += 1
  *             if (i+1<num_chunks):
  */
-      __pyx_t_2 = PyInt_FromLong((((__pyx_v_matching->arr[(__pyx_v_matching->start + __pyx_v_i)]) + __pyx_v_j) - __pyx_v_f_sent_start)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1486; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyInt_FromLong((((__pyx_v_matching->arr[(__pyx_v_matching->start + __pyx_v_i)]) + __pyx_v_j) - __pyx_v_f_sent_start)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1500; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_1 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes1), __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1486; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes1), __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1500; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1487
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1501
  *             for j in range(chunklen[i]):
  *                 self.findexes1.append(matching.arr[matching.start+i]+j-f_sent_start);
  *                 sofar += 1             # <<<<<<<<<<<<<<
  *             if (i+1<num_chunks):
  *                 self.findexes1.append(phrase[sofar])
  */
-      __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_sofar, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_sofar, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1501; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_v_sofar);
       __pyx_v_sofar = __pyx_t_1;
       __pyx_t_1 = 0;
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1488
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1502
  *                 self.findexes1.append(matching.arr[matching.start+i]+j-f_sent_start);
  *                 sofar += 1
  *             if (i+1<num_chunks):             # <<<<<<<<<<<<<<
@@ -53609,28 +53784,28 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     __pyx_t_7 = ((__pyx_v_i + 1) < __pyx_v_num_chunks);
     if (__pyx_t_7) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1489
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1503
  *                 sofar += 1
  *             if (i+1<num_chunks):
  *                 self.findexes1.append(phrase[sofar])             # <<<<<<<<<<<<<<
  *                 sofar += 1
  * 
  */
-      __pyx_t_1 = PyObject_GetItem(((PyObject *)__pyx_v_phrase), __pyx_v_sofar); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1489; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_GetItem(((PyObject *)__pyx_v_phrase), __pyx_v_sofar); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1503; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_2 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes1), __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1489; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes1), __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1503; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1490
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1504
  *             if (i+1<num_chunks):
  *                 self.findexes1.append(phrase[sofar])
  *                 sofar += 1             # <<<<<<<<<<<<<<
  * 
  * 
  */
-      __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_sofar, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1490; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_sofar, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1504; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_v_sofar);
       __pyx_v_sofar = __pyx_t_2;
@@ -53640,7 +53815,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     __pyx_L7:;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1493
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1507
  * 
  * 
  *         e_links_low = <int*> malloc(e_sent_len*sizeof(int))             # <<<<<<<<<<<<<<
@@ -53649,7 +53824,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_e_links_low = ((int *)malloc((__pyx_v_e_sent_len * (sizeof(int)))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1494
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1508
  * 
  *         e_links_low = <int*> malloc(e_sent_len*sizeof(int))
  *         e_links_high = <int*> malloc(e_sent_len*sizeof(int))             # <<<<<<<<<<<<<<
@@ -53658,7 +53833,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_e_links_high = ((int *)malloc((__pyx_v_e_sent_len * (sizeof(int)))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1495
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1509
  *         e_links_low = <int*> malloc(e_sent_len*sizeof(int))
  *         e_links_high = <int*> malloc(e_sent_len*sizeof(int))
  *         f_links_low = <int*> malloc(f_sent_len*sizeof(int))             # <<<<<<<<<<<<<<
@@ -53667,7 +53842,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_f_links_low = ((int *)malloc((__pyx_v_f_sent_len * (sizeof(int)))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1496
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1510
  *         e_links_high = <int*> malloc(e_sent_len*sizeof(int))
  *         f_links_low = <int*> malloc(f_sent_len*sizeof(int))
  *         f_links_high = <int*> malloc(f_sent_len*sizeof(int))             # <<<<<<<<<<<<<<
@@ -53676,7 +53851,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_f_links_high = ((int *)malloc((__pyx_v_f_sent_len * (sizeof(int)))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1497
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1511
  *         f_links_low = <int*> malloc(f_sent_len*sizeof(int))
  *         f_links_high = <int*> malloc(f_sent_len*sizeof(int))
  *         f_gap_low = <int*> malloc((num_chunks+1)*sizeof(int))             # <<<<<<<<<<<<<<
@@ -53685,7 +53860,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_f_gap_low = ((int *)malloc(((__pyx_v_num_chunks + 1) * (sizeof(int)))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1498
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1512
  *         f_links_high = <int*> malloc(f_sent_len*sizeof(int))
  *         f_gap_low = <int*> malloc((num_chunks+1)*sizeof(int))
  *         f_gap_high = <int*> malloc((num_chunks+1)*sizeof(int))             # <<<<<<<<<<<<<<
@@ -53694,7 +53869,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_f_gap_high = ((int *)malloc(((__pyx_v_num_chunks + 1) * (sizeof(int)))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1499
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1513
  *         f_gap_low = <int*> malloc((num_chunks+1)*sizeof(int))
  *         f_gap_high = <int*> malloc((num_chunks+1)*sizeof(int))
  *         e_gap_low = <int*> malloc((num_chunks+1)*sizeof(int))             # <<<<<<<<<<<<<<
@@ -53703,7 +53878,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_e_gap_low = ((int *)malloc(((__pyx_v_num_chunks + 1) * (sizeof(int)))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1500
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1514
  *         f_gap_high = <int*> malloc((num_chunks+1)*sizeof(int))
  *         e_gap_low = <int*> malloc((num_chunks+1)*sizeof(int))
  *         e_gap_high = <int*> malloc((num_chunks+1)*sizeof(int))             # <<<<<<<<<<<<<<
@@ -53712,7 +53887,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_e_gap_high = ((int *)malloc(((__pyx_v_num_chunks + 1) * (sizeof(int)))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1501
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1515
  *         e_gap_low = <int*> malloc((num_chunks+1)*sizeof(int))
  *         e_gap_high = <int*> malloc((num_chunks+1)*sizeof(int))
  *         memset(f_gap_low, 0, (num_chunks+1)*sizeof(int))             # <<<<<<<<<<<<<<
@@ -53721,7 +53896,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   memset(__pyx_v_f_gap_low, 0, ((__pyx_v_num_chunks + 1) * (sizeof(int))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1502
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1516
  *         e_gap_high = <int*> malloc((num_chunks+1)*sizeof(int))
  *         memset(f_gap_low, 0, (num_chunks+1)*sizeof(int))
  *         memset(f_gap_high, 0, (num_chunks+1)*sizeof(int))             # <<<<<<<<<<<<<<
@@ -53730,7 +53905,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   memset(__pyx_v_f_gap_high, 0, ((__pyx_v_num_chunks + 1) * (sizeof(int))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1503
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1517
  *         memset(f_gap_low, 0, (num_chunks+1)*sizeof(int))
  *         memset(f_gap_high, 0, (num_chunks+1)*sizeof(int))
  *         memset(e_gap_low, 0, (num_chunks+1)*sizeof(int))             # <<<<<<<<<<<<<<
@@ -53739,7 +53914,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   memset(__pyx_v_e_gap_low, 0, ((__pyx_v_num_chunks + 1) * (sizeof(int))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1504
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1518
  *         memset(f_gap_high, 0, (num_chunks+1)*sizeof(int))
  *         memset(e_gap_low, 0, (num_chunks+1)*sizeof(int))
  *         memset(e_gap_high, 0, (num_chunks+1)*sizeof(int))             # <<<<<<<<<<<<<<
@@ -53748,7 +53923,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   memset(__pyx_v_e_gap_high, 0, ((__pyx_v_num_chunks + 1) * (sizeof(int))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1506
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1520
  *         memset(e_gap_high, 0, (num_chunks+1)*sizeof(int))
  * 
  *         reason_for_failure = ""             # <<<<<<<<<<<<<<
@@ -53758,7 +53933,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
   __Pyx_INCREF(((PyObject *)__pyx_kp_s_45));
   __pyx_v_reason_for_failure = ((PyObject *)__pyx_kp_s_45);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1508
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1522
  *         reason_for_failure = ""
  * 
  *         for i from 0 <= i < e_sent_len:             # <<<<<<<<<<<<<<
@@ -53768,7 +53943,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
   __pyx_t_3 = __pyx_v_e_sent_len;
   for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_3; __pyx_v_i++) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1509
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1523
  * 
  *         for i from 0 <= i < e_sent_len:
  *             e_links_low[i] = -1             # <<<<<<<<<<<<<<
@@ -53777,7 +53952,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
     (__pyx_v_e_links_low[__pyx_v_i]) = -1;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1510
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1524
  *         for i from 0 <= i < e_sent_len:
  *             e_links_low[i] = -1
  *             e_links_high[i] = -1             # <<<<<<<<<<<<<<
@@ -53787,7 +53962,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     (__pyx_v_e_links_high[__pyx_v_i]) = -1;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1511
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1525
  *             e_links_low[i] = -1
  *             e_links_high[i] = -1
  *         for i from 0 <= i < f_sent_len:             # <<<<<<<<<<<<<<
@@ -53797,7 +53972,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
   __pyx_t_3 = __pyx_v_f_sent_len;
   for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_3; __pyx_v_i++) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1512
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1526
  *             e_links_high[i] = -1
  *         for i from 0 <= i < f_sent_len:
  *             f_links_low[i] = -1             # <<<<<<<<<<<<<<
@@ -53806,7 +53981,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
     (__pyx_v_f_links_low[__pyx_v_i]) = -1;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1513
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1527
  *         for i from 0 <= i < f_sent_len:
  *             f_links_low[i] = -1
  *             f_links_high[i] = -1             # <<<<<<<<<<<<<<
@@ -53816,7 +53991,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     (__pyx_v_f_links_high[__pyx_v_i]) = -1;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1519
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1533
  *         # links that we care about (but then how to look up
  *         # when we want to check something on the e side?)
  *         i = 0             # <<<<<<<<<<<<<<
@@ -53825,7 +54000,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_i = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1520
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1534
  *         # when we want to check something on the e side?)
  *         i = 0
  *         while i < num_links*2:             # <<<<<<<<<<<<<<
@@ -53836,7 +54011,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     __pyx_t_7 = (__pyx_v_i < (__pyx_v_num_links * 2));
     if (!__pyx_t_7) break;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1521
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1535
  *         i = 0
  *         while i < num_links*2:
  *             f_i = sent_links[i]             # <<<<<<<<<<<<<<
@@ -53845,7 +54020,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
     __pyx_v_f_i = (__pyx_v_sent_links[__pyx_v_i]);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1522
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1536
  *         while i < num_links*2:
  *             f_i = sent_links[i]
  *             e_i = sent_links[i+1]             # <<<<<<<<<<<<<<
@@ -53854,7 +54029,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
     __pyx_v_e_i = (__pyx_v_sent_links[(__pyx_v_i + 1)]);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1523
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1537
  *             f_i = sent_links[i]
  *             e_i = sent_links[i+1]
  *             if f_links_low[f_i] == -1 or f_links_low[f_i] > e_i:             # <<<<<<<<<<<<<<
@@ -53870,7 +54045,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     }
     if (__pyx_t_9) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1524
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1538
  *             e_i = sent_links[i+1]
  *             if f_links_low[f_i] == -1 or f_links_low[f_i] > e_i:
  *                 f_links_low[f_i] = e_i             # <<<<<<<<<<<<<<
@@ -53882,7 +54057,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     }
     __pyx_L14:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1525
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1539
  *             if f_links_low[f_i] == -1 or f_links_low[f_i] > e_i:
  *                 f_links_low[f_i] = e_i
  *             if f_links_high[f_i] == -1 or f_links_high[f_i] < e_i + 1:             # <<<<<<<<<<<<<<
@@ -53898,7 +54073,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     }
     if (__pyx_t_8) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1526
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1540
  *                 f_links_low[f_i] = e_i
  *             if f_links_high[f_i] == -1 or f_links_high[f_i] < e_i + 1:
  *                 f_links_high[f_i] = e_i + 1             # <<<<<<<<<<<<<<
@@ -53910,7 +54085,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     }
     __pyx_L15:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1527
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1541
  *             if f_links_high[f_i] == -1 or f_links_high[f_i] < e_i + 1:
  *                 f_links_high[f_i] = e_i + 1
  *             if e_links_low[e_i] == -1 or e_links_low[e_i] > f_i:             # <<<<<<<<<<<<<<
@@ -53926,7 +54101,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     }
     if (__pyx_t_7) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1528
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1542
  *                 f_links_high[f_i] = e_i + 1
  *             if e_links_low[e_i] == -1 or e_links_low[e_i] > f_i:
  *                 e_links_low[e_i] = f_i             # <<<<<<<<<<<<<<
@@ -53938,7 +54113,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     }
     __pyx_L16:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1529
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1543
  *             if e_links_low[e_i] == -1 or e_links_low[e_i] > f_i:
  *                 e_links_low[e_i] = f_i
  *             if e_links_high[e_i] == -1 or e_links_high[e_i] < f_i + 1:             # <<<<<<<<<<<<<<
@@ -53954,7 +54129,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     }
     if (__pyx_t_9) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1530
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1544
  *                 e_links_low[e_i] = f_i
  *             if e_links_high[e_i] == -1 or e_links_high[e_i] < f_i + 1:
  *                 e_links_high[e_i] = f_i + 1             # <<<<<<<<<<<<<<
@@ -53966,7 +54141,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     }
     __pyx_L17:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1531
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1545
  *             if e_links_high[e_i] == -1 or e_links_high[e_i] < f_i + 1:
  *                 e_links_high[e_i] = f_i + 1
  *             i = i + 2             # <<<<<<<<<<<<<<
@@ -53976,19 +54151,19 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     __pyx_v_i = (__pyx_v_i + 2);
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1533
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1547
  *             i = i + 2
  * 
  *         als = []             # <<<<<<<<<<<<<<
  *         for x in range(matching.start,matching.end):
  *             al = (matching.arr[x]-f_sent_start,f_links_low[matching.arr[x]-f_sent_start])
  */
-  __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1533; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1547; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_v_als = __pyx_t_2;
   __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1534
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1548
  * 
  *         als = []
  *         for x in range(matching.start,matching.end):             # <<<<<<<<<<<<<<
@@ -53999,18 +54174,18 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
   for (__pyx_t_4 = __pyx_v_matching->start; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
     __pyx_v_x = __pyx_t_4;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1535
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1549
  *         als = []
  *         for x in range(matching.start,matching.end):
  *             al = (matching.arr[x]-f_sent_start,f_links_low[matching.arr[x]-f_sent_start])             # <<<<<<<<<<<<<<
  *             als.append(al)
  *         # check all source-side alignment constraints
  */
-    __pyx_t_2 = PyInt_FromLong(((__pyx_v_matching->arr[__pyx_v_x]) - __pyx_v_f_sent_start)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1535; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyInt_FromLong(((__pyx_v_matching->arr[__pyx_v_x]) - __pyx_v_f_sent_start)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1549; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_1 = PyInt_FromLong((__pyx_v_f_links_low[((__pyx_v_matching->arr[__pyx_v_x]) - __pyx_v_f_sent_start)])); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1535; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyInt_FromLong((__pyx_v_f_links_low[((__pyx_v_matching->arr[__pyx_v_x]) - __pyx_v_f_sent_start)])); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1549; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1535; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1549; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_10);
     PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_2);
     __Pyx_GIVEREF(__pyx_t_2);
@@ -54022,17 +54197,17 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     __pyx_v_al = __pyx_t_10;
     __pyx_t_10 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1536
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1550
  *         for x in range(matching.start,matching.end):
  *             al = (matching.arr[x]-f_sent_start,f_links_low[matching.arr[x]-f_sent_start])
  *             als.append(al)             # <<<<<<<<<<<<<<
  *         # check all source-side alignment constraints
  *         met_constraints = 1
  */
-    __pyx_t_11 = PyList_Append(__pyx_v_als, ((PyObject *)__pyx_v_al)); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1536; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_11 = PyList_Append(__pyx_v_als, ((PyObject *)__pyx_v_al)); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1550; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1538
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1552
  *             als.append(al)
  *         # check all source-side alignment constraints
  *         met_constraints = 1             # <<<<<<<<<<<<<<
@@ -54041,7 +54216,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_met_constraints = 1;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1539
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1553
  *         # check all source-side alignment constraints
  *         met_constraints = 1
  *         if self.require_aligned_terminal:             # <<<<<<<<<<<<<<
@@ -54050,7 +54225,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   if (__pyx_v_self->require_aligned_terminal) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1540
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1554
  *         met_constraints = 1
  *         if self.require_aligned_terminal:
  *             num_aligned_chunks = 0             # <<<<<<<<<<<<<<
@@ -54059,7 +54234,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
     __pyx_v_num_aligned_chunks = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1541
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1555
  *         if self.require_aligned_terminal:
  *             num_aligned_chunks = 0
  *             for i from 0 <= i < num_chunks:             # <<<<<<<<<<<<<<
@@ -54069,7 +54244,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     __pyx_t_3 = __pyx_v_num_chunks;
     for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_3; __pyx_v_i++) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1542
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1556
  *             num_aligned_chunks = 0
  *             for i from 0 <= i < num_chunks:
  *                 for j from 0 <= j < chunklen[i]:             # <<<<<<<<<<<<<<
@@ -54079,7 +54254,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       __pyx_t_4 = (__pyx_v_chunklen[__pyx_v_i]);
       for (__pyx_v_j = 0; __pyx_v_j < __pyx_t_4; __pyx_v_j++) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1543
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1557
  *             for i from 0 <= i < num_chunks:
  *                 for j from 0 <= j < chunklen[i]:
  *                     if f_links_low[matching.arr[matching.start+i]+j-f_sent_start] > -1:             # <<<<<<<<<<<<<<
@@ -54089,7 +54264,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         __pyx_t_9 = ((__pyx_v_f_links_low[(((__pyx_v_matching->arr[(__pyx_v_matching->start + __pyx_v_i)]) + __pyx_v_j) - __pyx_v_f_sent_start)]) > -1);
         if (__pyx_t_9) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1544
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1558
  *                 for j from 0 <= j < chunklen[i]:
  *                     if f_links_low[matching.arr[matching.start+i]+j-f_sent_start] > -1:
  *                         num_aligned_chunks = num_aligned_chunks + 1             # <<<<<<<<<<<<<<
@@ -54098,7 +54273,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
           __pyx_v_num_aligned_chunks = (__pyx_v_num_aligned_chunks + 1);
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1545
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1559
  *                     if f_links_low[matching.arr[matching.start+i]+j-f_sent_start] > -1:
  *                         num_aligned_chunks = num_aligned_chunks + 1
  *                         break             # <<<<<<<<<<<<<<
@@ -54113,7 +54288,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       __pyx_L24_break:;
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1546
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1560
  *                         num_aligned_chunks = num_aligned_chunks + 1
  *                         break
  *             if num_aligned_chunks == 0:             # <<<<<<<<<<<<<<
@@ -54123,7 +54298,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     __pyx_t_9 = (__pyx_v_num_aligned_chunks == 0);
     if (__pyx_t_9) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1547
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1561
  *                         break
  *             if num_aligned_chunks == 0:
  *                 reason_for_failure = "No aligned terminals"             # <<<<<<<<<<<<<<
@@ -54134,7 +54309,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       __Pyx_DECREF(__pyx_v_reason_for_failure);
       __pyx_v_reason_for_failure = ((PyObject *)__pyx_kp_s_126);
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1548
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1562
  *             if num_aligned_chunks == 0:
  *                 reason_for_failure = "No aligned terminals"
  *                 met_constraints = 0             # <<<<<<<<<<<<<<
@@ -54146,7 +54321,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     }
     __pyx_L26:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1549
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1563
  *                 reason_for_failure = "No aligned terminals"
  *                 met_constraints = 0
  *             if self.require_aligned_chunks and num_aligned_chunks < num_chunks:             # <<<<<<<<<<<<<<
@@ -54161,7 +54336,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     }
     if (__pyx_t_7) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1550
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1564
  *                 met_constraints = 0
  *             if self.require_aligned_chunks and num_aligned_chunks < num_chunks:
  *                 reason_for_failure = "Unaligned chunk"             # <<<<<<<<<<<<<<
@@ -54172,7 +54347,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       __Pyx_DECREF(__pyx_v_reason_for_failure);
       __pyx_v_reason_for_failure = ((PyObject *)__pyx_kp_s_127);
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1551
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1565
  *             if self.require_aligned_chunks and num_aligned_chunks < num_chunks:
  *                 reason_for_failure = "Unaligned chunk"
  *                 met_constraints = 0             # <<<<<<<<<<<<<<
@@ -54187,7 +54362,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
   }
   __pyx_L20:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1553
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1567
  *                 met_constraints = 0
  * 
  *         if met_constraints and self.tight_phrases:             # <<<<<<<<<<<<<<
@@ -54202,7 +54377,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
   }
   if (__pyx_t_9) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1555
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1569
  *         if met_constraints and self.tight_phrases:
  *             # outside edge constraints are checked later
  *             for i from 0 <= i < num_chunks-1:             # <<<<<<<<<<<<<<
@@ -54212,7 +54387,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     __pyx_t_12 = (__pyx_v_num_chunks - 1);
     for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_12; __pyx_v_i++) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1556
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1570
  *             # outside edge constraints are checked later
  *             for i from 0 <= i < num_chunks-1:
  *                 if f_links_low[matching.arr[matching.start+i]+chunklen[i]-f_sent_start] == -1:             # <<<<<<<<<<<<<<
@@ -54222,7 +54397,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       __pyx_t_9 = ((__pyx_v_f_links_low[(((__pyx_v_matching->arr[(__pyx_v_matching->start + __pyx_v_i)]) + (__pyx_v_chunklen[__pyx_v_i])) - __pyx_v_f_sent_start)]) == -1);
       if (__pyx_t_9) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1557
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1571
  *             for i from 0 <= i < num_chunks-1:
  *                 if f_links_low[matching.arr[matching.start+i]+chunklen[i]-f_sent_start] == -1:
  *                     reason_for_failure = "Gaps are not tight phrases"             # <<<<<<<<<<<<<<
@@ -54233,7 +54408,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         __Pyx_DECREF(__pyx_v_reason_for_failure);
         __pyx_v_reason_for_failure = ((PyObject *)__pyx_kp_s_128);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1558
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1572
  *                 if f_links_low[matching.arr[matching.start+i]+chunklen[i]-f_sent_start] == -1:
  *                     reason_for_failure = "Gaps are not tight phrases"
  *                     met_constraints = 0             # <<<<<<<<<<<<<<
@@ -54242,7 +54417,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         __pyx_v_met_constraints = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1559
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1573
  *                     reason_for_failure = "Gaps are not tight phrases"
  *                     met_constraints = 0
  *                     break             # <<<<<<<<<<<<<<
@@ -54254,7 +54429,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       }
       __pyx_L31:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1560
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1574
  *                     met_constraints = 0
  *                     break
  *                 if f_links_low[matching.arr[matching.start+i+1]-1-f_sent_start] == -1:             # <<<<<<<<<<<<<<
@@ -54264,7 +54439,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       __pyx_t_9 = ((__pyx_v_f_links_low[(((__pyx_v_matching->arr[((__pyx_v_matching->start + __pyx_v_i) + 1)]) - 1) - __pyx_v_f_sent_start)]) == -1);
       if (__pyx_t_9) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1561
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1575
  *                     break
  *                 if f_links_low[matching.arr[matching.start+i+1]-1-f_sent_start] == -1:
  *                     reason_for_failure = "Gaps are not tight phrases"             # <<<<<<<<<<<<<<
@@ -54275,7 +54450,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         __Pyx_DECREF(__pyx_v_reason_for_failure);
         __pyx_v_reason_for_failure = ((PyObject *)__pyx_kp_s_128);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1562
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1576
  *                 if f_links_low[matching.arr[matching.start+i+1]-1-f_sent_start] == -1:
  *                     reason_for_failure = "Gaps are not tight phrases"
  *                     met_constraints = 0             # <<<<<<<<<<<<<<
@@ -54284,7 +54459,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         __pyx_v_met_constraints = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1563
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1577
  *                     reason_for_failure = "Gaps are not tight phrases"
  *                     met_constraints = 0
  *                     break             # <<<<<<<<<<<<<<
@@ -54301,7 +54476,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
   }
   __pyx_L28:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1565
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1579
  *                     break
  * 
  *         f_low = matching.arr[matching.start] - f_sent_start             # <<<<<<<<<<<<<<
@@ -54310,7 +54485,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_f_low = ((__pyx_v_matching->arr[__pyx_v_matching->start]) - __pyx_v_f_sent_start);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1566
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1580
  * 
  *         f_low = matching.arr[matching.start] - f_sent_start
  *         f_high = matching.arr[matching.start + matching.size - 1] + chunklen[num_chunks-1] - f_sent_start             # <<<<<<<<<<<<<<
@@ -54319,7 +54494,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_f_high = (((__pyx_v_matching->arr[((__pyx_v_matching->start + __pyx_v_matching->size) - 1)]) + (__pyx_v_chunklen[(__pyx_v_num_chunks - 1)])) - __pyx_v_f_sent_start);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1567
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1581
  *         f_low = matching.arr[matching.start] - f_sent_start
  *         f_high = matching.arr[matching.start + matching.size - 1] + chunklen[num_chunks-1] - f_sent_start
  *         if met_constraints:             # <<<<<<<<<<<<<<
@@ -54328,17 +54503,17 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   if (__pyx_v_met_constraints) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1569
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1583
  *         if met_constraints:
  * 
  *             if self.find_fixpoint(f_low, f_high, f_links_low, f_links_high, e_links_low, e_links_high,             # <<<<<<<<<<<<<<
  *                                 -1, -1, &e_low, &e_high, &f_back_low, &f_back_high, f_sent_len, e_sent_len,
  *                                 self.train_max_initial_size, self.train_max_initial_size,
  */
-    __pyx_t_10 = PyInt_FromLong(__pyx_v_f_high); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = PyInt_FromLong(__pyx_v_f_high); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1583; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_10);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1573
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1587
  *                                 self.train_max_initial_size, self.train_max_initial_size,
  *                                 self.train_min_gap_size, 0,
  *                                 self.max_nonterminals - num_chunks + 1, 1, 1, 0, 0):             # <<<<<<<<<<<<<<
@@ -54349,7 +54524,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
     if (__pyx_t_3) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1574
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1588
  *                                 self.train_min_gap_size, 0,
  *                                 self.max_nonterminals - num_chunks + 1, 1, 1, 0, 0):
  *                 gap_error = 0             # <<<<<<<<<<<<<<
@@ -54358,7 +54533,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
       __pyx_v_gap_error = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1575
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1589
  *                                 self.max_nonterminals - num_chunks + 1, 1, 1, 0, 0):
  *                 gap_error = 0
  *                 num_gaps = 0             # <<<<<<<<<<<<<<
@@ -54367,7 +54542,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
       __pyx_v_num_gaps = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1577
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1591
  *                 num_gaps = 0
  * 
  *                 if f_back_low < f_low:             # <<<<<<<<<<<<<<
@@ -54377,7 +54552,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       __pyx_t_9 = (__pyx_v_f_back_low < __pyx_v_f_low);
       if (__pyx_t_9) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1578
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1592
  * 
  *                 if f_back_low < f_low:
  *                     f_gap_low[0] = f_back_low             # <<<<<<<<<<<<<<
@@ -54386,7 +54561,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         (__pyx_v_f_gap_low[0]) = __pyx_v_f_back_low;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1579
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1593
  *                 if f_back_low < f_low:
  *                     f_gap_low[0] = f_back_low
  *                     f_gap_high[0] = f_low             # <<<<<<<<<<<<<<
@@ -54395,7 +54570,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         (__pyx_v_f_gap_high[0]) = __pyx_v_f_low;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1580
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1594
  *                     f_gap_low[0] = f_back_low
  *                     f_gap_high[0] = f_low
  *                     num_gaps = 1             # <<<<<<<<<<<<<<
@@ -54404,7 +54579,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         __pyx_v_num_gaps = 1;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1581
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1595
  *                     f_gap_high[0] = f_low
  *                     num_gaps = 1
  *                     gap_start = 0             # <<<<<<<<<<<<<<
@@ -54413,7 +54588,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         __pyx_v_gap_start = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1582
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1596
  *                     num_gaps = 1
  *                     gap_start = 0
  *                     phrase_len = phrase_len+1             # <<<<<<<<<<<<<<
@@ -54422,7 +54597,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         __pyx_v_phrase_len = (__pyx_v_phrase_len + 1);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1583
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1597
  *                     gap_start = 0
  *                     phrase_len = phrase_len+1
  *                     if phrase_len > self.max_length:             # <<<<<<<<<<<<<<
@@ -54432,7 +54607,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         __pyx_t_9 = (__pyx_v_phrase_len > __pyx_v_self->max_length);
         if (__pyx_t_9) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1584
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1598
  *                     phrase_len = phrase_len+1
  *                     if phrase_len > self.max_length:
  *                         gap_error = 1             # <<<<<<<<<<<<<<
@@ -54444,7 +54619,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         }
         __pyx_L36:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1585
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1599
  *                     if phrase_len > self.max_length:
  *                         gap_error = 1
  *                     if self.tight_phrases:             # <<<<<<<<<<<<<<
@@ -54453,7 +54628,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         if (__pyx_v_self->tight_phrases) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1586
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1600
  *                         gap_error = 1
  *                     if self.tight_phrases:
  *                         if f_links_low[f_back_low] == -1 or f_links_low[f_low-1] == -1:             # <<<<<<<<<<<<<<
@@ -54469,7 +54644,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           }
           if (__pyx_t_8) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1587
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1601
  *                     if self.tight_phrases:
  *                         if f_links_low[f_back_low] == -1 or f_links_low[f_low-1] == -1:
  *                             gap_error = 1             # <<<<<<<<<<<<<<
@@ -54478,7 +54653,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             __pyx_v_gap_error = 1;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1588
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1602
  *                         if f_links_low[f_back_low] == -1 or f_links_low[f_low-1] == -1:
  *                             gap_error = 1
  *                             reason_for_failure = "Inside edges of preceding subphrase are not tight"             # <<<<<<<<<<<<<<
@@ -54498,7 +54673,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       }
       /*else*/ {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1590
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1604
  *                             reason_for_failure = "Inside edges of preceding subphrase are not tight"
  *                 else:
  *                     gap_start = 1             # <<<<<<<<<<<<<<
@@ -54507,7 +54682,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         __pyx_v_gap_start = 1;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1591
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1605
  *                 else:
  *                     gap_start = 1
  *                     if self.tight_phrases and f_links_low[f_low] == -1:             # <<<<<<<<<<<<<<
@@ -54522,7 +54697,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         }
         if (__pyx_t_9) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1594
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1608
  *                         # this is not a hard error.    we can't extract this phrase
  *                         # but we still might be able to extract a superphrase
  *                         met_constraints = 0             # <<<<<<<<<<<<<<
@@ -54536,7 +54711,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       }
       __pyx_L35:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1596
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1610
  *                         met_constraints = 0
  * 
  *                 for i from 0 <= i < matching.size - 1:             # <<<<<<<<<<<<<<
@@ -54546,7 +54721,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       __pyx_t_12 = (__pyx_v_matching->size - 1);
       for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_12; __pyx_v_i++) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1597
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1611
  * 
  *                 for i from 0 <= i < matching.size - 1:
  *                     f_gap_low[1+i] = matching.arr[matching.start+i] + chunklen[i] - f_sent_start             # <<<<<<<<<<<<<<
@@ -54555,7 +54730,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         (__pyx_v_f_gap_low[(1 + __pyx_v_i)]) = (((__pyx_v_matching->arr[(__pyx_v_matching->start + __pyx_v_i)]) + (__pyx_v_chunklen[__pyx_v_i])) - __pyx_v_f_sent_start);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1598
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1612
  *                 for i from 0 <= i < matching.size - 1:
  *                     f_gap_low[1+i] = matching.arr[matching.start+i] + chunklen[i] - f_sent_start
  *                     f_gap_high[1+i] = matching.arr[matching.start+i+1] - f_sent_start             # <<<<<<<<<<<<<<
@@ -54564,7 +54739,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         (__pyx_v_f_gap_high[(1 + __pyx_v_i)]) = ((__pyx_v_matching->arr[((__pyx_v_matching->start + __pyx_v_i) + 1)]) - __pyx_v_f_sent_start);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1599
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1613
  *                     f_gap_low[1+i] = matching.arr[matching.start+i] + chunklen[i] - f_sent_start
  *                     f_gap_high[1+i] = matching.arr[matching.start+i+1] - f_sent_start
  *                     num_gaps = num_gaps + 1             # <<<<<<<<<<<<<<
@@ -54574,7 +54749,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         __pyx_v_num_gaps = (__pyx_v_num_gaps + 1);
       }
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1601
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1615
  *                     num_gaps = num_gaps + 1
  * 
  *                 if f_high < f_back_high:             # <<<<<<<<<<<<<<
@@ -54584,7 +54759,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       __pyx_t_9 = (__pyx_v_f_high < __pyx_v_f_back_high);
       if (__pyx_t_9) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1602
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1616
  * 
  *                 if f_high < f_back_high:
  *                     f_gap_low[gap_start+num_gaps] = f_high             # <<<<<<<<<<<<<<
@@ -54593,7 +54768,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         (__pyx_v_f_gap_low[(__pyx_v_gap_start + __pyx_v_num_gaps)]) = __pyx_v_f_high;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1603
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1617
  *                 if f_high < f_back_high:
  *                     f_gap_low[gap_start+num_gaps] = f_high
  *                     f_gap_high[gap_start+num_gaps] = f_back_high             # <<<<<<<<<<<<<<
@@ -54602,7 +54777,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         (__pyx_v_f_gap_high[(__pyx_v_gap_start + __pyx_v_num_gaps)]) = __pyx_v_f_back_high;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1604
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1618
  *                     f_gap_low[gap_start+num_gaps] = f_high
  *                     f_gap_high[gap_start+num_gaps] = f_back_high
  *                     num_gaps = num_gaps + 1             # <<<<<<<<<<<<<<
@@ -54611,7 +54786,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         __pyx_v_num_gaps = (__pyx_v_num_gaps + 1);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1605
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1619
  *                     f_gap_high[gap_start+num_gaps] = f_back_high
  *                     num_gaps = num_gaps + 1
  *                     phrase_len = phrase_len+1             # <<<<<<<<<<<<<<
@@ -54620,7 +54795,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         __pyx_v_phrase_len = (__pyx_v_phrase_len + 1);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1606
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1620
  *                     num_gaps = num_gaps + 1
  *                     phrase_len = phrase_len+1
  *                     if phrase_len > self.max_length:             # <<<<<<<<<<<<<<
@@ -54630,7 +54805,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         __pyx_t_9 = (__pyx_v_phrase_len > __pyx_v_self->max_length);
         if (__pyx_t_9) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1607
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1621
  *                     phrase_len = phrase_len+1
  *                     if phrase_len > self.max_length:
  *                         gap_error = 1             # <<<<<<<<<<<<<<
@@ -54642,7 +54817,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         }
         __pyx_L43:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1608
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1622
  *                     if phrase_len > self.max_length:
  *                         gap_error = 1
  *                     if self.tight_phrases:             # <<<<<<<<<<<<<<
@@ -54651,7 +54826,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         if (__pyx_v_self->tight_phrases) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1609
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1623
  *                         gap_error = 1
  *                     if self.tight_phrases:
  *                         if f_links_low[f_back_high-1] == -1 or f_links_low[f_high] == -1:             # <<<<<<<<<<<<<<
@@ -54667,7 +54842,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           }
           if (__pyx_t_7) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1610
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1624
  *                     if self.tight_phrases:
  *                         if f_links_low[f_back_high-1] == -1 or f_links_low[f_high] == -1:
  *                             gap_error = 1             # <<<<<<<<<<<<<<
@@ -54676,7 +54851,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             __pyx_v_gap_error = 1;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1611
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1625
  *                         if f_links_low[f_back_high-1] == -1 or f_links_low[f_high] == -1:
  *                             gap_error = 1
  *                             reason_for_failure = "Inside edges of following subphrase are not tight"             # <<<<<<<<<<<<<<
@@ -54696,7 +54871,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       }
       /*else*/ {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1613
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1627
  *                             reason_for_failure = "Inside edges of following subphrase are not tight"
  *                 else:
  *                     if self.tight_phrases and f_links_low[f_high-1] == -1:             # <<<<<<<<<<<<<<
@@ -54711,7 +54886,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         }
         if (__pyx_t_9) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1614
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1628
  *                 else:
  *                     if self.tight_phrases and f_links_low[f_high-1] == -1:
  *                         met_constraints = 0             # <<<<<<<<<<<<<<
@@ -54725,7 +54900,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       }
       __pyx_L42:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1616
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1630
  *                         met_constraints = 0
  * 
  *                 if gap_error == 0:             # <<<<<<<<<<<<<<
@@ -54735,7 +54910,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       __pyx_t_9 = (__pyx_v_gap_error == 0);
       if (__pyx_t_9) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1617
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1631
  * 
  *                 if gap_error == 0:
  *                     e_word_count = e_high - e_low             # <<<<<<<<<<<<<<
@@ -54744,7 +54919,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         __pyx_v_e_word_count = (__pyx_v_e_high - __pyx_v_e_low);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1618
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1632
  *                 if gap_error == 0:
  *                     e_word_count = e_high - e_low
  *                     for i from 0 <= i < num_gaps: # check integrity of subphrases             # <<<<<<<<<<<<<<
@@ -54754,17 +54929,17 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         __pyx_t_3 = __pyx_v_num_gaps;
         for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_3; __pyx_v_i++) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1619
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1633
  *                     e_word_count = e_high - e_low
  *                     for i from 0 <= i < num_gaps: # check integrity of subphrases
  *                         if self.find_fixpoint(f_gap_low[gap_start+i], f_gap_high[gap_start+i],             # <<<<<<<<<<<<<<
  *                                             f_links_low, f_links_high, e_links_low, e_links_high,
  *                                             -1, -1, e_gap_low+gap_start+i, e_gap_high+gap_start+i,
  */
-          __pyx_t_10 = PyInt_FromLong((__pyx_v_f_gap_high[(__pyx_v_gap_start + __pyx_v_i)])); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1619; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_10 = PyInt_FromLong((__pyx_v_f_gap_high[(__pyx_v_gap_start + __pyx_v_i)])); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_10);
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1624
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1638
  *                                             f_gap_low+gap_start+i, f_gap_high+gap_start+i,
  *                                             f_sent_len, e_sent_len,
  *                                             self.train_max_initial_size, self.train_max_initial_size,             # <<<<<<<<<<<<<<
@@ -54775,7 +54950,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
           if (__pyx_t_9) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1626
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1640
  *                                             self.train_max_initial_size, self.train_max_initial_size,
  *                                             0, 0, 0, 0, 0, 0, 0) == 0:
  *                             gap_error = 1             # <<<<<<<<<<<<<<
@@ -54784,18 +54959,18 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             __pyx_v_gap_error = 1;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1627
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1641
  *                                             0, 0, 0, 0, 0, 0, 0) == 0:
  *                             gap_error = 1
  *                             reason_for_failure = "Subphrase [%d, %d] failed integrity check" % (f_gap_low[gap_start+i], f_gap_high[gap_start+i])             # <<<<<<<<<<<<<<
  *                             break
  * 
  */
-            __pyx_t_10 = PyInt_FromLong((__pyx_v_f_gap_low[(__pyx_v_gap_start + __pyx_v_i)])); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1627; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_10 = PyInt_FromLong((__pyx_v_f_gap_low[(__pyx_v_gap_start + __pyx_v_i)])); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_10);
-            __pyx_t_1 = PyInt_FromLong((__pyx_v_f_gap_high[(__pyx_v_gap_start + __pyx_v_i)])); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1627; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_1 = PyInt_FromLong((__pyx_v_f_gap_high[(__pyx_v_gap_start + __pyx_v_i)])); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_1);
-            __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1627; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_2);
             PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_10);
             __Pyx_GIVEREF(__pyx_t_10);
@@ -54803,14 +54978,14 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             __Pyx_GIVEREF(__pyx_t_1);
             __pyx_t_10 = 0;
             __pyx_t_1 = 0;
-            __pyx_t_1 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_131), ((PyObject *)__pyx_t_2)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1627; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_1 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_131), ((PyObject *)__pyx_t_2)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(((PyObject *)__pyx_t_1));
             __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
             __Pyx_DECREF(__pyx_v_reason_for_failure);
             __pyx_v_reason_for_failure = ((PyObject *)__pyx_t_1);
             __pyx_t_1 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1628
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1642
  *                             gap_error = 1
  *                             reason_for_failure = "Subphrase [%d, %d] failed integrity check" % (f_gap_low[gap_start+i], f_gap_high[gap_start+i])
  *                             break             # <<<<<<<<<<<<<<
@@ -54827,7 +55002,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       }
       __pyx_L47:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1630
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1644
  *                             break
  * 
  *                 if gap_error == 0:             # <<<<<<<<<<<<<<
@@ -54837,7 +55012,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       __pyx_t_9 = (__pyx_v_gap_error == 0);
       if (__pyx_t_9) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1631
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1645
  * 
  *                 if gap_error == 0:
  *                     i = 1             # <<<<<<<<<<<<<<
@@ -54846,21 +55021,21 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         __pyx_v_i = 1;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1632
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1646
  *                 if gap_error == 0:
  *                     i = 1
  *                     self.findexes.reset()             # <<<<<<<<<<<<<<
  *                     if f_back_low < f_low:
  *                         fphr_arr._append(sym_setindex(self.category, i))
  */
-        __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__reset); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1632; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__reset); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1646; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
-        __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1632; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1646; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1633
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1647
  *                     i = 1
  *                     self.findexes.reset()
  *                     if f_back_low < f_low:             # <<<<<<<<<<<<<<
@@ -54870,7 +55045,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         __pyx_t_9 = (__pyx_v_f_back_low < __pyx_v_f_low);
         if (__pyx_t_9) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1634
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1648
  *                     self.findexes.reset()
  *                     if f_back_low < f_low:
  *                         fphr_arr._append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
@@ -54879,7 +55054,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
           ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_fphr_arr->__pyx_vtab)->_append(__pyx_v_fphr_arr, __pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i));
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1635
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1649
  *                     if f_back_low < f_low:
  *                         fphr_arr._append(sym_setindex(self.category, i))
  *                         i = i+1             # <<<<<<<<<<<<<<
@@ -54888,16 +55063,16 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
           __pyx_v_i = (__pyx_v_i + 1);
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1636
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1650
  *                         fphr_arr._append(sym_setindex(self.category, i))
  *                         i = i+1
  *                         self.findexes.append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
  *                     self.findexes.extend(self.findexes1)
  *                     for j from 0 <= j < phrase.n:
  */
-          __pyx_t_2 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1636; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_2 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1650; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_2);
-          __pyx_t_1 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1636; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_1 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1650; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_1);
           __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
           __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -54905,27 +55080,27 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         }
         __pyx_L52:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1637
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1651
  *                         i = i+1
  *                         self.findexes.append(sym_setindex(self.category, i))
  *                     self.findexes.extend(self.findexes1)             # <<<<<<<<<<<<<<
  *                     for j from 0 <= j < phrase.n:
  *                         if sym_isvar(phrase.syms[j]):
  */
-        __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__extend); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1637; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__extend); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1651; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
-        __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1637; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1651; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_INCREF(((PyObject *)__pyx_v_self->findexes1));
         PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_v_self->findexes1));
         __Pyx_GIVEREF(((PyObject *)__pyx_v_self->findexes1));
-        __pyx_t_10 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1637; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_10 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1651; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_10);
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
         __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1638
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1652
  *                         self.findexes.append(sym_setindex(self.category, i))
  *                     self.findexes.extend(self.findexes1)
  *                     for j from 0 <= j < phrase.n:             # <<<<<<<<<<<<<<
@@ -54935,7 +55110,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         __pyx_t_3 = __pyx_v_phrase->n;
         for (__pyx_v_j = 0; __pyx_v_j < __pyx_t_3; __pyx_v_j++) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1639
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1653
  *                     self.findexes.extend(self.findexes1)
  *                     for j from 0 <= j < phrase.n:
  *                         if sym_isvar(phrase.syms[j]):             # <<<<<<<<<<<<<<
@@ -54945,7 +55120,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           __pyx_t_4 = __pyx_f_3_sa_sym_isvar((__pyx_v_phrase->syms[__pyx_v_j]));
           if (__pyx_t_4) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1640
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1654
  *                     for j from 0 <= j < phrase.n:
  *                         if sym_isvar(phrase.syms[j]):
  *                             fphr_arr._append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
@@ -54954,7 +55129,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_fphr_arr->__pyx_vtab)->_append(__pyx_v_fphr_arr, __pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i));
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1641
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1655
  *                         if sym_isvar(phrase.syms[j]):
  *                             fphr_arr._append(sym_setindex(self.category, i))
  *                             i = i + 1             # <<<<<<<<<<<<<<
@@ -54966,7 +55141,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           }
           /*else*/ {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1643
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1657
  *                             i = i + 1
  *                         else:
  *                             fphr_arr._append(phrase.syms[j])             # <<<<<<<<<<<<<<
@@ -54978,7 +55153,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           __pyx_L55:;
         }
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1644
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1658
  *                         else:
  *                             fphr_arr._append(phrase.syms[j])
  *                     if f_back_high > f_high:             # <<<<<<<<<<<<<<
@@ -54988,7 +55163,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         __pyx_t_9 = (__pyx_v_f_back_high > __pyx_v_f_high);
         if (__pyx_t_9) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1645
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1659
  *                             fphr_arr._append(phrase.syms[j])
  *                     if f_back_high > f_high:
  *                         fphr_arr._append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
@@ -54997,16 +55172,16 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
           ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_fphr_arr->__pyx_vtab)->_append(__pyx_v_fphr_arr, __pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i));
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1646
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1660
  *                     if f_back_high > f_high:
  *                         fphr_arr._append(sym_setindex(self.category, i))
  *                         self.findexes.append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
  * 
  *                     fphr = Phrase(fphr_arr)
  */
-          __pyx_t_10 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1646; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_10 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_10);
-          __pyx_t_2 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_10); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1646; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_2 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_10); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
           __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -55014,25 +55189,25 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         }
         __pyx_L56:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1648
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1662
  *                         self.findexes.append(sym_setindex(self.category, i))
  * 
  *                     fphr = Phrase(fphr_arr)             # <<<<<<<<<<<<<<
  *                     if met_constraints:
  *                         phrase_list = self.extract_phrases(e_low, e_high, e_gap_low + gap_start, e_gap_high + gap_start, e_links_low, num_gaps,
  */
-        __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1648; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1662; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_INCREF(((PyObject *)__pyx_v_fphr_arr));
         PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_v_fphr_arr));
         __Pyx_GIVEREF(((PyObject *)__pyx_v_fphr_arr));
-        __pyx_t_10 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1648; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_10 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1662; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_10);
         __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
         __pyx_v_fphr = ((struct __pyx_obj_3_sa_Phrase *)__pyx_t_10);
         __pyx_t_10 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1649
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1663
  * 
  *                     fphr = Phrase(fphr_arr)
  *                     if met_constraints:             # <<<<<<<<<<<<<<
@@ -55041,47 +55216,47 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         if (__pyx_v_met_constraints) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1652
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1666
  *                         phrase_list = self.extract_phrases(e_low, e_high, e_gap_low + gap_start, e_gap_high + gap_start, e_links_low, num_gaps,
  *                                             f_back_low, f_back_high, f_gap_low + gap_start, f_gap_high + gap_start, f_links_low,
  *                                             matching.sent_id, e_sent_len, e_sent_start)             # <<<<<<<<<<<<<<
  *                         if len(phrase_list) > 0:
  *                             pair_count = 1.0 / len(phrase_list)
  */
-          __pyx_t_10 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->extract_phrases(__pyx_v_self, __pyx_v_e_low, __pyx_v_e_high, (__pyx_v_e_gap_low + __pyx_v_gap_start), (__pyx_v_e_gap_high + __pyx_v_gap_start), __pyx_v_e_links_low, __pyx_v_num_gaps, __pyx_v_f_back_low, __pyx_v_f_back_high, (__pyx_v_f_gap_low + __pyx_v_gap_start), (__pyx_v_f_gap_high + __pyx_v_gap_start), __pyx_v_f_links_low, __pyx_v_matching->sent_id, __pyx_v_e_sent_len, __pyx_v_e_sent_start); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1650; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_10 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->extract_phrases(__pyx_v_self, __pyx_v_e_low, __pyx_v_e_high, (__pyx_v_e_gap_low + __pyx_v_gap_start), (__pyx_v_e_gap_high + __pyx_v_gap_start), __pyx_v_e_links_low, __pyx_v_num_gaps, __pyx_v_f_back_low, __pyx_v_f_back_high, (__pyx_v_f_gap_low + __pyx_v_gap_start), (__pyx_v_f_gap_high + __pyx_v_gap_start), __pyx_v_f_links_low, __pyx_v_matching->sent_id, __pyx_v_e_sent_len, __pyx_v_e_sent_start); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1664; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_10);
           __pyx_v_phrase_list = __pyx_t_10;
           __pyx_t_10 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1653
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1667
  *                                             f_back_low, f_back_high, f_gap_low + gap_start, f_gap_high + gap_start, f_links_low,
  *                                             matching.sent_id, e_sent_len, e_sent_start)
  *                         if len(phrase_list) > 0:             # <<<<<<<<<<<<<<
  *                             pair_count = 1.0 / len(phrase_list)
  *                         else:
  */
-          __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1653; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1667; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __pyx_t_9 = (__pyx_t_13 > 0);
           if (__pyx_t_9) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1654
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1668
  *                                             matching.sent_id, e_sent_len, e_sent_start)
  *                         if len(phrase_list) > 0:
  *                             pair_count = 1.0 / len(phrase_list)             # <<<<<<<<<<<<<<
  *                         else:
  *                             pair_count = 0
  */
-            __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1668; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             if (unlikely(__pyx_t_13 == 0)) {
               PyErr_Format(PyExc_ZeroDivisionError, "float division");
-              {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1668; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             }
             __pyx_v_pair_count = (1.0 / __pyx_t_13);
             goto __pyx_L58;
           }
           /*else*/ {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1656
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1670
  *                             pair_count = 1.0 / len(phrase_list)
  *                         else:
  *                             pair_count = 0             # <<<<<<<<<<<<<<
@@ -55090,22 +55265,22 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             __pyx_v_pair_count = 0.0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1657
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1671
  *                         else:
  *                             pair_count = 0
  *                             reason_for_failure = "Didn't extract anything from [%d, %d] -> [%d, %d]" % (f_back_low, f_back_high, e_low, e_high)             # <<<<<<<<<<<<<<
  *                         for (phrase2,eindexes) in phrase_list:
  *                             als1 = self.create_alignments(sent_links,num_links,self.findexes,eindexes)
  */
-            __pyx_t_10 = PyInt_FromLong(__pyx_v_f_back_low); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1657; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_10 = PyInt_FromLong(__pyx_v_f_back_low); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1671; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_10);
-            __pyx_t_2 = PyInt_FromLong(__pyx_v_f_back_high); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1657; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_2 = PyInt_FromLong(__pyx_v_f_back_high); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1671; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_2);
-            __pyx_t_1 = PyInt_FromLong(__pyx_v_e_low); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1657; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_1 = PyInt_FromLong(__pyx_v_e_low); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1671; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_1);
-            __pyx_t_14 = PyInt_FromLong(__pyx_v_e_high); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1657; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_14 = PyInt_FromLong(__pyx_v_e_high); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1671; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_14);
-            __pyx_t_15 = PyTuple_New(4); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1657; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_15 = PyTuple_New(4); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1671; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_15);
             PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_t_10);
             __Pyx_GIVEREF(__pyx_t_10);
@@ -55119,7 +55294,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             __pyx_t_2 = 0;
             __pyx_t_1 = 0;
             __pyx_t_14 = 0;
-            __pyx_t_14 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_132), ((PyObject *)__pyx_t_15)); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1657; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_14 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_132), ((PyObject *)__pyx_t_15)); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1671; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(((PyObject *)__pyx_t_14));
             __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
             __Pyx_DECREF(__pyx_v_reason_for_failure);
@@ -55128,7 +55303,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           }
           __pyx_L58:;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1658
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1672
  *                             pair_count = 0
  *                             reason_for_failure = "Didn't extract anything from [%d, %d] -> [%d, %d]" % (f_back_low, f_back_high, e_low, e_high)
  *                         for (phrase2,eindexes) in phrase_list:             # <<<<<<<<<<<<<<
@@ -55139,7 +55314,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             __pyx_t_14 = __pyx_v_phrase_list; __Pyx_INCREF(__pyx_t_14); __pyx_t_13 = 0;
             __pyx_t_16 = NULL;
           } else {
-            __pyx_t_13 = -1; __pyx_t_14 = PyObject_GetIter(__pyx_v_phrase_list); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1658; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_13 = -1; __pyx_t_14 = PyObject_GetIter(__pyx_v_phrase_list); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1672; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_14);
             __pyx_t_16 = Py_TYPE(__pyx_t_14)->tp_iternext;
           }
@@ -55147,23 +55322,23 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             if (!__pyx_t_16 && PyList_CheckExact(__pyx_t_14)) {
               if (__pyx_t_13 >= PyList_GET_SIZE(__pyx_t_14)) break;
               #if CYTHON_COMPILING_IN_CPYTHON
-              __pyx_t_15 = PyList_GET_ITEM(__pyx_t_14, __pyx_t_13); __Pyx_INCREF(__pyx_t_15); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1658; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = PyList_GET_ITEM(__pyx_t_14, __pyx_t_13); __Pyx_INCREF(__pyx_t_15); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1672; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               #else
-              __pyx_t_15 = PySequence_ITEM(__pyx_t_14, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1658; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = PySequence_ITEM(__pyx_t_14, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1672; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               #endif
             } else if (!__pyx_t_16 && PyTuple_CheckExact(__pyx_t_14)) {
               if (__pyx_t_13 >= PyTuple_GET_SIZE(__pyx_t_14)) break;
               #if CYTHON_COMPILING_IN_CPYTHON
-              __pyx_t_15 = PyTuple_GET_ITEM(__pyx_t_14, __pyx_t_13); __Pyx_INCREF(__pyx_t_15); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1658; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = PyTuple_GET_ITEM(__pyx_t_14, __pyx_t_13); __Pyx_INCREF(__pyx_t_15); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1672; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               #else
-              __pyx_t_15 = PySequence_ITEM(__pyx_t_14, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1658; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = PySequence_ITEM(__pyx_t_14, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1672; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               #endif
             } else {
               __pyx_t_15 = __pyx_t_16(__pyx_t_14);
               if (unlikely(!__pyx_t_15)) {
                 if (PyErr_Occurred()) {
                   if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-                  else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1658; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1672; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 }
                 break;
               }
@@ -55179,7 +55354,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               if (unlikely(size != 2)) {
                 if (size > 2) __Pyx_RaiseTooManyValuesError(2);
                 else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-                {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1658; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1672; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               }
               #if CYTHON_COMPILING_IN_CPYTHON
               if (likely(PyTuple_CheckExact(sequence))) {
@@ -55192,14 +55367,14 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               __Pyx_INCREF(__pyx_t_1);
               __Pyx_INCREF(__pyx_t_2);
               #else
-              __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1658; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-              __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1658; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1672; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1672; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               #endif
               __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
             } else
             {
               Py_ssize_t index = -1;
-              __pyx_t_10 = PyObject_GetIter(__pyx_t_15); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1658; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_10 = PyObject_GetIter(__pyx_t_15); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1672; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_10);
               __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
               __pyx_t_17 = Py_TYPE(__pyx_t_10)->tp_iternext;
@@ -55207,7 +55382,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               __Pyx_GOTREF(__pyx_t_1);
               index = 1; __pyx_t_2 = __pyx_t_17(__pyx_t_10); if (unlikely(!__pyx_t_2)) goto __pyx_L61_unpacking_failed;
               __Pyx_GOTREF(__pyx_t_2);
-              if (__Pyx_IternextUnpackEndCheck(__pyx_t_17(__pyx_t_10), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1658; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              if (__Pyx_IternextUnpackEndCheck(__pyx_t_17(__pyx_t_10), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1672; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __pyx_t_17 = NULL;
               __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
               goto __pyx_L62_unpacking_done;
@@ -55215,7 +55390,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
               __pyx_t_17 = NULL;
               if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-              {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1658; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1672; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __pyx_L62_unpacking_done:;
             }
             __Pyx_XDECREF(__pyx_v_phrase2);
@@ -55225,7 +55400,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             __pyx_v_eindexes = __pyx_t_2;
             __pyx_t_2 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1659
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1673
  *                             reason_for_failure = "Didn't extract anything from [%d, %d] -> [%d, %d]" % (f_back_low, f_back_high, e_low, e_high)
  *                         for (phrase2,eindexes) in phrase_list:
  *                             als1 = self.create_alignments(sent_links,num_links,self.findexes,eindexes)             # <<<<<<<<<<<<<<
@@ -55234,31 +55409,31 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             __pyx_t_15 = ((PyObject *)__pyx_v_self->findexes);
             __Pyx_INCREF(__pyx_t_15);
-            __pyx_t_2 = ((PyObject *)((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->create_alignments(__pyx_v_self, __pyx_v_sent_links, __pyx_v_num_links, __pyx_t_15, __pyx_v_eindexes)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1659; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_2 = ((PyObject *)((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->create_alignments(__pyx_v_self, __pyx_v_sent_links, __pyx_v_num_links, __pyx_t_15, __pyx_v_eindexes)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1673; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_2);
             __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
             __Pyx_XDECREF(((PyObject *)__pyx_v_als1));
             __pyx_v_als1 = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_2);
             __pyx_t_2 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1660
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1674
  *                         for (phrase2,eindexes) in phrase_list:
  *                             als1 = self.create_alignments(sent_links,num_links,self.findexes,eindexes)
  *                             extracts.append((fphr, phrase2, pair_count, tuple(als1)))             # <<<<<<<<<<<<<<
  * 
  *                     if (num_gaps < self.max_nonterminals and
  */
-            __pyx_t_2 = PyFloat_FromDouble(__pyx_v_pair_count); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_2 = PyFloat_FromDouble(__pyx_v_pair_count); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_2);
-            __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_15);
             __Pyx_INCREF(((PyObject *)__pyx_v_als1));
             PyTuple_SET_ITEM(__pyx_t_15, 0, ((PyObject *)__pyx_v_als1));
             __Pyx_GIVEREF(((PyObject *)__pyx_v_als1));
-            __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_1);
             __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
-            __pyx_t_15 = PyTuple_New(4); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_15 = PyTuple_New(4); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_15);
             __Pyx_INCREF(((PyObject *)__pyx_v_fphr));
             PyTuple_SET_ITEM(__pyx_t_15, 0, ((PyObject *)__pyx_v_fphr));
@@ -55272,7 +55447,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             __Pyx_GIVEREF(__pyx_t_1);
             __pyx_t_2 = 0;
             __pyx_t_1 = 0;
-            __pyx_t_1 = __Pyx_PyObject_Append(__pyx_v_extracts, ((PyObject *)__pyx_t_15)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_1 = __Pyx_PyObject_Append(__pyx_v_extracts, ((PyObject *)__pyx_t_15)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_1);
             __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
             __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -55282,7 +55457,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         }
         __pyx_L57:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1662
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1676
  *                             extracts.append((fphr, phrase2, pair_count, tuple(als1)))
  * 
  *                     if (num_gaps < self.max_nonterminals and             # <<<<<<<<<<<<<<
@@ -55292,7 +55467,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         __pyx_t_9 = (__pyx_v_num_gaps < __pyx_v_self->max_nonterminals);
         if (__pyx_t_9) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1663
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1677
  * 
  *                     if (num_gaps < self.max_nonterminals and
  *                         phrase_len < self.max_length and             # <<<<<<<<<<<<<<
@@ -55302,7 +55477,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           __pyx_t_7 = (__pyx_v_phrase_len < __pyx_v_self->max_length);
           if (__pyx_t_7) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1664
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1678
  *                     if (num_gaps < self.max_nonterminals and
  *                         phrase_len < self.max_length and
  *                         f_back_high - f_back_low + self.train_min_gap_size <= self.train_max_initial_size):             # <<<<<<<<<<<<<<
@@ -55320,7 +55495,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         }
         if (__pyx_t_7) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1665
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1679
  *                         phrase_len < self.max_length and
  *                         f_back_high - f_back_low + self.train_min_gap_size <= self.train_max_initial_size):
  *                         if (f_back_low == f_low and             # <<<<<<<<<<<<<<
@@ -55330,7 +55505,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           __pyx_t_7 = (__pyx_v_f_back_low == __pyx_v_f_low);
           if (__pyx_t_7) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1666
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1680
  *                         f_back_high - f_back_low + self.train_min_gap_size <= self.train_max_initial_size):
  *                         if (f_back_low == f_low and
  *                                 f_low >= self.train_min_gap_size and             # <<<<<<<<<<<<<<
@@ -55340,7 +55515,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             __pyx_t_9 = (__pyx_v_f_low >= __pyx_v_self->train_min_gap_size);
             if (__pyx_t_9) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1667
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1681
  *                         if (f_back_low == f_low and
  *                                 f_low >= self.train_min_gap_size and
  *                                 ((not self.tight_phrases) or (f_links_low[f_low-1] != -1 and f_links_low[f_back_high-1] != -1))):             # <<<<<<<<<<<<<<
@@ -55370,7 +55545,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           }
           if (__pyx_t_9) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1668
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1682
  *                                 f_low >= self.train_min_gap_size and
  *                                 ((not self.tight_phrases) or (f_links_low[f_low-1] != -1 and f_links_low[f_back_high-1] != -1))):
  *                             f_x_low = f_low-self.train_min_gap_size             # <<<<<<<<<<<<<<
@@ -55379,7 +55554,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             __pyx_v_f_x_low = (__pyx_v_f_low - __pyx_v_self->train_min_gap_size);
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1669
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1683
  *                                 ((not self.tight_phrases) or (f_links_low[f_low-1] != -1 and f_links_low[f_back_high-1] != -1))):
  *                             f_x_low = f_low-self.train_min_gap_size
  *                             met_constraints = 1             # <<<<<<<<<<<<<<
@@ -55388,7 +55563,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             __pyx_v_met_constraints = 1;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1670
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1684
  *                             f_x_low = f_low-self.train_min_gap_size
  *                             met_constraints = 1
  *                             if self.tight_phrases:             # <<<<<<<<<<<<<<
@@ -55397,7 +55572,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             if (__pyx_v_self->tight_phrases) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1671
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1685
  *                             met_constraints = 1
  *                             if self.tight_phrases:
  *                                 while f_x_low >= 0 and f_links_low[f_x_low] == -1:             # <<<<<<<<<<<<<<
@@ -55414,7 +55589,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 }
                 if (!__pyx_t_18) break;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1672
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1686
  *                             if self.tight_phrases:
  *                                 while f_x_low >= 0 and f_links_low[f_x_low] == -1:
  *                                     f_x_low = f_x_low - 1             # <<<<<<<<<<<<<<
@@ -55427,7 +55602,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             }
             __pyx_L65:;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1673
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1687
  *                                 while f_x_low >= 0 and f_links_low[f_x_low] == -1:
  *                                     f_x_low = f_x_low - 1
  *                             if f_x_low < 0 or f_back_high - f_x_low > self.train_max_initial_size:             # <<<<<<<<<<<<<<
@@ -55443,7 +55618,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             }
             if (__pyx_t_7) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1674
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1688
  *                                     f_x_low = f_x_low - 1
  *                             if f_x_low < 0 or f_back_high - f_x_low > self.train_max_initial_size:
  *                                 met_constraints = 0             # <<<<<<<<<<<<<<
@@ -55455,7 +55630,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             }
             __pyx_L68:;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1676
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1690
  *                                 met_constraints = 0
  * 
  *                             if (met_constraints and             # <<<<<<<<<<<<<<
@@ -55464,17 +55639,17 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             if (__pyx_v_met_constraints) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1677
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1691
  * 
  *                             if (met_constraints and
  *                                 self.find_fixpoint(f_x_low, f_back_high,             # <<<<<<<<<<<<<<
  *                                             f_links_low, f_links_high, e_links_low, e_links_high,
  *                                             e_low, e_high, &e_x_low, &e_x_high, &f_x_low, &f_x_high,
  */
-              __pyx_t_14 = PyInt_FromLong(__pyx_v_f_back_high); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1677; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_14 = PyInt_FromLong(__pyx_v_f_back_high); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1691; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_14);
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1681
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1695
  *                                             e_low, e_high, &e_x_low, &e_x_high, &f_x_low, &f_x_high,
  *                                             f_sent_len, e_sent_len,
  *                                             self.train_max_initial_size, self.train_max_initial_size,             # <<<<<<<<<<<<<<
@@ -55484,7 +55659,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               if (((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->find_fixpoint(__pyx_v_self, __pyx_v_f_x_low, __pyx_t_14, __pyx_v_f_links_low, __pyx_v_f_links_high, __pyx_v_e_links_low, __pyx_v_e_links_high, __pyx_v_e_low, __pyx_v_e_high, (&__pyx_v_e_x_low), (&__pyx_v_e_x_high), (&__pyx_v_f_x_low), (&__pyx_v_f_x_high), __pyx_v_f_sent_len, __pyx_v_e_sent_len, __pyx_v_self->train_max_initial_size, __pyx_v_self->train_max_initial_size, 1, 1, 1, 1, 0, 1, 0)) {
                 __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1683
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1697
  *                                             self.train_max_initial_size, self.train_max_initial_size,
  *                                             1, 1, 1, 1, 0, 1, 0) and
  *                                 ((not self.tight_phrases) or f_links_low[f_x_low] != -1) and             # <<<<<<<<<<<<<<
@@ -55500,17 +55675,17 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 }
                 if (__pyx_t_9) {
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1684
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1698
  *                                             1, 1, 1, 1, 0, 1, 0) and
  *                                 ((not self.tight_phrases) or f_links_low[f_x_low] != -1) and
  *                                 self.find_fixpoint(f_x_low, f_low,    # check integrity of new subphrase             # <<<<<<<<<<<<<<
  *                                             f_links_low, f_links_high, e_links_low, e_links_high,
  *                                             -1, -1, e_gap_low, e_gap_high, f_gap_low, f_gap_high,
  */
-                  __pyx_t_1 = PyInt_FromLong(__pyx_v_f_low); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1684; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_1 = PyInt_FromLong(__pyx_v_f_low); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1698; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __Pyx_GOTREF(__pyx_t_1);
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1688
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1702
  *                                             -1, -1, e_gap_low, e_gap_high, f_gap_low, f_gap_high,
  *                                             f_sent_len, e_sent_len,
  *                                             self.train_max_initial_size, self.train_max_initial_size,             # <<<<<<<<<<<<<<
@@ -55533,7 +55708,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             }
             if (__pyx_t_7) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1690
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1704
  *                                             self.train_max_initial_size, self.train_max_initial_size,
  *                                             0, 0, 0, 0, 0, 0, 0)):
  *                                 fphr_arr._clear()             # <<<<<<<<<<<<<<
@@ -55542,7 +55717,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
               ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_fphr_arr->__pyx_vtab)->_clear(__pyx_v_fphr_arr);
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1691
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1705
  *                                             0, 0, 0, 0, 0, 0, 0)):
  *                                 fphr_arr._clear()
  *                                 i = 1             # <<<<<<<<<<<<<<
@@ -55551,35 +55726,35 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
               __pyx_v_i = 1;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1692
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1706
  *                                 fphr_arr._clear()
  *                                 i = 1
  *                                 self.findexes.reset()             # <<<<<<<<<<<<<<
  *                                 self.findexes.append(sym_setindex(self.category, i))
  *                                 fphr_arr._append(sym_setindex(self.category, i))
  */
-              __pyx_t_14 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__reset); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1692; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_14 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__reset); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1706; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_14);
-              __pyx_t_1 = PyObject_Call(__pyx_t_14, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1692; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_1 = PyObject_Call(__pyx_t_14, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1706; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_1);
               __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
               __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1693
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1707
  *                                 i = 1
  *                                 self.findexes.reset()
  *                                 self.findexes.append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
  *                                 fphr_arr._append(sym_setindex(self.category, i))
  *                                 i = i+1
  */
-              __pyx_t_1 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1693; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_1 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1707; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_1);
-              __pyx_t_14 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1693; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_14 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1707; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_14);
               __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
               __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1694
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1708
  *                                 self.findexes.reset()
  *                                 self.findexes.append(sym_setindex(self.category, i))
  *                                 fphr_arr._append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
@@ -55588,7 +55763,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
               ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_fphr_arr->__pyx_vtab)->_append(__pyx_v_fphr_arr, __pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i));
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1695
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1709
  *                                 self.findexes.append(sym_setindex(self.category, i))
  *                                 fphr_arr._append(sym_setindex(self.category, i))
  *                                 i = i+1             # <<<<<<<<<<<<<<
@@ -55597,27 +55772,27 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
               __pyx_v_i = (__pyx_v_i + 1);
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1696
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1710
  *                                 fphr_arr._append(sym_setindex(self.category, i))
  *                                 i = i+1
  *                                 self.findexes.extend(self.findexes1)             # <<<<<<<<<<<<<<
  *                                 for j from 0 <= j < phrase.n:
  *                                     if sym_isvar(phrase.syms[j]):
  */
-              __pyx_t_14 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__extend); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1696; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_14 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__extend); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1710; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_14);
-              __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1696; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1710; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_1);
               __Pyx_INCREF(((PyObject *)__pyx_v_self->findexes1));
               PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_v_self->findexes1));
               __Pyx_GIVEREF(((PyObject *)__pyx_v_self->findexes1));
-              __pyx_t_15 = PyObject_Call(__pyx_t_14, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1696; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = PyObject_Call(__pyx_t_14, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1710; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_15);
               __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
               __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
               __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1697
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1711
  *                                 i = i+1
  *                                 self.findexes.extend(self.findexes1)
  *                                 for j from 0 <= j < phrase.n:             # <<<<<<<<<<<<<<
@@ -55627,7 +55802,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               __pyx_t_3 = __pyx_v_phrase->n;
               for (__pyx_v_j = 0; __pyx_v_j < __pyx_t_3; __pyx_v_j++) {
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1698
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1712
  *                                 self.findexes.extend(self.findexes1)
  *                                 for j from 0 <= j < phrase.n:
  *                                     if sym_isvar(phrase.syms[j]):             # <<<<<<<<<<<<<<
@@ -55637,7 +55812,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __pyx_t_4 = __pyx_f_3_sa_sym_isvar((__pyx_v_phrase->syms[__pyx_v_j]));
                 if (__pyx_t_4) {
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1699
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1713
  *                                 for j from 0 <= j < phrase.n:
  *                                     if sym_isvar(phrase.syms[j]):
  *                                         fphr_arr._append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
@@ -55646,7 +55821,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
                   ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_fphr_arr->__pyx_vtab)->_append(__pyx_v_fphr_arr, __pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i));
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1700
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1714
  *                                     if sym_isvar(phrase.syms[j]):
  *                                         fphr_arr._append(sym_setindex(self.category, i))
  *                                         i = i + 1             # <<<<<<<<<<<<<<
@@ -55658,7 +55833,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 }
                 /*else*/ {
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1702
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1716
  *                                         i = i + 1
  *                                     else:
  *                                         fphr_arr._append(phrase.syms[j])             # <<<<<<<<<<<<<<
@@ -55670,7 +55845,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __pyx_L72:;
               }
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1703
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1717
  *                                     else:
  *                                         fphr_arr._append(phrase.syms[j])
  *                                 if f_back_high > f_high:             # <<<<<<<<<<<<<<
@@ -55680,7 +55855,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               __pyx_t_7 = (__pyx_v_f_back_high > __pyx_v_f_high);
               if (__pyx_t_7) {
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1704
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1718
  *                                         fphr_arr._append(phrase.syms[j])
  *                                 if f_back_high > f_high:
  *                                     fphr_arr._append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
@@ -55689,16 +55864,16 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
                 ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_fphr_arr->__pyx_vtab)->_append(__pyx_v_fphr_arr, __pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i));
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1705
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1719
  *                                 if f_back_high > f_high:
  *                                     fphr_arr._append(sym_setindex(self.category, i))
  *                                     self.findexes.append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
  *                                 fphr = Phrase(fphr_arr)
  *                                 phrase_list = self.extract_phrases(e_x_low, e_x_high, e_gap_low, e_gap_high, e_links_low, num_gaps+1,
  */
-                __pyx_t_15 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1705; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_15);
-                __pyx_t_1 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_15); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1705; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_1 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_15); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_1);
                 __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
                 __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -55706,67 +55881,67 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               }
               __pyx_L73:;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1706
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1720
  *                                     fphr_arr._append(sym_setindex(self.category, i))
  *                                     self.findexes.append(sym_setindex(self.category, i))
  *                                 fphr = Phrase(fphr_arr)             # <<<<<<<<<<<<<<
  *                                 phrase_list = self.extract_phrases(e_x_low, e_x_high, e_gap_low, e_gap_high, e_links_low, num_gaps+1,
  *                                                     f_x_low, f_x_high, f_gap_low, f_gap_high, f_links_low, matching.sent_id,
  */
-              __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1706; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1720; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_1);
               __Pyx_INCREF(((PyObject *)__pyx_v_fphr_arr));
               PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_v_fphr_arr));
               __Pyx_GIVEREF(((PyObject *)__pyx_v_fphr_arr));
-              __pyx_t_15 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1706; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1720; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_15);
               __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
               __Pyx_DECREF(((PyObject *)__pyx_v_fphr));
               __pyx_v_fphr = ((struct __pyx_obj_3_sa_Phrase *)__pyx_t_15);
               __pyx_t_15 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1709
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1723
  *                                 phrase_list = self.extract_phrases(e_x_low, e_x_high, e_gap_low, e_gap_high, e_links_low, num_gaps+1,
  *                                                     f_x_low, f_x_high, f_gap_low, f_gap_high, f_links_low, matching.sent_id,
  *                                                     e_sent_len, e_sent_start)             # <<<<<<<<<<<<<<
  *                                 if len(phrase_list) > 0:
  *                                     pair_count = 1.0 / len(phrase_list)
  */
-              __pyx_t_15 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->extract_phrases(__pyx_v_self, __pyx_v_e_x_low, __pyx_v_e_x_high, __pyx_v_e_gap_low, __pyx_v_e_gap_high, __pyx_v_e_links_low, (__pyx_v_num_gaps + 1), __pyx_v_f_x_low, __pyx_v_f_x_high, __pyx_v_f_gap_low, __pyx_v_f_gap_high, __pyx_v_f_links_low, __pyx_v_matching->sent_id, __pyx_v_e_sent_len, __pyx_v_e_sent_start); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1707; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->extract_phrases(__pyx_v_self, __pyx_v_e_x_low, __pyx_v_e_x_high, __pyx_v_e_gap_low, __pyx_v_e_gap_high, __pyx_v_e_links_low, (__pyx_v_num_gaps + 1), __pyx_v_f_x_low, __pyx_v_f_x_high, __pyx_v_f_gap_low, __pyx_v_f_gap_high, __pyx_v_f_links_low, __pyx_v_matching->sent_id, __pyx_v_e_sent_len, __pyx_v_e_sent_start); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1721; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_15);
               __Pyx_XDECREF(__pyx_v_phrase_list);
               __pyx_v_phrase_list = __pyx_t_15;
               __pyx_t_15 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1710
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1724
  *                                                     f_x_low, f_x_high, f_gap_low, f_gap_high, f_links_low, matching.sent_id,
  *                                                     e_sent_len, e_sent_start)
  *                                 if len(phrase_list) > 0:             # <<<<<<<<<<<<<<
  *                                     pair_count = 1.0 / len(phrase_list)
  *                                 else:
  */
-              __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1710; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1724; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __pyx_t_7 = (__pyx_t_13 > 0);
               if (__pyx_t_7) {
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1711
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1725
  *                                                     e_sent_len, e_sent_start)
  *                                 if len(phrase_list) > 0:
  *                                     pair_count = 1.0 / len(phrase_list)             # <<<<<<<<<<<<<<
  *                                 else:
  *                                     pair_count = 0
  */
-                __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1711; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1725; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 if (unlikely(__pyx_t_13 == 0)) {
                   PyErr_Format(PyExc_ZeroDivisionError, "float division");
-                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1711; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1725; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 }
                 __pyx_v_pair_count = (1.0 / __pyx_t_13);
                 goto __pyx_L74;
               }
               /*else*/ {
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1713
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1727
  *                                     pair_count = 1.0 / len(phrase_list)
  *                                 else:
  *                                     pair_count = 0             # <<<<<<<<<<<<<<
@@ -55777,7 +55952,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               }
               __pyx_L74:;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1714
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1728
  *                                 else:
  *                                     pair_count = 0
  *                                 for phrase2,eindexes in phrase_list:             # <<<<<<<<<<<<<<
@@ -55788,7 +55963,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __pyx_t_15 = __pyx_v_phrase_list; __Pyx_INCREF(__pyx_t_15); __pyx_t_13 = 0;
                 __pyx_t_16 = NULL;
               } else {
-                __pyx_t_13 = -1; __pyx_t_15 = PyObject_GetIter(__pyx_v_phrase_list); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1714; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_13 = -1; __pyx_t_15 = PyObject_GetIter(__pyx_v_phrase_list); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1728; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_15);
                 __pyx_t_16 = Py_TYPE(__pyx_t_15)->tp_iternext;
               }
@@ -55796,23 +55971,23 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 if (!__pyx_t_16 && PyList_CheckExact(__pyx_t_15)) {
                   if (__pyx_t_13 >= PyList_GET_SIZE(__pyx_t_15)) break;
                   #if CYTHON_COMPILING_IN_CPYTHON
-                  __pyx_t_1 = PyList_GET_ITEM(__pyx_t_15, __pyx_t_13); __Pyx_INCREF(__pyx_t_1); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1714; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_1 = PyList_GET_ITEM(__pyx_t_15, __pyx_t_13); __Pyx_INCREF(__pyx_t_1); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1728; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #else
-                  __pyx_t_1 = PySequence_ITEM(__pyx_t_15, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1714; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_1 = PySequence_ITEM(__pyx_t_15, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1728; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #endif
                 } else if (!__pyx_t_16 && PyTuple_CheckExact(__pyx_t_15)) {
                   if (__pyx_t_13 >= PyTuple_GET_SIZE(__pyx_t_15)) break;
                   #if CYTHON_COMPILING_IN_CPYTHON
-                  __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_15, __pyx_t_13); __Pyx_INCREF(__pyx_t_1); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1714; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_15, __pyx_t_13); __Pyx_INCREF(__pyx_t_1); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1728; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #else
-                  __pyx_t_1 = PySequence_ITEM(__pyx_t_15, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1714; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_1 = PySequence_ITEM(__pyx_t_15, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1728; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #endif
                 } else {
                   __pyx_t_1 = __pyx_t_16(__pyx_t_15);
                   if (unlikely(!__pyx_t_1)) {
                     if (PyErr_Occurred()) {
                       if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-                      else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1714; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                      else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1728; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                     }
                     break;
                   }
@@ -55828,7 +56003,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                   if (unlikely(size != 2)) {
                     if (size > 2) __Pyx_RaiseTooManyValuesError(2);
                     else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-                    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1714; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1728; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   }
                   #if CYTHON_COMPILING_IN_CPYTHON
                   if (likely(PyTuple_CheckExact(sequence))) {
@@ -55841,14 +56016,14 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                   __Pyx_INCREF(__pyx_t_14);
                   __Pyx_INCREF(__pyx_t_2);
                   #else
-                  __pyx_t_14 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1714; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-                  __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1714; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_14 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1728; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1728; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #endif
                   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
                 } else
                 {
                   Py_ssize_t index = -1;
-                  __pyx_t_10 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1714; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_10 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1728; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __Pyx_GOTREF(__pyx_t_10);
                   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
                   __pyx_t_17 = Py_TYPE(__pyx_t_10)->tp_iternext;
@@ -55856,7 +56031,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                   __Pyx_GOTREF(__pyx_t_14);
                   index = 1; __pyx_t_2 = __pyx_t_17(__pyx_t_10); if (unlikely(!__pyx_t_2)) goto __pyx_L77_unpacking_failed;
                   __Pyx_GOTREF(__pyx_t_2);
-                  if (__Pyx_IternextUnpackEndCheck(__pyx_t_17(__pyx_t_10), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1714; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  if (__Pyx_IternextUnpackEndCheck(__pyx_t_17(__pyx_t_10), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1728; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __pyx_t_17 = NULL;
                   __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
                   goto __pyx_L78_unpacking_done;
@@ -55864,7 +56039,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                   __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
                   __pyx_t_17 = NULL;
                   if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1714; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1728; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __pyx_L78_unpacking_done:;
                 }
                 __Pyx_XDECREF(__pyx_v_phrase2);
@@ -55874,7 +56049,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __pyx_v_eindexes = __pyx_t_2;
                 __pyx_t_2 = 0;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1715
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1729
  *                                     pair_count = 0
  *                                 for phrase2,eindexes in phrase_list:
  *                                     als2 = self.create_alignments(sent_links,num_links,self.findexes,eindexes)             # <<<<<<<<<<<<<<
@@ -55883,31 +56058,31 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
                 __pyx_t_1 = ((PyObject *)__pyx_v_self->findexes);
                 __Pyx_INCREF(__pyx_t_1);
-                __pyx_t_2 = ((PyObject *)((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->create_alignments(__pyx_v_self, __pyx_v_sent_links, __pyx_v_num_links, __pyx_t_1, __pyx_v_eindexes)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1715; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_2 = ((PyObject *)((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->create_alignments(__pyx_v_self, __pyx_v_sent_links, __pyx_v_num_links, __pyx_t_1, __pyx_v_eindexes)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1729; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_2);
                 __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
                 __Pyx_XDECREF(((PyObject *)__pyx_v_als2));
                 __pyx_v_als2 = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_2);
                 __pyx_t_2 = 0;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1716
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1730
  *                                 for phrase2,eindexes in phrase_list:
  *                                     als2 = self.create_alignments(sent_links,num_links,self.findexes,eindexes)
  *                                     extracts.append((fphr, phrase2, pair_count, tuple(als2)))             # <<<<<<<<<<<<<<
  * 
  *                         if (f_back_high == f_high and
  */
-                __pyx_t_2 = PyFloat_FromDouble(__pyx_v_pair_count); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1716; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_2 = PyFloat_FromDouble(__pyx_v_pair_count); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1730; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_2);
-                __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1716; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1730; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_1);
                 __Pyx_INCREF(((PyObject *)__pyx_v_als2));
                 PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_v_als2));
                 __Pyx_GIVEREF(((PyObject *)__pyx_v_als2));
-                __pyx_t_14 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1716; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_14 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1730; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_14);
                 __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-                __pyx_t_1 = PyTuple_New(4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1716; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_1 = PyTuple_New(4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1730; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_1);
                 __Pyx_INCREF(((PyObject *)__pyx_v_fphr));
                 PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_v_fphr));
@@ -55921,7 +56096,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __Pyx_GIVEREF(__pyx_t_14);
                 __pyx_t_2 = 0;
                 __pyx_t_14 = 0;
-                __pyx_t_14 = __Pyx_PyObject_Append(__pyx_v_extracts, ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1716; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_14 = __Pyx_PyObject_Append(__pyx_v_extracts, ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1730; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_14);
                 __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
                 __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
@@ -55934,7 +56109,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           }
           __pyx_L64:;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1718
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1732
  *                                     extracts.append((fphr, phrase2, pair_count, tuple(als2)))
  * 
  *                         if (f_back_high == f_high and             # <<<<<<<<<<<<<<
@@ -55944,7 +56119,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           __pyx_t_7 = (__pyx_v_f_back_high == __pyx_v_f_high);
           if (__pyx_t_7) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1719
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1733
  * 
  *                         if (f_back_high == f_high and
  *                             f_sent_len - f_high >= self.train_min_gap_size and             # <<<<<<<<<<<<<<
@@ -55954,7 +56129,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             __pyx_t_9 = ((__pyx_v_f_sent_len - __pyx_v_f_high) >= __pyx_v_self->train_min_gap_size);
             if (__pyx_t_9) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1720
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1734
  *                         if (f_back_high == f_high and
  *                             f_sent_len - f_high >= self.train_min_gap_size and
  *                             ((not self.tight_phrases) or (f_links_low[f_high] != -1 and f_links_low[f_back_low] != -1))):             # <<<<<<<<<<<<<<
@@ -55984,7 +56159,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           }
           if (__pyx_t_9) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1721
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1735
  *                             f_sent_len - f_high >= self.train_min_gap_size and
  *                             ((not self.tight_phrases) or (f_links_low[f_high] != -1 and f_links_low[f_back_low] != -1))):
  *                             f_x_high = f_high+self.train_min_gap_size             # <<<<<<<<<<<<<<
@@ -55993,7 +56168,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             __pyx_v_f_x_high = (__pyx_v_f_high + __pyx_v_self->train_min_gap_size);
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1722
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1736
  *                             ((not self.tight_phrases) or (f_links_low[f_high] != -1 and f_links_low[f_back_low] != -1))):
  *                             f_x_high = f_high+self.train_min_gap_size
  *                             met_constraints = 1             # <<<<<<<<<<<<<<
@@ -56002,7 +56177,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             __pyx_v_met_constraints = 1;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1723
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1737
  *                             f_x_high = f_high+self.train_min_gap_size
  *                             met_constraints = 1
  *                             if self.tight_phrases:             # <<<<<<<<<<<<<<
@@ -56011,7 +56186,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             if (__pyx_v_self->tight_phrases) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1724
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1738
  *                             met_constraints = 1
  *                             if self.tight_phrases:
  *                                 while f_x_high <= f_sent_len and f_links_low[f_x_high-1] == -1:             # <<<<<<<<<<<<<<
@@ -56028,7 +56203,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 }
                 if (!__pyx_t_18) break;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1725
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1739
  *                             if self.tight_phrases:
  *                                 while f_x_high <= f_sent_len and f_links_low[f_x_high-1] == -1:
  *                                     f_x_high = f_x_high + 1             # <<<<<<<<<<<<<<
@@ -56041,7 +56216,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             }
             __pyx_L80:;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1726
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1740
  *                                 while f_x_high <= f_sent_len and f_links_low[f_x_high-1] == -1:
  *                                     f_x_high = f_x_high + 1
  *                             if f_x_high > f_sent_len or f_x_high - f_back_low > self.train_max_initial_size:             # <<<<<<<<<<<<<<
@@ -56057,7 +56232,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             }
             if (__pyx_t_7) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1727
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1741
  *                                     f_x_high = f_x_high + 1
  *                             if f_x_high > f_sent_len or f_x_high - f_back_low > self.train_max_initial_size:
  *                                 met_constraints = 0             # <<<<<<<<<<<<<<
@@ -56069,7 +56244,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             }
             __pyx_L83:;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1729
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1743
  *                                 met_constraints = 0
  * 
  *                             if (met_constraints and             # <<<<<<<<<<<<<<
@@ -56078,17 +56253,17 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             if (__pyx_v_met_constraints) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1730
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1744
  * 
  *                             if (met_constraints and
  *                                 self.find_fixpoint(f_back_low, f_x_high,             # <<<<<<<<<<<<<<
  *                                             f_links_low, f_links_high, e_links_low, e_links_high,
  *                                             e_low, e_high, &e_x_low, &e_x_high, &f_x_low, &f_x_high,
  */
-              __pyx_t_15 = PyInt_FromLong(__pyx_v_f_x_high); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1730; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = PyInt_FromLong(__pyx_v_f_x_high); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1744; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_15);
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1734
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1748
  *                                             e_low, e_high, &e_x_low, &e_x_high, &f_x_low, &f_x_high,
  *                                             f_sent_len, e_sent_len,
  *                                             self.train_max_initial_size, self.train_max_initial_size,             # <<<<<<<<<<<<<<
@@ -56098,7 +56273,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               if (((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->find_fixpoint(__pyx_v_self, __pyx_v_f_back_low, __pyx_t_15, __pyx_v_f_links_low, __pyx_v_f_links_high, __pyx_v_e_links_low, __pyx_v_e_links_high, __pyx_v_e_low, __pyx_v_e_high, (&__pyx_v_e_x_low), (&__pyx_v_e_x_high), (&__pyx_v_f_x_low), (&__pyx_v_f_x_high), __pyx_v_f_sent_len, __pyx_v_e_sent_len, __pyx_v_self->train_max_initial_size, __pyx_v_self->train_max_initial_size, 1, 1, 1, 0, 1, 1, 0)) {
                 __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1736
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1750
  *                                             self.train_max_initial_size, self.train_max_initial_size,
  *                                             1, 1, 1, 0, 1, 1, 0) and
  *                                 ((not self.tight_phrases) or f_links_low[f_x_high-1] != -1) and             # <<<<<<<<<<<<<<
@@ -56114,17 +56289,17 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 }
                 if (__pyx_t_9) {
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1737
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1751
  *                                             1, 1, 1, 0, 1, 1, 0) and
  *                                 ((not self.tight_phrases) or f_links_low[f_x_high-1] != -1) and
  *                                 self.find_fixpoint(f_high, f_x_high,             # <<<<<<<<<<<<<<
  *                                             f_links_low, f_links_high, e_links_low, e_links_high,
  *                                             -1, -1, e_gap_low+gap_start+num_gaps, e_gap_high+gap_start+num_gaps,
  */
-                  __pyx_t_14 = PyInt_FromLong(__pyx_v_f_x_high); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1737; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_14 = PyInt_FromLong(__pyx_v_f_x_high); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1751; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __Pyx_GOTREF(__pyx_t_14);
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1742
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1756
  *                                             f_gap_low+gap_start+num_gaps, f_gap_high+gap_start+num_gaps,
  *                                             f_sent_len, e_sent_len,
  *                                             self.train_max_initial_size, self.train_max_initial_size,             # <<<<<<<<<<<<<<
@@ -56147,7 +56322,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             }
             if (__pyx_t_7) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1744
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1758
  *                                             self.train_max_initial_size, self.train_max_initial_size,
  *                                             0, 0, 0, 0, 0, 0, 0)):
  *                                 fphr_arr._clear()             # <<<<<<<<<<<<<<
@@ -56156,7 +56331,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
               ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_fphr_arr->__pyx_vtab)->_clear(__pyx_v_fphr_arr);
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1745
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1759
  *                                             0, 0, 0, 0, 0, 0, 0)):
  *                                 fphr_arr._clear()
  *                                 i = 1             # <<<<<<<<<<<<<<
@@ -56165,21 +56340,21 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
               __pyx_v_i = 1;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1746
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1760
  *                                 fphr_arr._clear()
  *                                 i = 1
  *                                 self.findexes.reset()             # <<<<<<<<<<<<<<
  *                                 if f_back_low < f_low:
  *                                     fphr_arr._append(sym_setindex(self.category, i))
  */
-              __pyx_t_15 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__reset); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1746; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__reset); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1760; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_15);
-              __pyx_t_14 = PyObject_Call(__pyx_t_15, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1746; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_14 = PyObject_Call(__pyx_t_15, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1760; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_14);
               __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
               __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1747
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1761
  *                                 i = 1
  *                                 self.findexes.reset()
  *                                 if f_back_low < f_low:             # <<<<<<<<<<<<<<
@@ -56189,7 +56364,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               __pyx_t_7 = (__pyx_v_f_back_low < __pyx_v_f_low);
               if (__pyx_t_7) {
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1748
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1762
  *                                 self.findexes.reset()
  *                                 if f_back_low < f_low:
  *                                     fphr_arr._append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
@@ -56198,7 +56373,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
                 ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_fphr_arr->__pyx_vtab)->_append(__pyx_v_fphr_arr, __pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i));
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1749
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1763
  *                                 if f_back_low < f_low:
  *                                     fphr_arr._append(sym_setindex(self.category, i))
  *                                     i = i+1             # <<<<<<<<<<<<<<
@@ -56207,16 +56382,16 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
                 __pyx_v_i = (__pyx_v_i + 1);
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1750
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1764
  *                                     fphr_arr._append(sym_setindex(self.category, i))
  *                                     i = i+1
  *                                     self.findexes.append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
  *                                 self.findexes.extend(self.findexes1)
  *                                 for j from 0 <= j < phrase.n:
  */
-                __pyx_t_14 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1750; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_14 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1764; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_14);
-                __pyx_t_15 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_14); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1750; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_14); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1764; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_15);
                 __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
                 __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
@@ -56224,27 +56399,27 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               }
               __pyx_L85:;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1751
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1765
  *                                     i = i+1
  *                                     self.findexes.append(sym_setindex(self.category, i))
  *                                 self.findexes.extend(self.findexes1)             # <<<<<<<<<<<<<<
  *                                 for j from 0 <= j < phrase.n:
  *                                     if sym_isvar(phrase.syms[j]):
  */
-              __pyx_t_15 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__extend); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1751; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__extend); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1765; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_15);
-              __pyx_t_14 = PyTuple_New(1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1751; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_14 = PyTuple_New(1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1765; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_14);
               __Pyx_INCREF(((PyObject *)__pyx_v_self->findexes1));
               PyTuple_SET_ITEM(__pyx_t_14, 0, ((PyObject *)__pyx_v_self->findexes1));
               __Pyx_GIVEREF(((PyObject *)__pyx_v_self->findexes1));
-              __pyx_t_1 = PyObject_Call(__pyx_t_15, ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1751; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_1 = PyObject_Call(__pyx_t_15, ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1765; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_1);
               __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
               __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
               __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1752
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1766
  *                                     self.findexes.append(sym_setindex(self.category, i))
  *                                 self.findexes.extend(self.findexes1)
  *                                 for j from 0 <= j < phrase.n:             # <<<<<<<<<<<<<<
@@ -56254,7 +56429,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               __pyx_t_3 = __pyx_v_phrase->n;
               for (__pyx_v_j = 0; __pyx_v_j < __pyx_t_3; __pyx_v_j++) {
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1753
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1767
  *                                 self.findexes.extend(self.findexes1)
  *                                 for j from 0 <= j < phrase.n:
  *                                     if sym_isvar(phrase.syms[j]):             # <<<<<<<<<<<<<<
@@ -56264,7 +56439,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __pyx_t_4 = __pyx_f_3_sa_sym_isvar((__pyx_v_phrase->syms[__pyx_v_j]));
                 if (__pyx_t_4) {
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1754
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1768
  *                                 for j from 0 <= j < phrase.n:
  *                                     if sym_isvar(phrase.syms[j]):
  *                                         fphr_arr._append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
@@ -56273,7 +56448,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
                   ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_fphr_arr->__pyx_vtab)->_append(__pyx_v_fphr_arr, __pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i));
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1755
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1769
  *                                     if sym_isvar(phrase.syms[j]):
  *                                         fphr_arr._append(sym_setindex(self.category, i))
  *                                         i = i + 1             # <<<<<<<<<<<<<<
@@ -56285,7 +56460,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 }
                 /*else*/ {
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1757
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1771
  *                                         i = i + 1
  *                                     else:
  *                                         fphr_arr._append(phrase.syms[j])             # <<<<<<<<<<<<<<
@@ -56297,7 +56472,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __pyx_L88:;
               }
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1758
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1772
  *                                     else:
  *                                         fphr_arr._append(phrase.syms[j])
  *                                 fphr_arr._append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
@@ -56306,81 +56481,81 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
               ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_fphr_arr->__pyx_vtab)->_append(__pyx_v_fphr_arr, __pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i));
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1759
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1773
  *                                         fphr_arr._append(phrase.syms[j])
  *                                 fphr_arr._append(sym_setindex(self.category, i))
  *                                 self.findexes.append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
  *                                 fphr = Phrase(fphr_arr)
  *                                 phrase_list = self.extract_phrases(e_x_low, e_x_high, e_gap_low+gap_start, e_gap_high+gap_start, e_links_low, num_gaps+1,
  */
-              __pyx_t_1 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1759; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_1 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1773; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_1);
-              __pyx_t_14 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1759; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_14 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1773; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_14);
               __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
               __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1760
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1774
  *                                 fphr_arr._append(sym_setindex(self.category, i))
  *                                 self.findexes.append(sym_setindex(self.category, i))
  *                                 fphr = Phrase(fphr_arr)             # <<<<<<<<<<<<<<
  *                                 phrase_list = self.extract_phrases(e_x_low, e_x_high, e_gap_low+gap_start, e_gap_high+gap_start, e_links_low, num_gaps+1,
  *                                                     f_x_low, f_x_high, f_gap_low+gap_start, f_gap_high+gap_start, f_links_low,
  */
-              __pyx_t_14 = PyTuple_New(1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1760; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_14 = PyTuple_New(1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1774; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_14);
               __Pyx_INCREF(((PyObject *)__pyx_v_fphr_arr));
               PyTuple_SET_ITEM(__pyx_t_14, 0, ((PyObject *)__pyx_v_fphr_arr));
               __Pyx_GIVEREF(((PyObject *)__pyx_v_fphr_arr));
-              __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1760; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1774; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_1);
               __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
               __Pyx_DECREF(((PyObject *)__pyx_v_fphr));
               __pyx_v_fphr = ((struct __pyx_obj_3_sa_Phrase *)__pyx_t_1);
               __pyx_t_1 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1763
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1777
  *                                 phrase_list = self.extract_phrases(e_x_low, e_x_high, e_gap_low+gap_start, e_gap_high+gap_start, e_links_low, num_gaps+1,
  *                                                     f_x_low, f_x_high, f_gap_low+gap_start, f_gap_high+gap_start, f_links_low,
  *                                                     matching.sent_id, e_sent_len, e_sent_start)             # <<<<<<<<<<<<<<
  *                                 if len(phrase_list) > 0:
  *                                     pair_count = 1.0 / len(phrase_list)
  */
-              __pyx_t_1 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->extract_phrases(__pyx_v_self, __pyx_v_e_x_low, __pyx_v_e_x_high, (__pyx_v_e_gap_low + __pyx_v_gap_start), (__pyx_v_e_gap_high + __pyx_v_gap_start), __pyx_v_e_links_low, (__pyx_v_num_gaps + 1), __pyx_v_f_x_low, __pyx_v_f_x_high, (__pyx_v_f_gap_low + __pyx_v_gap_start), (__pyx_v_f_gap_high + __pyx_v_gap_start), __pyx_v_f_links_low, __pyx_v_matching->sent_id, __pyx_v_e_sent_len, __pyx_v_e_sent_start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1761; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_1 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->extract_phrases(__pyx_v_self, __pyx_v_e_x_low, __pyx_v_e_x_high, (__pyx_v_e_gap_low + __pyx_v_gap_start), (__pyx_v_e_gap_high + __pyx_v_gap_start), __pyx_v_e_links_low, (__pyx_v_num_gaps + 1), __pyx_v_f_x_low, __pyx_v_f_x_high, (__pyx_v_f_gap_low + __pyx_v_gap_start), (__pyx_v_f_gap_high + __pyx_v_gap_start), __pyx_v_f_links_low, __pyx_v_matching->sent_id, __pyx_v_e_sent_len, __pyx_v_e_sent_start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1775; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_1);
               __Pyx_XDECREF(__pyx_v_phrase_list);
               __pyx_v_phrase_list = __pyx_t_1;
               __pyx_t_1 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1764
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1778
  *                                                     f_x_low, f_x_high, f_gap_low+gap_start, f_gap_high+gap_start, f_links_low,
  *                                                     matching.sent_id, e_sent_len, e_sent_start)
  *                                 if len(phrase_list) > 0:             # <<<<<<<<<<<<<<
  *                                     pair_count = 1.0 / len(phrase_list)
  *                                 else:
  */
-              __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1764; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1778; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __pyx_t_7 = (__pyx_t_13 > 0);
               if (__pyx_t_7) {
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1765
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1779
  *                                                     matching.sent_id, e_sent_len, e_sent_start)
  *                                 if len(phrase_list) > 0:
  *                                     pair_count = 1.0 / len(phrase_list)             # <<<<<<<<<<<<<<
  *                                 else:
  *                                     pair_count = 0
  */
-                __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1765; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1779; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 if (unlikely(__pyx_t_13 == 0)) {
                   PyErr_Format(PyExc_ZeroDivisionError, "float division");
-                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1765; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1779; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 }
                 __pyx_v_pair_count = (1.0 / __pyx_t_13);
                 goto __pyx_L89;
               }
               /*else*/ {
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1767
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1781
  *                                     pair_count = 1.0 / len(phrase_list)
  *                                 else:
  *                                     pair_count = 0             # <<<<<<<<<<<<<<
@@ -56391,7 +56566,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               }
               __pyx_L89:;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1768
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1782
  *                                 else:
  *                                     pair_count = 0
  *                                 for phrase2, eindexes in phrase_list:             # <<<<<<<<<<<<<<
@@ -56402,7 +56577,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __pyx_t_1 = __pyx_v_phrase_list; __Pyx_INCREF(__pyx_t_1); __pyx_t_13 = 0;
                 __pyx_t_16 = NULL;
               } else {
-                __pyx_t_13 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_phrase_list); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1768; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_13 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_phrase_list); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1782; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_1);
                 __pyx_t_16 = Py_TYPE(__pyx_t_1)->tp_iternext;
               }
@@ -56410,23 +56585,23 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 if (!__pyx_t_16 && PyList_CheckExact(__pyx_t_1)) {
                   if (__pyx_t_13 >= PyList_GET_SIZE(__pyx_t_1)) break;
                   #if CYTHON_COMPILING_IN_CPYTHON
-                  __pyx_t_14 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_13); __Pyx_INCREF(__pyx_t_14); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1768; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_14 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_13); __Pyx_INCREF(__pyx_t_14); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1782; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #else
-                  __pyx_t_14 = PySequence_ITEM(__pyx_t_1, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1768; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_14 = PySequence_ITEM(__pyx_t_1, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1782; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #endif
                 } else if (!__pyx_t_16 && PyTuple_CheckExact(__pyx_t_1)) {
                   if (__pyx_t_13 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
                   #if CYTHON_COMPILING_IN_CPYTHON
-                  __pyx_t_14 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_13); __Pyx_INCREF(__pyx_t_14); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1768; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_14 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_13); __Pyx_INCREF(__pyx_t_14); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1782; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #else
-                  __pyx_t_14 = PySequence_ITEM(__pyx_t_1, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1768; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_14 = PySequence_ITEM(__pyx_t_1, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1782; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #endif
                 } else {
                   __pyx_t_14 = __pyx_t_16(__pyx_t_1);
                   if (unlikely(!__pyx_t_14)) {
                     if (PyErr_Occurred()) {
                       if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-                      else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1768; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                      else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1782; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                     }
                     break;
                   }
@@ -56442,7 +56617,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                   if (unlikely(size != 2)) {
                     if (size > 2) __Pyx_RaiseTooManyValuesError(2);
                     else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-                    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1768; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1782; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   }
                   #if CYTHON_COMPILING_IN_CPYTHON
                   if (likely(PyTuple_CheckExact(sequence))) {
@@ -56455,14 +56630,14 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                   __Pyx_INCREF(__pyx_t_15);
                   __Pyx_INCREF(__pyx_t_2);
                   #else
-                  __pyx_t_15 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1768; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-                  __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1768; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_15 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1782; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1782; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #endif
                   __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
                 } else
                 {
                   Py_ssize_t index = -1;
-                  __pyx_t_10 = PyObject_GetIter(__pyx_t_14); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1768; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_10 = PyObject_GetIter(__pyx_t_14); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1782; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __Pyx_GOTREF(__pyx_t_10);
                   __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
                   __pyx_t_17 = Py_TYPE(__pyx_t_10)->tp_iternext;
@@ -56470,7 +56645,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                   __Pyx_GOTREF(__pyx_t_15);
                   index = 1; __pyx_t_2 = __pyx_t_17(__pyx_t_10); if (unlikely(!__pyx_t_2)) goto __pyx_L92_unpacking_failed;
                   __Pyx_GOTREF(__pyx_t_2);
-                  if (__Pyx_IternextUnpackEndCheck(__pyx_t_17(__pyx_t_10), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1768; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  if (__Pyx_IternextUnpackEndCheck(__pyx_t_17(__pyx_t_10), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1782; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __pyx_t_17 = NULL;
                   __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
                   goto __pyx_L93_unpacking_done;
@@ -56478,7 +56653,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                   __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
                   __pyx_t_17 = NULL;
                   if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1768; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1782; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __pyx_L93_unpacking_done:;
                 }
                 __Pyx_XDECREF(__pyx_v_phrase2);
@@ -56488,7 +56663,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __pyx_v_eindexes = __pyx_t_2;
                 __pyx_t_2 = 0;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1769
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1783
  *                                     pair_count = 0
  *                                 for phrase2, eindexes in phrase_list:
  *                                     als3 = self.create_alignments(sent_links,num_links,self.findexes,eindexes)             # <<<<<<<<<<<<<<
@@ -56497,31 +56672,31 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
                 __pyx_t_14 = ((PyObject *)__pyx_v_self->findexes);
                 __Pyx_INCREF(__pyx_t_14);
-                __pyx_t_2 = ((PyObject *)((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->create_alignments(__pyx_v_self, __pyx_v_sent_links, __pyx_v_num_links, __pyx_t_14, __pyx_v_eindexes)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1769; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_2 = ((PyObject *)((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->create_alignments(__pyx_v_self, __pyx_v_sent_links, __pyx_v_num_links, __pyx_t_14, __pyx_v_eindexes)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1783; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_2);
                 __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
                 __Pyx_XDECREF(((PyObject *)__pyx_v_als3));
                 __pyx_v_als3 = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_2);
                 __pyx_t_2 = 0;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1770
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1784
  *                                 for phrase2, eindexes in phrase_list:
  *                                     als3 = self.create_alignments(sent_links,num_links,self.findexes,eindexes)
  *                                     extracts.append((fphr, phrase2, pair_count, tuple(als3)))             # <<<<<<<<<<<<<<
  *                         if (num_gaps < self.max_nonterminals - 1 and
  *                             phrase_len+1 < self.max_length and
  */
-                __pyx_t_2 = PyFloat_FromDouble(__pyx_v_pair_count); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1770; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_2 = PyFloat_FromDouble(__pyx_v_pair_count); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1784; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_2);
-                __pyx_t_14 = PyTuple_New(1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1770; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_14 = PyTuple_New(1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1784; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_14);
                 __Pyx_INCREF(((PyObject *)__pyx_v_als3));
                 PyTuple_SET_ITEM(__pyx_t_14, 0, ((PyObject *)__pyx_v_als3));
                 __Pyx_GIVEREF(((PyObject *)__pyx_v_als3));
-                __pyx_t_15 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1770; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1784; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_15);
                 __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
-                __pyx_t_14 = PyTuple_New(4); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1770; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_14 = PyTuple_New(4); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1784; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_14);
                 __Pyx_INCREF(((PyObject *)__pyx_v_fphr));
                 PyTuple_SET_ITEM(__pyx_t_14, 0, ((PyObject *)__pyx_v_fphr));
@@ -56535,7 +56710,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __Pyx_GIVEREF(__pyx_t_15);
                 __pyx_t_2 = 0;
                 __pyx_t_15 = 0;
-                __pyx_t_15 = __Pyx_PyObject_Append(__pyx_v_extracts, ((PyObject *)__pyx_t_14)); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1770; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = __Pyx_PyObject_Append(__pyx_v_extracts, ((PyObject *)__pyx_t_14)); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1784; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_15);
                 __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
                 __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
@@ -56548,7 +56723,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           }
           __pyx_L79:;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1771
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1785
  *                                     als3 = self.create_alignments(sent_links,num_links,self.findexes,eindexes)
  *                                     extracts.append((fphr, phrase2, pair_count, tuple(als3)))
  *                         if (num_gaps < self.max_nonterminals - 1 and             # <<<<<<<<<<<<<<
@@ -56558,7 +56733,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           __pyx_t_7 = (__pyx_v_num_gaps < (__pyx_v_self->max_nonterminals - 1));
           if (__pyx_t_7) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1772
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1786
  *                                     extracts.append((fphr, phrase2, pair_count, tuple(als3)))
  *                         if (num_gaps < self.max_nonterminals - 1 and
  *                             phrase_len+1 < self.max_length and             # <<<<<<<<<<<<<<
@@ -56568,7 +56743,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             __pyx_t_9 = ((__pyx_v_phrase_len + 1) < __pyx_v_self->max_length);
             if (__pyx_t_9) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1773
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1787
  *                         if (num_gaps < self.max_nonterminals - 1 and
  *                             phrase_len+1 < self.max_length and
  *                             f_back_high == f_high and             # <<<<<<<<<<<<<<
@@ -56578,7 +56753,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               __pyx_t_18 = (__pyx_v_f_back_high == __pyx_v_f_high);
               if (__pyx_t_18) {
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1774
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1788
  *                             phrase_len+1 < self.max_length and
  *                             f_back_high == f_high and
  *                             f_back_low == f_low and             # <<<<<<<<<<<<<<
@@ -56588,7 +56763,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __pyx_t_8 = (__pyx_v_f_back_low == __pyx_v_f_low);
                 if (__pyx_t_8) {
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1775
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1789
  *                             f_back_high == f_high and
  *                             f_back_low == f_low and
  *                             f_back_high - f_back_low + (2*self.train_min_gap_size) <= self.train_max_initial_size and             # <<<<<<<<<<<<<<
@@ -56598,7 +56773,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                   __pyx_t_19 = (((__pyx_v_f_back_high - __pyx_v_f_back_low) + (2 * __pyx_v_self->train_min_gap_size)) <= __pyx_v_self->train_max_initial_size);
                   if (__pyx_t_19) {
 
-                    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1776
+                    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1790
  *                             f_back_low == f_low and
  *                             f_back_high - f_back_low + (2*self.train_min_gap_size) <= self.train_max_initial_size and
  *                             f_low >= self.train_min_gap_size and             # <<<<<<<<<<<<<<
@@ -56608,7 +56783,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                     __pyx_t_20 = (__pyx_v_f_low >= __pyx_v_self->train_min_gap_size);
                     if (__pyx_t_20) {
 
-                      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1777
+                      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1791
  *                             f_back_high - f_back_low + (2*self.train_min_gap_size) <= self.train_max_initial_size and
  *                             f_low >= self.train_min_gap_size and
  *                             f_high <= f_sent_len - self.train_min_gap_size and             # <<<<<<<<<<<<<<
@@ -56618,7 +56793,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                       __pyx_t_21 = (__pyx_v_f_high <= (__pyx_v_f_sent_len - __pyx_v_self->train_min_gap_size));
                       if (__pyx_t_21) {
 
-                        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1778
+                        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1792
  *                             f_low >= self.train_min_gap_size and
  *                             f_high <= f_sent_len - self.train_min_gap_size and
  *                             ((not self.tight_phrases) or (f_links_low[f_low-1] != -1 and f_links_low[f_high] != -1))):             # <<<<<<<<<<<<<<
@@ -56668,7 +56843,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           }
           if (__pyx_t_9) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1780
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1794
  *                             ((not self.tight_phrases) or (f_links_low[f_low-1] != -1 and f_links_low[f_high] != -1))):
  * 
  *                             met_constraints = 1             # <<<<<<<<<<<<<<
@@ -56677,7 +56852,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             __pyx_v_met_constraints = 1;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1781
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1795
  * 
  *                             met_constraints = 1
  *                             f_x_low = f_low-self.train_min_gap_size             # <<<<<<<<<<<<<<
@@ -56686,7 +56861,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             __pyx_v_f_x_low = (__pyx_v_f_low - __pyx_v_self->train_min_gap_size);
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1782
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1796
  *                             met_constraints = 1
  *                             f_x_low = f_low-self.train_min_gap_size
  *                             if self.tight_phrases:             # <<<<<<<<<<<<<<
@@ -56695,7 +56870,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             if (__pyx_v_self->tight_phrases) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1783
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1797
  *                             f_x_low = f_low-self.train_min_gap_size
  *                             if self.tight_phrases:
  *                                 while f_x_low >= 0 and f_links_low[f_x_low] == -1:             # <<<<<<<<<<<<<<
@@ -56712,7 +56887,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 }
                 if (!__pyx_t_18) break;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1784
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1798
  *                             if self.tight_phrases:
  *                                 while f_x_low >= 0 and f_links_low[f_x_low] == -1:
  *                                     f_x_low = f_x_low - 1             # <<<<<<<<<<<<<<
@@ -56725,7 +56900,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             }
             __pyx_L95:;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1785
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1799
  *                                 while f_x_low >= 0 and f_links_low[f_x_low] == -1:
  *                                     f_x_low = f_x_low - 1
  *                             if f_x_low < 0:             # <<<<<<<<<<<<<<
@@ -56735,7 +56910,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             __pyx_t_18 = (__pyx_v_f_x_low < 0);
             if (__pyx_t_18) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1786
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1800
  *                                     f_x_low = f_x_low - 1
  *                             if f_x_low < 0:
  *                                 met_constraints = 0             # <<<<<<<<<<<<<<
@@ -56747,7 +56922,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             }
             __pyx_L98:;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1788
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1802
  *                                 met_constraints = 0
  * 
  *                             f_x_high = f_high+self.train_min_gap_size             # <<<<<<<<<<<<<<
@@ -56756,7 +56931,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             __pyx_v_f_x_high = (__pyx_v_f_high + __pyx_v_self->train_min_gap_size);
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1789
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1803
  * 
  *                             f_x_high = f_high+self.train_min_gap_size
  *                             if self.tight_phrases:             # <<<<<<<<<<<<<<
@@ -56765,7 +56940,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             if (__pyx_v_self->tight_phrases) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1790
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1804
  *                             f_x_high = f_high+self.train_min_gap_size
  *                             if self.tight_phrases:
  *                                 while f_x_high <= f_sent_len and f_links_low[f_x_high-1] == -1:             # <<<<<<<<<<<<<<
@@ -56782,7 +56957,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 }
                 if (!__pyx_t_7) break;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1791
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1805
  *                             if self.tight_phrases:
  *                                 while f_x_high <= f_sent_len and f_links_low[f_x_high-1] == -1:
  *                                     f_x_high = f_x_high + 1             # <<<<<<<<<<<<<<
@@ -56795,7 +56970,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             }
             __pyx_L99:;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1792
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1806
  *                                 while f_x_high <= f_sent_len and f_links_low[f_x_high-1] == -1:
  *                                     f_x_high = f_x_high + 1
  *                             if f_x_high > f_sent_len or f_x_high - f_x_low > self.train_max_initial_size:             # <<<<<<<<<<<<<<
@@ -56811,7 +56986,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             }
             if (__pyx_t_9) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1793
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1807
  *                                     f_x_high = f_x_high + 1
  *                             if f_x_high > f_sent_len or f_x_high - f_x_low > self.train_max_initial_size:
  *                                 met_constraints = 0             # <<<<<<<<<<<<<<
@@ -56823,7 +56998,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             }
             __pyx_L102:;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1795
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1809
  *                                 met_constraints = 0
  * 
  *                             if (met_constraints and             # <<<<<<<<<<<<<<
@@ -56832,17 +57007,17 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             if (__pyx_v_met_constraints) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1796
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1810
  * 
  *                             if (met_constraints and
  *                                 self.find_fixpoint(f_x_low, f_x_high,             # <<<<<<<<<<<<<<
  *                                                 f_links_low, f_links_high, e_links_low, e_links_high,
  *                                                 e_low, e_high, &e_x_low, &e_x_high, &f_x_low, &f_x_high,
  */
-              __pyx_t_1 = PyInt_FromLong(__pyx_v_f_x_high); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_1 = PyInt_FromLong(__pyx_v_f_x_high); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1810; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_1);
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1800
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1814
  *                                                 e_low, e_high, &e_x_low, &e_x_high, &f_x_low, &f_x_high,
  *                                                 f_sent_len, e_sent_len,
  *                                                 self.train_max_initial_size, self.train_max_initial_size,             # <<<<<<<<<<<<<<
@@ -56852,7 +57027,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               if (((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->find_fixpoint(__pyx_v_self, __pyx_v_f_x_low, __pyx_t_1, __pyx_v_f_links_low, __pyx_v_f_links_high, __pyx_v_e_links_low, __pyx_v_e_links_high, __pyx_v_e_low, __pyx_v_e_high, (&__pyx_v_e_x_low), (&__pyx_v_e_x_high), (&__pyx_v_f_x_low), (&__pyx_v_f_x_high), __pyx_v_f_sent_len, __pyx_v_e_sent_len, __pyx_v_self->train_max_initial_size, __pyx_v_self->train_max_initial_size, 1, 1, 2, 1, 1, 1, 1)) {
                 __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1802
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1816
  *                                                 self.train_max_initial_size, self.train_max_initial_size,
  *                                                 1, 1, 2, 1, 1, 1, 1) and
  *                                 ((not self.tight_phrases) or (f_links_low[f_x_low] != -1 and f_links_low[f_x_high-1] != -1)) and             # <<<<<<<<<<<<<<
@@ -56874,17 +57049,17 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 }
                 if (__pyx_t_7) {
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1803
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1817
  *                                                 1, 1, 2, 1, 1, 1, 1) and
  *                                 ((not self.tight_phrases) or (f_links_low[f_x_low] != -1 and f_links_low[f_x_high-1] != -1)) and
  *                                 self.find_fixpoint(f_x_low, f_low,             # <<<<<<<<<<<<<<
  *                                                 f_links_low, f_links_high, e_links_low, e_links_high,
  *                                                 -1, -1, e_gap_low, e_gap_high, f_gap_low, f_gap_high,
  */
-                  __pyx_t_15 = PyInt_FromLong(__pyx_v_f_low); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_15 = PyInt_FromLong(__pyx_v_f_low); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1817; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __Pyx_GOTREF(__pyx_t_15);
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1807
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1821
  *                                                 -1, -1, e_gap_low, e_gap_high, f_gap_low, f_gap_high,
  *                                                 f_sent_len, e_sent_len,
  *                                                 self.train_max_initial_size, self.train_max_initial_size,             # <<<<<<<<<<<<<<
@@ -56895,17 +57070,17 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                   __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
                   if (__pyx_t_3) {
 
-                    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1809
+                    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1823
  *                                                 self.train_max_initial_size, self.train_max_initial_size,
  *                                                 0, 0, 0, 0, 0, 0, 0) and
  *                                 self.find_fixpoint(f_high, f_x_high,             # <<<<<<<<<<<<<<
  *                                                 f_links_low, f_links_high, e_links_low, e_links_high,
  *                                                 -1, -1, e_gap_low+1+num_gaps, e_gap_high+1+num_gaps,
  */
-                    __pyx_t_15 = PyInt_FromLong(__pyx_v_f_x_high); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1809; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                    __pyx_t_15 = PyInt_FromLong(__pyx_v_f_x_high); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                     __Pyx_GOTREF(__pyx_t_15);
 
-                    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1814
+                    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1828
  *                                                 f_gap_low+1+num_gaps, f_gap_high+1+num_gaps,
  *                                                 f_sent_len, e_sent_len,
  *                                                 self.train_max_initial_size, self.train_max_initial_size,             # <<<<<<<<<<<<<<
@@ -56933,7 +57108,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             }
             if (__pyx_t_8) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1816
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1830
  *                                                 self.train_max_initial_size, self.train_max_initial_size,
  *                                                 0, 0, 0, 0, 0, 0, 0)):
  *                                 fphr_arr._clear()             # <<<<<<<<<<<<<<
@@ -56942,7 +57117,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
               ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_fphr_arr->__pyx_vtab)->_clear(__pyx_v_fphr_arr);
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1817
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1831
  *                                                 0, 0, 0, 0, 0, 0, 0)):
  *                                 fphr_arr._clear()
  *                                 i = 1             # <<<<<<<<<<<<<<
@@ -56951,35 +57126,35 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
               __pyx_v_i = 1;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1818
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1832
  *                                 fphr_arr._clear()
  *                                 i = 1
  *                                 self.findexes.reset()             # <<<<<<<<<<<<<<
  *                                 self.findexes.append(sym_setindex(self.category, i))
  *                                 fphr_arr._append(sym_setindex(self.category, i))
  */
-              __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__reset); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1818; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__reset); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_1);
-              __pyx_t_15 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1818; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_15);
               __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
               __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1819
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1833
  *                                 i = 1
  *                                 self.findexes.reset()
  *                                 self.findexes.append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
  *                                 fphr_arr._append(sym_setindex(self.category, i))
  *                                 i = i+1
  */
-              __pyx_t_15 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1819; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_15);
-              __pyx_t_1 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_15); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1819; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_1 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_15); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_1);
               __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
               __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1820
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1834
  *                                 self.findexes.reset()
  *                                 self.findexes.append(sym_setindex(self.category, i))
  *                                 fphr_arr._append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
@@ -56988,7 +57163,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
               ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_fphr_arr->__pyx_vtab)->_append(__pyx_v_fphr_arr, __pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i));
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1821
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1835
  *                                 self.findexes.append(sym_setindex(self.category, i))
  *                                 fphr_arr._append(sym_setindex(self.category, i))
  *                                 i = i+1             # <<<<<<<<<<<<<<
@@ -56997,27 +57172,27 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
               __pyx_v_i = (__pyx_v_i + 1);
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1822
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1836
  *                                 fphr_arr._append(sym_setindex(self.category, i))
  *                                 i = i+1
  *                                 self.findexes.extend(self.findexes1)             # <<<<<<<<<<<<<<
  *                                 for j from 0 <= j < phrase.n:
  *                                     if sym_isvar(phrase.syms[j]):
  */
-              __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__extend); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1822; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__extend); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_1);
-              __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1822; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_15);
               __Pyx_INCREF(((PyObject *)__pyx_v_self->findexes1));
               PyTuple_SET_ITEM(__pyx_t_15, 0, ((PyObject *)__pyx_v_self->findexes1));
               __Pyx_GIVEREF(((PyObject *)__pyx_v_self->findexes1));
-              __pyx_t_14 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1822; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_14 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_14);
               __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
               __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
               __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1823
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1837
  *                                 i = i+1
  *                                 self.findexes.extend(self.findexes1)
  *                                 for j from 0 <= j < phrase.n:             # <<<<<<<<<<<<<<
@@ -57027,7 +57202,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               __pyx_t_3 = __pyx_v_phrase->n;
               for (__pyx_v_j = 0; __pyx_v_j < __pyx_t_3; __pyx_v_j++) {
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1824
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1838
  *                                 self.findexes.extend(self.findexes1)
  *                                 for j from 0 <= j < phrase.n:
  *                                     if sym_isvar(phrase.syms[j]):             # <<<<<<<<<<<<<<
@@ -57037,7 +57212,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __pyx_t_4 = __pyx_f_3_sa_sym_isvar((__pyx_v_phrase->syms[__pyx_v_j]));
                 if (__pyx_t_4) {
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1825
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1839
  *                                 for j from 0 <= j < phrase.n:
  *                                     if sym_isvar(phrase.syms[j]):
  *                                         fphr_arr._append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
@@ -57046,7 +57221,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
                   ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_fphr_arr->__pyx_vtab)->_append(__pyx_v_fphr_arr, __pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i));
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1826
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1840
  *                                     if sym_isvar(phrase.syms[j]):
  *                                         fphr_arr._append(sym_setindex(self.category, i))
  *                                         i = i + 1             # <<<<<<<<<<<<<<
@@ -57058,7 +57233,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 }
                 /*else*/ {
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1828
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1842
  *                                         i = i + 1
  *                                     else:
  *                                         fphr_arr._append(phrase.syms[j])             # <<<<<<<<<<<<<<
@@ -57070,7 +57245,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __pyx_L106:;
               }
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1829
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1843
  *                                     else:
  *                                         fphr_arr._append(phrase.syms[j])
  *                                 fphr_arr._append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
@@ -57079,81 +57254,81 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
               ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_fphr_arr->__pyx_vtab)->_append(__pyx_v_fphr_arr, __pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i));
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1830
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1844
  *                                         fphr_arr._append(phrase.syms[j])
  *                                 fphr_arr._append(sym_setindex(self.category, i))
  *                                 self.findexes.append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
  *                                 fphr = Phrase(fphr_arr)
  *                                 phrase_list = self.extract_phrases(e_x_low, e_x_high, e_gap_low, e_gap_high, e_links_low, num_gaps+2,
  */
-              __pyx_t_14 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_14 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_14);
-              __pyx_t_15 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_14); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_14); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_15);
               __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
               __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1831
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1845
  *                                 fphr_arr._append(sym_setindex(self.category, i))
  *                                 self.findexes.append(sym_setindex(self.category, i))
  *                                 fphr = Phrase(fphr_arr)             # <<<<<<<<<<<<<<
  *                                 phrase_list = self.extract_phrases(e_x_low, e_x_high, e_gap_low, e_gap_high, e_links_low, num_gaps+2,
  *                                                     f_x_low, f_x_high, f_gap_low, f_gap_high, f_links_low,
  */
-              __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1845; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_15);
               __Pyx_INCREF(((PyObject *)__pyx_v_fphr_arr));
               PyTuple_SET_ITEM(__pyx_t_15, 0, ((PyObject *)__pyx_v_fphr_arr));
               __Pyx_GIVEREF(((PyObject *)__pyx_v_fphr_arr));
-              __pyx_t_14 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_14 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1845; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_14);
               __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
               __Pyx_DECREF(((PyObject *)__pyx_v_fphr));
               __pyx_v_fphr = ((struct __pyx_obj_3_sa_Phrase *)__pyx_t_14);
               __pyx_t_14 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1834
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1848
  *                                 phrase_list = self.extract_phrases(e_x_low, e_x_high, e_gap_low, e_gap_high, e_links_low, num_gaps+2,
  *                                                     f_x_low, f_x_high, f_gap_low, f_gap_high, f_links_low,
  *                                                     matching.sent_id, e_sent_len, e_sent_start)             # <<<<<<<<<<<<<<
  *                                 if len(phrase_list) > 0:
  *                                     pair_count = 1.0 / len(phrase_list)
  */
-              __pyx_t_14 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->extract_phrases(__pyx_v_self, __pyx_v_e_x_low, __pyx_v_e_x_high, __pyx_v_e_gap_low, __pyx_v_e_gap_high, __pyx_v_e_links_low, (__pyx_v_num_gaps + 2), __pyx_v_f_x_low, __pyx_v_f_x_high, __pyx_v_f_gap_low, __pyx_v_f_gap_high, __pyx_v_f_links_low, __pyx_v_matching->sent_id, __pyx_v_e_sent_len, __pyx_v_e_sent_start); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_14 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->extract_phrases(__pyx_v_self, __pyx_v_e_x_low, __pyx_v_e_x_high, __pyx_v_e_gap_low, __pyx_v_e_gap_high, __pyx_v_e_links_low, (__pyx_v_num_gaps + 2), __pyx_v_f_x_low, __pyx_v_f_x_high, __pyx_v_f_gap_low, __pyx_v_f_gap_high, __pyx_v_f_links_low, __pyx_v_matching->sent_id, __pyx_v_e_sent_len, __pyx_v_e_sent_start); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1846; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_14);
               __Pyx_XDECREF(__pyx_v_phrase_list);
               __pyx_v_phrase_list = __pyx_t_14;
               __pyx_t_14 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1835
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1849
  *                                                     f_x_low, f_x_high, f_gap_low, f_gap_high, f_links_low,
  *                                                     matching.sent_id, e_sent_len, e_sent_start)
  *                                 if len(phrase_list) > 0:             # <<<<<<<<<<<<<<
  *                                     pair_count = 1.0 / len(phrase_list)
  *                                 else:
  */
-              __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1849; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __pyx_t_8 = (__pyx_t_13 > 0);
               if (__pyx_t_8) {
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1836
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1850
  *                                                     matching.sent_id, e_sent_len, e_sent_start)
  *                                 if len(phrase_list) > 0:
  *                                     pair_count = 1.0 / len(phrase_list)             # <<<<<<<<<<<<<<
  *                                 else:
  *                                     pair_count = 0
  */
-                __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1850; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 if (unlikely(__pyx_t_13 == 0)) {
                   PyErr_Format(PyExc_ZeroDivisionError, "float division");
-                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1850; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 }
                 __pyx_v_pair_count = (1.0 / __pyx_t_13);
                 goto __pyx_L107;
               }
               /*else*/ {
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1838
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1852
  *                                     pair_count = 1.0 / len(phrase_list)
  *                                 else:
  *                                     pair_count = 0             # <<<<<<<<<<<<<<
@@ -57164,7 +57339,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               }
               __pyx_L107:;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1839
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1853
  *                                 else:
  *                                     pair_count = 0
  *                                 for phrase2, eindexes in phrase_list:             # <<<<<<<<<<<<<<
@@ -57175,7 +57350,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __pyx_t_14 = __pyx_v_phrase_list; __Pyx_INCREF(__pyx_t_14); __pyx_t_13 = 0;
                 __pyx_t_16 = NULL;
               } else {
-                __pyx_t_13 = -1; __pyx_t_14 = PyObject_GetIter(__pyx_v_phrase_list); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_13 = -1; __pyx_t_14 = PyObject_GetIter(__pyx_v_phrase_list); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_14);
                 __pyx_t_16 = Py_TYPE(__pyx_t_14)->tp_iternext;
               }
@@ -57183,23 +57358,23 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 if (!__pyx_t_16 && PyList_CheckExact(__pyx_t_14)) {
                   if (__pyx_t_13 >= PyList_GET_SIZE(__pyx_t_14)) break;
                   #if CYTHON_COMPILING_IN_CPYTHON
-                  __pyx_t_15 = PyList_GET_ITEM(__pyx_t_14, __pyx_t_13); __Pyx_INCREF(__pyx_t_15); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_15 = PyList_GET_ITEM(__pyx_t_14, __pyx_t_13); __Pyx_INCREF(__pyx_t_15); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #else
-                  __pyx_t_15 = PySequence_ITEM(__pyx_t_14, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_15 = PySequence_ITEM(__pyx_t_14, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #endif
                 } else if (!__pyx_t_16 && PyTuple_CheckExact(__pyx_t_14)) {
                   if (__pyx_t_13 >= PyTuple_GET_SIZE(__pyx_t_14)) break;
                   #if CYTHON_COMPILING_IN_CPYTHON
-                  __pyx_t_15 = PyTuple_GET_ITEM(__pyx_t_14, __pyx_t_13); __Pyx_INCREF(__pyx_t_15); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_15 = PyTuple_GET_ITEM(__pyx_t_14, __pyx_t_13); __Pyx_INCREF(__pyx_t_15); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #else
-                  __pyx_t_15 = PySequence_ITEM(__pyx_t_14, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_15 = PySequence_ITEM(__pyx_t_14, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #endif
                 } else {
                   __pyx_t_15 = __pyx_t_16(__pyx_t_14);
                   if (unlikely(!__pyx_t_15)) {
                     if (PyErr_Occurred()) {
                       if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-                      else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                      else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                     }
                     break;
                   }
@@ -57215,7 +57390,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                   if (unlikely(size != 2)) {
                     if (size > 2) __Pyx_RaiseTooManyValuesError(2);
                     else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-                    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   }
                   #if CYTHON_COMPILING_IN_CPYTHON
                   if (likely(PyTuple_CheckExact(sequence))) {
@@ -57228,14 +57403,14 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                   __Pyx_INCREF(__pyx_t_1);
                   __Pyx_INCREF(__pyx_t_2);
                   #else
-                  __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-                  __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #endif
                   __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
                 } else
                 {
                   Py_ssize_t index = -1;
-                  __pyx_t_10 = PyObject_GetIter(__pyx_t_15); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_10 = PyObject_GetIter(__pyx_t_15); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __Pyx_GOTREF(__pyx_t_10);
                   __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
                   __pyx_t_17 = Py_TYPE(__pyx_t_10)->tp_iternext;
@@ -57243,7 +57418,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                   __Pyx_GOTREF(__pyx_t_1);
                   index = 1; __pyx_t_2 = __pyx_t_17(__pyx_t_10); if (unlikely(!__pyx_t_2)) goto __pyx_L110_unpacking_failed;
                   __Pyx_GOTREF(__pyx_t_2);
-                  if (__Pyx_IternextUnpackEndCheck(__pyx_t_17(__pyx_t_10), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  if (__Pyx_IternextUnpackEndCheck(__pyx_t_17(__pyx_t_10), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __pyx_t_17 = NULL;
                   __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
                   goto __pyx_L111_unpacking_done;
@@ -57251,7 +57426,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                   __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
                   __pyx_t_17 = NULL;
                   if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __pyx_L111_unpacking_done:;
                 }
                 __Pyx_XDECREF(__pyx_v_phrase2);
@@ -57261,7 +57436,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __pyx_v_eindexes = __pyx_t_2;
                 __pyx_t_2 = 0;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1840
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1854
  *                                     pair_count = 0
  *                                 for phrase2, eindexes in phrase_list:
  *                                     als4 = self.create_alignments(sent_links,num_links,self.findexes,eindexes)             # <<<<<<<<<<<<<<
@@ -57270,31 +57445,31 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
                 __pyx_t_15 = ((PyObject *)__pyx_v_self->findexes);
                 __Pyx_INCREF(__pyx_t_15);
-                __pyx_t_2 = ((PyObject *)((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->create_alignments(__pyx_v_self, __pyx_v_sent_links, __pyx_v_num_links, __pyx_t_15, __pyx_v_eindexes)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_2 = ((PyObject *)((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->create_alignments(__pyx_v_self, __pyx_v_sent_links, __pyx_v_num_links, __pyx_t_15, __pyx_v_eindexes)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1854; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_2);
                 __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
                 __Pyx_XDECREF(((PyObject *)__pyx_v_als4));
                 __pyx_v_als4 = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_2);
                 __pyx_t_2 = 0;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1841
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1855
  *                                 for phrase2, eindexes in phrase_list:
  *                                     als4 = self.create_alignments(sent_links,num_links,self.findexes,eindexes)
  *                                     extracts.append((fphr, phrase2, pair_count, tuple(als4)))             # <<<<<<<<<<<<<<
  *             else:
  *                 reason_for_failure = "Unable to extract basic phrase"
  */
-                __pyx_t_2 = PyFloat_FromDouble(__pyx_v_pair_count); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_2 = PyFloat_FromDouble(__pyx_v_pair_count); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_2);
-                __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_15);
                 __Pyx_INCREF(((PyObject *)__pyx_v_als4));
                 PyTuple_SET_ITEM(__pyx_t_15, 0, ((PyObject *)__pyx_v_als4));
                 __Pyx_GIVEREF(((PyObject *)__pyx_v_als4));
-                __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_1);
                 __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
-                __pyx_t_15 = PyTuple_New(4); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PyTuple_New(4); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_15);
                 __Pyx_INCREF(((PyObject *)__pyx_v_fphr));
                 PyTuple_SET_ITEM(__pyx_t_15, 0, ((PyObject *)__pyx_v_fphr));
@@ -57308,7 +57483,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __Pyx_GIVEREF(__pyx_t_1);
                 __pyx_t_2 = 0;
                 __pyx_t_1 = 0;
-                __pyx_t_1 = __Pyx_PyObject_Append(__pyx_v_extracts, ((PyObject *)__pyx_t_15)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_1 = __Pyx_PyObject_Append(__pyx_v_extracts, ((PyObject *)__pyx_t_15)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_1);
                 __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
                 __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -57330,7 +57505,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     }
     /*else*/ {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1843
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1857
  *                                     extracts.append((fphr, phrase2, pair_count, tuple(als4)))
  *             else:
  *                 reason_for_failure = "Unable to extract basic phrase"             # <<<<<<<<<<<<<<
@@ -57346,7 +57521,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
   }
   __pyx_L33:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1845
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1859
  *                 reason_for_failure = "Unable to extract basic phrase"
  * 
  *         free(sent_links)             # <<<<<<<<<<<<<<
@@ -57355,7 +57530,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   free(__pyx_v_sent_links);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1846
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1860
  * 
  *         free(sent_links)
  *         free(f_links_low)             # <<<<<<<<<<<<<<
@@ -57364,7 +57539,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   free(__pyx_v_f_links_low);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1847
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1861
  *         free(sent_links)
  *         free(f_links_low)
  *         free(f_links_high)             # <<<<<<<<<<<<<<
@@ -57373,7 +57548,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   free(__pyx_v_f_links_high);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1848
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1862
  *         free(f_links_low)
  *         free(f_links_high)
  *         free(e_links_low)             # <<<<<<<<<<<<<<
@@ -57382,7 +57557,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   free(__pyx_v_e_links_low);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1849
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1863
  *         free(f_links_high)
  *         free(e_links_low)
  *         free(e_links_high)             # <<<<<<<<<<<<<<
@@ -57391,7 +57566,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   free(__pyx_v_e_links_high);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1850
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1864
  *         free(e_links_low)
  *         free(e_links_high)
  *         free(f_gap_low)             # <<<<<<<<<<<<<<
@@ -57400,7 +57575,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   free(__pyx_v_f_gap_low);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1851
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1865
  *         free(e_links_high)
  *         free(f_gap_low)
  *         free(f_gap_high)             # <<<<<<<<<<<<<<
@@ -57409,7 +57584,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   free(__pyx_v_f_gap_high);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1852
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1866
  *         free(f_gap_low)
  *         free(f_gap_high)
  *         free(e_gap_low)             # <<<<<<<<<<<<<<
@@ -57418,7 +57593,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   free(__pyx_v_e_gap_low);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1853
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1867
  *         free(f_gap_high)
  *         free(e_gap_low)
  *         free(e_gap_high)             # <<<<<<<<<<<<<<
@@ -57427,7 +57602,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   free(__pyx_v_e_gap_high);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1855
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1869
  *         free(e_gap_high)
  * 
  *         return extracts             # <<<<<<<<<<<<<<
@@ -57499,16 +57674,16 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_26add_instance(PyObject
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__e_words)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("add_instance", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1863; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("add_instance", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1877; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__alignment)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("add_instance", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1863; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("add_instance", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1877; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add_instance") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1863; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add_instance") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1877; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
       goto __pyx_L5_argtuple_error;
@@ -57523,7 +57698,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_26add_instance(PyObject
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("add_instance", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1863; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("add_instance", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1877; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.add_instance", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -57577,46 +57752,46 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_12add_instance_1extract
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__f_j)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__e_i)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  3:
         if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__e_j)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 3); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 3); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  4:
         if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__min_bound)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 4); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 4); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  5:
         if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__wc)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 5); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 5); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  6:
         if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__links)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 6); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 6); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  7:
         if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__nt)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 7); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 7); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  8:
         if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__nt_open)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 8); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 8); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "extract") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "extract") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
       goto __pyx_L5_argtuple_error;
@@ -57643,7 +57818,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_12add_instance_1extract
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.add_instance.extract", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -57654,7 +57829,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_12add_instance_1extract
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1897
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1911
  *         # f_ i and j are current, e_ i and j are previous
  *         # We care _considering_ f_j, so it is not yet in counts
  *         def extract(f_i, f_j, e_i, e_j, min_bound, wc, links, nt, nt_open):             # <<<<<<<<<<<<<<
@@ -57700,33 +57875,33 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   __pyx_outer_scope = (struct __pyx_obj_3_sa___pyx_scope_struct_21_add_instance *) __Pyx_CyFunction_GetClosure(__pyx_self);
   __pyx_cur_scope = __pyx_outer_scope;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1899
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1913
  *         def extract(f_i, f_j, e_i, e_j, min_bound, wc, links, nt, nt_open):
  *             # Phrase extraction limits
  *             if f_j > (f_len - 1) or (f_j - f_i) + 1 > self.max_initial_size:             # <<<<<<<<<<<<<<
  *                 return
  *             # Unaligned word
  */
-  if (unlikely(!__pyx_cur_scope->__pyx_v_f_len)) { __Pyx_RaiseClosureNameError("f_len"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1899; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-  __pyx_t_1 = PyNumber_Subtract(__pyx_cur_scope->__pyx_v_f_len, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__pyx_cur_scope->__pyx_v_f_len)) { __Pyx_RaiseClosureNameError("f_len"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+  __pyx_t_1 = PyNumber_Subtract(__pyx_cur_scope->__pyx_v_f_len, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_RichCompare(__pyx_v_f_j, __pyx_t_1, Py_GT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_RichCompare(__pyx_v_f_j, __pyx_t_1, Py_GT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   if (!__pyx_t_3) {
-    __pyx_t_2 = PyNumber_Subtract(__pyx_v_f_j, __pyx_v_f_i); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyNumber_Subtract(__pyx_v_f_j, __pyx_v_f_i); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    if (unlikely(!__pyx_cur_scope->__pyx_v_self)) { __Pyx_RaiseClosureNameError("self"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1899; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-    __pyx_t_2 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_initial_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_cur_scope->__pyx_v_self)) { __Pyx_RaiseClosureNameError("self"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+    __pyx_t_2 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_initial_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_4 = PyObject_RichCompare(__pyx_t_1, __pyx_t_2, Py_GT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_RichCompare(__pyx_t_1, __pyx_t_2, Py_GT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __pyx_t_6 = __pyx_t_5;
   } else {
@@ -57734,7 +57909,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   }
   if (__pyx_t_6) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1900
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1914
  *             # Phrase extraction limits
  *             if f_j > (f_len - 1) or (f_j - f_i) + 1 > self.max_initial_size:
  *                 return             # <<<<<<<<<<<<<<
@@ -57748,41 +57923,41 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1902
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1916
  *                 return
  *             # Unaligned word
  *             if not al[f_j]:             # <<<<<<<<<<<<<<
  *                 # Adjacent to non-terminal: extend (non-terminal now open)
  *                 if nt and nt[-1][2] == f_j - 1:
  */
-  if (unlikely(!__pyx_cur_scope->__pyx_v_al)) { __Pyx_RaiseClosureNameError("al"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1902; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-  __pyx_t_4 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_al, __pyx_v_f_j); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1902; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__pyx_cur_scope->__pyx_v_al)) { __Pyx_RaiseClosureNameError("al"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1916; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+  __pyx_t_4 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_al, __pyx_v_f_j); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1916; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1902; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1916; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_3 = (!__pyx_t_6);
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1904
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1918
  *             if not al[f_j]:
  *                 # Adjacent to non-terminal: extend (non-terminal now open)
  *                 if nt and nt[-1][2] == f_j - 1:             # <<<<<<<<<<<<<<
  *                     nt[-1][2] += 1
  *                     extract(f_i, f_j + 1, e_i, e_j, min_bound, wc, links, nt, True)
  */
-    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_nt); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_nt); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     if (__pyx_t_3) {
-      __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_4, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_4, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_4 = PyNumber_Subtract(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyNumber_Subtract(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       __pyx_t_5 = __pyx_t_6;
     } else {
@@ -57790,38 +57965,38 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     }
     if (__pyx_t_5) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1905
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1919
  *                 # Adjacent to non-terminal: extend (non-terminal now open)
  *                 if nt and nt[-1][2] == f_j - 1:
  *                     nt[-1][2] += 1             # <<<<<<<<<<<<<<
  *                     extract(f_i, f_j + 1, e_i, e_j, min_bound, wc, links, nt, True)
  *                     nt[-1][2] -= 1
  */
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1919; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __pyx_t_7 = 2;
-      __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_1, __pyx_t_7, sizeof(Py_ssize_t), PyInt_FromSsize_t); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_1, __pyx_t_7, sizeof(Py_ssize_t), PyInt_FromSsize_t); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1919; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1919; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      if (__Pyx_SetItemInt(__pyx_t_1, __pyx_t_7, __pyx_t_2, sizeof(Py_ssize_t), PyInt_FromSsize_t) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (__Pyx_SetItemInt(__pyx_t_1, __pyx_t_7, __pyx_t_2, sizeof(Py_ssize_t), PyInt_FromSsize_t) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1919; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1906
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1920
  *                 if nt and nt[-1][2] == f_j - 1:
  *                     nt[-1][2] += 1
  *                     extract(f_i, f_j + 1, e_i, e_j, min_bound, wc, links, nt, True)             # <<<<<<<<<<<<<<
  *                     nt[-1][2] -= 1
  *                 # Unless non-terminal already open, always extend with word
  */
-      if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1906; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_1 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1920; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_1 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1920; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_2 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1920; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_4 = PyTuple_New(9); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyTuple_New(9); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1920; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_INCREF(__pyx_v_f_i);
       PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_f_i);
@@ -57850,48 +58025,48 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       __Pyx_GIVEREF(__pyx_t_2);
       __pyx_t_1 = 0;
       __pyx_t_2 = 0;
-      __pyx_t_2 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1920; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1907
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1921
  *                     nt[-1][2] += 1
  *                     extract(f_i, f_j + 1, e_i, e_j, min_bound, wc, links, nt, True)
  *                     nt[-1][2] -= 1             # <<<<<<<<<<<<<<
  *                 # Unless non-terminal already open, always extend with word
  *                 # Make sure adding a word doesn't exceed length
  */
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1907; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __pyx_t_7 = 2;
-      __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_2, __pyx_t_7, sizeof(Py_ssize_t), PyInt_FromSsize_t); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1907; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_2, __pyx_t_7, sizeof(Py_ssize_t), PyInt_FromSsize_t); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_1 = PyNumber_InPlaceSubtract(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1907; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyNumber_InPlaceSubtract(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      if (__Pyx_SetItemInt(__pyx_t_2, __pyx_t_7, __pyx_t_1, sizeof(Py_ssize_t), PyInt_FromSsize_t) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1907; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (__Pyx_SetItemInt(__pyx_t_2, __pyx_t_7, __pyx_t_1, sizeof(Py_ssize_t), PyInt_FromSsize_t) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       goto __pyx_L5;
     }
     __pyx_L5:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1910
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1924
  *                 # Unless non-terminal already open, always extend with word
  *                 # Make sure adding a word doesn't exceed length
  *                 if not nt_open and wc < self.max_length:             # <<<<<<<<<<<<<<
  *                     extract(f_i, f_j + 1, e_i, e_j, min_bound, wc + 1, links, nt, False)
  *                 return
  */
-    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_nt_open); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_nt_open); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __pyx_t_3 = (!__pyx_t_5);
     if (__pyx_t_3) {
-      __pyx_t_2 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_length); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_length); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_1 = PyObject_RichCompare(__pyx_v_wc, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_RichCompare(__pyx_v_wc, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       __pyx_t_6 = __pyx_t_5;
     } else {
@@ -57899,21 +58074,21 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     }
     if (__pyx_t_6) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1911
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1925
  *                 # Make sure adding a word doesn't exceed length
  *                 if not nt_open and wc < self.max_length:
  *                     extract(f_i, f_j + 1, e_i, e_j, min_bound, wc + 1, links, nt, False)             # <<<<<<<<<<<<<<
  *                 return
  *             # Aligned word
  */
-      if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_1 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1925; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_1 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_2 = PyNumber_Add(__pyx_v_wc, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_Add(__pyx_v_wc, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_4 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_8 = PyTuple_New(9); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyTuple_New(9); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_INCREF(__pyx_v_f_i);
       PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_f_i);
@@ -57942,7 +58117,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       __pyx_t_1 = 0;
       __pyx_t_2 = 0;
       __pyx_t_4 = 0;
-      __pyx_t_4 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(((PyObject *)__pyx_t_8)); __pyx_t_8 = 0;
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
@@ -57950,7 +58125,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     }
     __pyx_L6:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1912
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1926
  *                 if not nt_open and wc < self.max_length:
  *                     extract(f_i, f_j + 1, e_i, e_j, min_bound, wc + 1, links, nt, False)
  *                 return             # <<<<<<<<<<<<<<
@@ -57964,38 +58139,38 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   }
   __pyx_L4:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1914
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1928
  *                 return
  *             # Aligned word
  *             link_i = fe_span[f_j][0]             # <<<<<<<<<<<<<<
  *             link_j = fe_span[f_j][1]
  *             new_e_i = min(link_i, e_i)
  */
-  if (unlikely(!__pyx_cur_scope->__pyx_v_fe_span)) { __Pyx_RaiseClosureNameError("fe_span"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1914; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-  __pyx_t_4 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fe_span, __pyx_v_f_j); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__pyx_cur_scope->__pyx_v_fe_span)) { __Pyx_RaiseClosureNameError("fe_span"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1928; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+  __pyx_t_4 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fe_span, __pyx_v_f_j); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1928; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_8 = __Pyx_GetItemInt(__pyx_t_4, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_8 = __Pyx_GetItemInt(__pyx_t_4, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1928; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_8);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_v_link_i = __pyx_t_8;
   __pyx_t_8 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1915
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1929
  *             # Aligned word
  *             link_i = fe_span[f_j][0]
  *             link_j = fe_span[f_j][1]             # <<<<<<<<<<<<<<
  *             new_e_i = min(link_i, e_i)
  *             new_e_j = max(link_j, e_j)
  */
-  __pyx_t_8 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fe_span, __pyx_v_f_j); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1915; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_8 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fe_span, __pyx_v_f_j); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_8);
-  __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_8, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1915; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_8, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
   __pyx_v_link_j = __pyx_t_4;
   __pyx_t_4 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1916
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1930
  *             link_i = fe_span[f_j][0]
  *             link_j = fe_span[f_j][1]
  *             new_e_i = min(link_i, e_i)             # <<<<<<<<<<<<<<
@@ -58006,8 +58181,8 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   __pyx_t_4 = __pyx_v_e_i;
   __Pyx_INCREF(__pyx_v_link_i);
   __pyx_t_8 = __pyx_v_link_i;
-  __pyx_t_1 = PyObject_RichCompare(__pyx_t_4, __pyx_t_8, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1916; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1916; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_RichCompare(__pyx_t_4, __pyx_t_8, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1930; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1930; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   if (__pyx_t_6) {
     __Pyx_INCREF(__pyx_t_4);
@@ -58022,7 +58197,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   __pyx_v_new_e_i = __pyx_t_2;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1917
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1931
  *             link_j = fe_span[f_j][1]
  *             new_e_i = min(link_i, e_i)
  *             new_e_j = max(link_j, e_j)             # <<<<<<<<<<<<<<
@@ -58033,8 +58208,8 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   __pyx_t_2 = __pyx_v_e_j;
   __Pyx_INCREF(__pyx_v_link_j);
   __pyx_t_4 = __pyx_v_link_j;
-  __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_4, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1917; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1917; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_4, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   if (__pyx_t_6) {
     __Pyx_INCREF(__pyx_t_2);
@@ -58049,7 +58224,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   __pyx_v_new_e_j = __pyx_t_8;
   __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1920
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1934
  *             # Check reverse links of newly covered words to see if they violate left
  *             # bound (return) or extend minimum right bound for chunk
  *             new_min_bound = min_bound             # <<<<<<<<<<<<<<
@@ -58059,54 +58234,54 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   __Pyx_INCREF(__pyx_v_min_bound);
   __pyx_v_new_min_bound = __pyx_v_min_bound;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1922
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1936
  *             new_min_bound = min_bound
  *             # First aligned word creates span
  *             if e_j == -1:             # <<<<<<<<<<<<<<
  *                 for i from new_e_i <= i <= new_e_j:
  *                     if ef_span[i][0] < f_i:
  */
-  __pyx_t_8 = PyObject_RichCompare(__pyx_v_e_j, __pyx_int_neg_1, Py_EQ); __Pyx_XGOTREF(__pyx_t_8); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_8 = PyObject_RichCompare(__pyx_v_e_j, __pyx_int_neg_1, Py_EQ); __Pyx_XGOTREF(__pyx_t_8); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1936; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1936; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
   if (__pyx_t_6) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1923
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1937
  *             # First aligned word creates span
  *             if e_j == -1:
  *                 for i from new_e_i <= i <= new_e_j:             # <<<<<<<<<<<<<<
  *                     if ef_span[i][0] < f_i:
  *                         return
  */
-    __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_v_new_e_i); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_10 = __Pyx_PyInt_AsInt(__pyx_v_new_e_j); if (unlikely((__pyx_t_10 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_v_new_e_i); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1937; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = __Pyx_PyInt_AsInt(__pyx_v_new_e_j); if (unlikely((__pyx_t_10 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1937; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     for (__pyx_t_11 = __pyx_t_9; __pyx_t_11 <= __pyx_t_10; __pyx_t_11++) {
-      __pyx_t_8 = PyInt_FromLong(__pyx_t_11); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyInt_FromLong(__pyx_t_11); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1937; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_XDECREF(__pyx_v_i);
       __pyx_v_i = __pyx_t_8;
       __pyx_t_8 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1924
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1938
  *             if e_j == -1:
  *                 for i from new_e_i <= i <= new_e_j:
  *                     if ef_span[i][0] < f_i:             # <<<<<<<<<<<<<<
  *                         return
  *                     new_min_bound = max(new_min_bound, ef_span[i][1])
  */
-      if (unlikely(!__pyx_cur_scope->__pyx_v_ef_span)) { __Pyx_RaiseClosureNameError("ef_span"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1924; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_8 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_i); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_ef_span)) { __Pyx_RaiseClosureNameError("ef_span"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1938; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_8 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_i); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_8, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_8, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-      __pyx_t_8 = PyObject_RichCompare(__pyx_t_2, __pyx_v_f_i, Py_LT); __Pyx_XGOTREF(__pyx_t_8); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyObject_RichCompare(__pyx_t_2, __pyx_v_f_i, Py_LT); __Pyx_XGOTREF(__pyx_t_8); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       if (__pyx_t_6) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1925
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1939
  *                 for i from new_e_i <= i <= new_e_j:
  *                     if ef_span[i][0] < f_i:
  *                         return             # <<<<<<<<<<<<<<
@@ -58120,22 +58295,22 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       }
       __pyx_L10:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1926
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1940
  *                     if ef_span[i][0] < f_i:
  *                         return
  *                     new_min_bound = max(new_min_bound, ef_span[i][1])             # <<<<<<<<<<<<<<
  *             # Other aligned words extend span
  *             else:
  */
-      __pyx_t_8 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_i); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1926; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_i); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_8, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1926; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_8, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       __Pyx_INCREF(__pyx_v_new_min_bound);
       __pyx_t_8 = __pyx_v_new_min_bound;
-      __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_8, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1926; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1926; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_8, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       if (__pyx_t_6) {
         __Pyx_INCREF(__pyx_t_2);
@@ -58150,17 +58325,17 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       __Pyx_DECREF(__pyx_v_new_min_bound);
       __pyx_v_new_min_bound = __pyx_t_4;
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_11 = __Pyx_PyInt_AsInt(__pyx_v_i); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_11 = __Pyx_PyInt_AsInt(__pyx_v_i); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1937; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1923
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1937
  *             # First aligned word creates span
  *             if e_j == -1:
  *                 for i from new_e_i <= i <= new_e_j:             # <<<<<<<<<<<<<<
  *                     if ef_span[i][0] < f_i:
  *                         return
  */
-    __pyx_t_4 = PyInt_FromLong(__pyx_t_11); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyInt_FromLong(__pyx_t_11); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1937; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_XDECREF(__pyx_v_i);
     __pyx_v_i = __pyx_t_4;
@@ -58169,42 +58344,42 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1929
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1943
  *             # Other aligned words extend span
  *             else:
  *                 for i from new_e_i <= i < e_i:             # <<<<<<<<<<<<<<
  *                     if ef_span[i][0] < f_i:
  *                         return
  */
-    __pyx_t_11 = __Pyx_PyInt_AsInt(__pyx_v_new_e_i); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_10 = __Pyx_PyInt_AsInt(__pyx_v_e_i); if (unlikely((__pyx_t_10 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_11 = __Pyx_PyInt_AsInt(__pyx_v_new_e_i); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = __Pyx_PyInt_AsInt(__pyx_v_e_i); if (unlikely((__pyx_t_10 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     for (__pyx_t_9 = __pyx_t_11; __pyx_t_9 < __pyx_t_10; __pyx_t_9++) {
-      __pyx_t_4 = PyInt_FromLong(__pyx_t_9); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyInt_FromLong(__pyx_t_9); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_XDECREF(__pyx_v_i);
       __pyx_v_i = __pyx_t_4;
       __pyx_t_4 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1930
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1944
  *             else:
  *                 for i from new_e_i <= i < e_i:
  *                     if ef_span[i][0] < f_i:             # <<<<<<<<<<<<<<
  *                         return
  *                     new_min_bound = max(new_min_bound, ef_span[i][1])
  */
-      if (unlikely(!__pyx_cur_scope->__pyx_v_ef_span)) { __Pyx_RaiseClosureNameError("ef_span"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1930; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_4 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_i); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1930; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_ef_span)) { __Pyx_RaiseClosureNameError("ef_span"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1944; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_4 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_i); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_4, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1930; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_4, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_4 = PyObject_RichCompare(__pyx_t_2, __pyx_v_f_i, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1930; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_RichCompare(__pyx_t_2, __pyx_v_f_i, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1930; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       if (__pyx_t_6) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1931
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1945
  *                 for i from new_e_i <= i < e_i:
  *                     if ef_span[i][0] < f_i:
  *                         return             # <<<<<<<<<<<<<<
@@ -58218,22 +58393,22 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       }
       __pyx_L13:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1932
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1946
  *                     if ef_span[i][0] < f_i:
  *                         return
  *                     new_min_bound = max(new_min_bound, ef_span[i][1])             # <<<<<<<<<<<<<<
  *                 for i from e_j < i <= new_e_j:
  *                     if ef_span[i][0] < f_i:
  */
-      __pyx_t_4 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_i); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1932; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_i); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_4, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1932; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_4, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_INCREF(__pyx_v_new_min_bound);
       __pyx_t_4 = __pyx_v_new_min_bound;
-      __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_4, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1932; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1932; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_4, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       if (__pyx_t_6) {
         __Pyx_INCREF(__pyx_t_2);
@@ -58248,58 +58423,58 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       __Pyx_DECREF(__pyx_v_new_min_bound);
       __pyx_v_new_min_bound = __pyx_t_8;
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-      __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_v_i); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_v_i); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1929
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1943
  *             # Other aligned words extend span
  *             else:
  *                 for i from new_e_i <= i < e_i:             # <<<<<<<<<<<<<<
  *                     if ef_span[i][0] < f_i:
  *                         return
  */
-    __pyx_t_8 = PyInt_FromLong(__pyx_t_9); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyInt_FromLong(__pyx_t_9); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
     __Pyx_XDECREF(__pyx_v_i);
     __pyx_v_i = __pyx_t_8;
     __pyx_t_8 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1933
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1947
  *                         return
  *                     new_min_bound = max(new_min_bound, ef_span[i][1])
  *                 for i from e_j < i <= new_e_j:             # <<<<<<<<<<<<<<
  *                     if ef_span[i][0] < f_i:
  *                         return
  */
-    __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_v_e_j); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1933; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_10 = __Pyx_PyInt_AsInt(__pyx_v_new_e_j); if (unlikely((__pyx_t_10 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1933; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_v_e_j); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = __Pyx_PyInt_AsInt(__pyx_v_new_e_j); if (unlikely((__pyx_t_10 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     for (__pyx_t_11 = __pyx_t_9+1; __pyx_t_11 <= __pyx_t_10; __pyx_t_11++) {
-      __pyx_t_8 = PyInt_FromLong(__pyx_t_11); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1933; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyInt_FromLong(__pyx_t_11); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_XDECREF(__pyx_v_i);
       __pyx_v_i = __pyx_t_8;
       __pyx_t_8 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1934
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1948
  *                     new_min_bound = max(new_min_bound, ef_span[i][1])
  *                 for i from e_j < i <= new_e_j:
  *                     if ef_span[i][0] < f_i:             # <<<<<<<<<<<<<<
  *                         return
  *                     new_min_bound = max(new_min_bound, ef_span[i][1])
  */
-      if (unlikely(!__pyx_cur_scope->__pyx_v_ef_span)) { __Pyx_RaiseClosureNameError("ef_span"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1934; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_8 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_i); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1934; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_ef_span)) { __Pyx_RaiseClosureNameError("ef_span"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1948; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_8 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_i); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1948; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_8, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1934; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_8, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1948; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-      __pyx_t_8 = PyObject_RichCompare(__pyx_t_2, __pyx_v_f_i, Py_LT); __Pyx_XGOTREF(__pyx_t_8); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1934; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyObject_RichCompare(__pyx_t_2, __pyx_v_f_i, Py_LT); __Pyx_XGOTREF(__pyx_t_8); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1948; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1934; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1948; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       if (__pyx_t_6) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1935
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1949
  *                 for i from e_j < i <= new_e_j:
  *                     if ef_span[i][0] < f_i:
  *                         return             # <<<<<<<<<<<<<<
@@ -58313,22 +58488,22 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       }
       __pyx_L16:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1936
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1950
  *                     if ef_span[i][0] < f_i:
  *                         return
  *                     new_min_bound = max(new_min_bound, ef_span[i][1])             # <<<<<<<<<<<<<<
  *             # Extract, extend with word (unless non-terminal open)
  *             if not nt_open:
  */
-      __pyx_t_8 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_i); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1936; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_i); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1950; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_8, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1936; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_8, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1950; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       __Pyx_INCREF(__pyx_v_new_min_bound);
       __pyx_t_8 = __pyx_v_new_min_bound;
-      __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_8, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1936; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1936; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_8, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1950; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1950; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       if (__pyx_t_6) {
         __Pyx_INCREF(__pyx_t_2);
@@ -58343,17 +58518,17 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       __Pyx_DECREF(__pyx_v_new_min_bound);
       __pyx_v_new_min_bound = __pyx_t_4;
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_11 = __Pyx_PyInt_AsInt(__pyx_v_i); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1933; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_11 = __Pyx_PyInt_AsInt(__pyx_v_i); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1933
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1947
  *                         return
  *                     new_min_bound = max(new_min_bound, ef_span[i][1])
  *                 for i from e_j < i <= new_e_j:             # <<<<<<<<<<<<<<
  *                     if ef_span[i][0] < f_i:
  *                         return
  */
-    __pyx_t_4 = PyInt_FromLong(__pyx_t_11); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1933; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyInt_FromLong(__pyx_t_11); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_XDECREF(__pyx_v_i);
     __pyx_v_i = __pyx_t_4;
@@ -58361,18 +58536,18 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   }
   __pyx_L7:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1938
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1952
  *                     new_min_bound = max(new_min_bound, ef_span[i][1])
  *             # Extract, extend with word (unless non-terminal open)
  *             if not nt_open:             # <<<<<<<<<<<<<<
  *                 nt_collision = False
  *                 for link in al[f_j]:
  */
-  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_nt_open); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_nt_open); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1952; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_t_3 = (!__pyx_t_6);
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1939
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1953
  *             # Extract, extend with word (unless non-terminal open)
  *             if not nt_open:
  *                 nt_collision = False             # <<<<<<<<<<<<<<
@@ -58381,20 +58556,20 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
  */
     __pyx_v_nt_collision = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1940
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1954
  *             if not nt_open:
  *                 nt_collision = False
  *                 for link in al[f_j]:             # <<<<<<<<<<<<<<
  *                     if e_nt_cover[link]:
  *                         nt_collision = True
  */
-    __pyx_t_4 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_al, __pyx_v_f_j); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_al, __pyx_v_f_j); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1954; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     if (PyList_CheckExact(__pyx_t_4) || PyTuple_CheckExact(__pyx_t_4)) {
       __pyx_t_2 = __pyx_t_4; __Pyx_INCREF(__pyx_t_2); __pyx_t_7 = 0;
       __pyx_t_12 = NULL;
     } else {
-      __pyx_t_7 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1954; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __pyx_t_12 = Py_TYPE(__pyx_t_2)->tp_iternext;
     }
@@ -58403,23 +58578,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       if (!__pyx_t_12 && PyList_CheckExact(__pyx_t_2)) {
         if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_2)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_4 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_7); __Pyx_INCREF(__pyx_t_4); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_7); __Pyx_INCREF(__pyx_t_4); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1954; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1954; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else if (!__pyx_t_12 && PyTuple_CheckExact(__pyx_t_2)) {
         if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_7); __Pyx_INCREF(__pyx_t_4); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_7); __Pyx_INCREF(__pyx_t_4); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1954; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1954; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else {
         __pyx_t_4 = __pyx_t_12(__pyx_t_2);
         if (unlikely(!__pyx_t_4)) {
           if (PyErr_Occurred()) {
             if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1954; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           }
           break;
         }
@@ -58429,21 +58604,21 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       __pyx_v_link = __pyx_t_4;
       __pyx_t_4 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1941
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1955
  *                 nt_collision = False
  *                 for link in al[f_j]:
  *                     if e_nt_cover[link]:             # <<<<<<<<<<<<<<
  *                         nt_collision = True
  *                 # Non-terminal collisions block word extraction and extension, but
  */
-      if (unlikely(!__pyx_cur_scope->__pyx_v_e_nt_cover)) { __Pyx_RaiseClosureNameError("e_nt_cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1941; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_4 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_e_nt_cover, __pyx_v_link); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1941; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_e_nt_cover)) { __Pyx_RaiseClosureNameError("e_nt_cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1955; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_4 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_e_nt_cover, __pyx_v_link); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1955; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1941; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1955; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       if (__pyx_t_3) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1942
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1956
  *                 for link in al[f_j]:
  *                     if e_nt_cover[link]:
  *                         nt_collision = True             # <<<<<<<<<<<<<<
@@ -58457,7 +58632,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     }
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1945
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1959
  *                 # Non-terminal collisions block word extraction and extension, but
  *                 # may be okay for continuing non-terminals
  *                 if not nt_collision and wc < self.max_length:             # <<<<<<<<<<<<<<
@@ -58466,11 +58641,11 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
  */
     __pyx_t_3 = (!__pyx_v_nt_collision);
     if (__pyx_t_3) {
-      __pyx_t_2 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_length); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_length); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1959; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_4 = PyObject_RichCompare(__pyx_v_wc, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_wc, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1959; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1959; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __pyx_t_5 = __pyx_t_6;
     } else {
@@ -58478,32 +58653,32 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     }
     if (__pyx_t_5) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1946
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1960
  *                 # may be okay for continuing non-terminals
  *                 if not nt_collision and wc < self.max_length:
  *                     plus_links = []             # <<<<<<<<<<<<<<
  *                     for link in al[f_j]:
  *                         plus_links.append((f_j, link))
  */
-      __pyx_t_4 = PyList_New(0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyList_New(0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1960; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __pyx_v_plus_links = __pyx_t_4;
       __pyx_t_4 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1947
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1961
  *                 if not nt_collision and wc < self.max_length:
  *                     plus_links = []
  *                     for link in al[f_j]:             # <<<<<<<<<<<<<<
  *                         plus_links.append((f_j, link))
  *                         cover[link] += 1
  */
-      __pyx_t_4 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_al, __pyx_v_f_j); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_al, __pyx_v_f_j); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       if (PyList_CheckExact(__pyx_t_4) || PyTuple_CheckExact(__pyx_t_4)) {
         __pyx_t_2 = __pyx_t_4; __Pyx_INCREF(__pyx_t_2); __pyx_t_7 = 0;
         __pyx_t_12 = NULL;
       } else {
-        __pyx_t_7 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
         __pyx_t_12 = Py_TYPE(__pyx_t_2)->tp_iternext;
       }
@@ -58512,23 +58687,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
         if (!__pyx_t_12 && PyList_CheckExact(__pyx_t_2)) {
           if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_2)) break;
           #if CYTHON_COMPILING_IN_CPYTHON
-          __pyx_t_4 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_7); __Pyx_INCREF(__pyx_t_4); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_4 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_7); __Pyx_INCREF(__pyx_t_4); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           #else
-          __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           #endif
         } else if (!__pyx_t_12 && PyTuple_CheckExact(__pyx_t_2)) {
           if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
           #if CYTHON_COMPILING_IN_CPYTHON
-          __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_7); __Pyx_INCREF(__pyx_t_4); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_7); __Pyx_INCREF(__pyx_t_4); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           #else
-          __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           #endif
         } else {
           __pyx_t_4 = __pyx_t_12(__pyx_t_2);
           if (unlikely(!__pyx_t_4)) {
             if (PyErr_Occurred()) {
               if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-              else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             }
             break;
           }
@@ -58538,14 +58713,14 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
         __pyx_v_link = __pyx_t_4;
         __pyx_t_4 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1948
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1962
  *                     plus_links = []
  *                     for link in al[f_j]:
  *                         plus_links.append((f_j, link))             # <<<<<<<<<<<<<<
  *                         cover[link] += 1
  *                     links.append(plus_links)
  */
-        __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1948; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1962; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_INCREF(__pyx_v_f_j);
         PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_f_j);
@@ -58553,10 +58728,10 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
         __Pyx_INCREF(__pyx_v_link);
         PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_v_link);
         __Pyx_GIVEREF(__pyx_v_link);
-        __pyx_t_13 = PyList_Append(__pyx_v_plus_links, ((PyObject *)__pyx_t_4)); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1948; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_13 = PyList_Append(__pyx_v_plus_links, ((PyObject *)__pyx_t_4)); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1962; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1949
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1963
  *                     for link in al[f_j]:
  *                         plus_links.append((f_j, link))
  *                         cover[link] += 1             # <<<<<<<<<<<<<<
@@ -58565,41 +58740,41 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
  */
         __Pyx_INCREF(__pyx_v_link);
         __pyx_t_4 = __pyx_v_link;
-        if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1949; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-        __pyx_t_8 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_cover, __pyx_t_4); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1949; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1963; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+        __pyx_t_8 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_cover, __pyx_t_4); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1963; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_8);
-        __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_t_8, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1949; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_t_8, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1963; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-        if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1949; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-        if (PyObject_SetItem(__pyx_cur_scope->__pyx_v_cover, __pyx_t_4, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1949; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1963; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+        if (PyObject_SetItem(__pyx_cur_scope->__pyx_v_cover, __pyx_t_4, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1963; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       }
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1950
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1964
  *                         plus_links.append((f_j, link))
  *                         cover[link] += 1
  *                     links.append(plus_links)             # <<<<<<<<<<<<<<
  *                     if links and f_j >= new_min_bound:
  *                         rules.add(self.form_rule(f_i, new_e_i, f_words[f_i:f_j + 1], e_words[new_e_i:new_e_j + 1], nt, links))
  */
-      __pyx_t_2 = __Pyx_PyObject_Append(__pyx_v_links, ((PyObject *)__pyx_v_plus_links)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1950; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_PyObject_Append(__pyx_v_links, ((PyObject *)__pyx_v_plus_links)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1964; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1951
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1965
  *                         cover[link] += 1
  *                     links.append(plus_links)
  *                     if links and f_j >= new_min_bound:             # <<<<<<<<<<<<<<
  *                         rules.add(self.form_rule(f_i, new_e_i, f_words[f_i:f_j + 1], e_words[new_e_i:new_e_j + 1], nt, links))
  *                     extract(f_i, f_j + 1, new_e_i, new_e_j, new_min_bound, wc + 1, links, nt, False)
  */
-      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_links); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1951; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_links); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1965; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       if (__pyx_t_5) {
-        __pyx_t_2 = PyObject_RichCompare(__pyx_v_f_j, __pyx_v_new_min_bound, Py_GE); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1951; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1951; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_2 = PyObject_RichCompare(__pyx_v_f_j, __pyx_v_new_min_bound, Py_GE); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1965; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1965; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_t_6 = __pyx_t_3;
       } else {
@@ -58607,35 +58782,35 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       }
       if (__pyx_t_6) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1952
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1966
  *                     links.append(plus_links)
  *                     if links and f_j >= new_min_bound:
  *                         rules.add(self.form_rule(f_i, new_e_i, f_words[f_i:f_j + 1], e_words[new_e_i:new_e_j + 1], nt, links))             # <<<<<<<<<<<<<<
  *                     extract(f_i, f_j + 1, new_e_i, new_e_j, new_min_bound, wc + 1, links, nt, False)
  *                     links.pop()
  */
-        if (unlikely(!__pyx_cur_scope->__pyx_v_rules)) { __Pyx_RaiseClosureNameError("rules"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1952; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-        __pyx_t_2 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_rules, __pyx_n_s__add); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1952; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (unlikely(!__pyx_cur_scope->__pyx_v_rules)) { __Pyx_RaiseClosureNameError("rules"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+        __pyx_t_2 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_rules, __pyx_n_s__add); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
-        __pyx_t_4 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__form_rule); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1952; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__form_rule); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_4);
-        if (unlikely(!__pyx_cur_scope->__pyx_v_f_words)) { __Pyx_RaiseClosureNameError("f_words"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1952; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-        __pyx_t_7 = __Pyx_PyIndex_AsSsize_t(__pyx_v_f_i); if (unlikely((__pyx_t_7 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1952; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __pyx_t_1 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1952; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (unlikely(!__pyx_cur_scope->__pyx_v_f_words)) { __Pyx_RaiseClosureNameError("f_words"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+        __pyx_t_7 = __Pyx_PyIndex_AsSsize_t(__pyx_v_f_i); if (unlikely((__pyx_t_7 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
-        __pyx_t_14 = __Pyx_PyIndex_AsSsize_t(__pyx_t_1); if (unlikely((__pyx_t_14 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1952; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_14 = __Pyx_PyIndex_AsSsize_t(__pyx_t_1); if (unlikely((__pyx_t_14 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-        __pyx_t_1 = __Pyx_PySequence_GetSlice(__pyx_cur_scope->__pyx_v_f_words, __pyx_t_7, __pyx_t_14); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1952; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = __Pyx_PySequence_GetSlice(__pyx_cur_scope->__pyx_v_f_words, __pyx_t_7, __pyx_t_14); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
-        if (unlikely(!__pyx_cur_scope->__pyx_v_e_words)) { __Pyx_RaiseClosureNameError("e_words"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1952; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-        __pyx_t_14 = __Pyx_PyIndex_AsSsize_t(__pyx_v_new_e_i); if (unlikely((__pyx_t_14 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1952; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __pyx_t_8 = PyNumber_Add(__pyx_v_new_e_j, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1952; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (unlikely(!__pyx_cur_scope->__pyx_v_e_words)) { __Pyx_RaiseClosureNameError("e_words"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+        __pyx_t_14 = __Pyx_PyIndex_AsSsize_t(__pyx_v_new_e_i); if (unlikely((__pyx_t_14 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_8 = PyNumber_Add(__pyx_v_new_e_j, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_8);
-        __pyx_t_7 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_7 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1952; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_7 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-        __pyx_t_8 = __Pyx_PySequence_GetSlice(__pyx_cur_scope->__pyx_v_e_words, __pyx_t_14, __pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1952; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_8 = __Pyx_PySequence_GetSlice(__pyx_cur_scope->__pyx_v_e_words, __pyx_t_14, __pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_8);
-        __pyx_t_15 = PyTuple_New(6); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1952; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_15 = PyTuple_New(6); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_15);
         __Pyx_INCREF(__pyx_v_f_i);
         PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_v_f_i);
@@ -58655,16 +58830,16 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
         __Pyx_GIVEREF(__pyx_v_links);
         __pyx_t_1 = 0;
         __pyx_t_8 = 0;
-        __pyx_t_8 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1952; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_8 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
         __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
-        __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1952; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_15);
         PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_8);
         __pyx_t_8 = 0;
-        __pyx_t_8 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1952; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_8 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
@@ -58673,21 +58848,21 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       }
       __pyx_L24:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1953
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1967
  *                     if links and f_j >= new_min_bound:
  *                         rules.add(self.form_rule(f_i, new_e_i, f_words[f_i:f_j + 1], e_words[new_e_i:new_e_j + 1], nt, links))
  *                     extract(f_i, f_j + 1, new_e_i, new_e_j, new_min_bound, wc + 1, links, nt, False)             # <<<<<<<<<<<<<<
  *                     links.pop()
  *                     for link in al[f_j]:
  */
-      if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1953; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_8 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1967; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_8 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
-      __pyx_t_15 = PyNumber_Add(__pyx_v_wc, __pyx_int_1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = PyNumber_Add(__pyx_v_wc, __pyx_int_1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
-      __pyx_t_2 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_4 = PyTuple_New(9); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyTuple_New(9); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_INCREF(__pyx_v_f_i);
       PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_f_i);
@@ -58716,36 +58891,36 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       __pyx_t_8 = 0;
       __pyx_t_15 = 0;
       __pyx_t_2 = 0;
-      __pyx_t_2 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1954
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1968
  *                         rules.add(self.form_rule(f_i, new_e_i, f_words[f_i:f_j + 1], e_words[new_e_i:new_e_j + 1], nt, links))
  *                     extract(f_i, f_j + 1, new_e_i, new_e_j, new_min_bound, wc + 1, links, nt, False)
  *                     links.pop()             # <<<<<<<<<<<<<<
  *                     for link in al[f_j]:
  *                         cover[link] -= 1
  */
-      __pyx_t_2 = __Pyx_PyObject_Pop(__pyx_v_links); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1954; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_PyObject_Pop(__pyx_v_links); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1955
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1969
  *                     extract(f_i, f_j + 1, new_e_i, new_e_j, new_min_bound, wc + 1, links, nt, False)
  *                     links.pop()
  *                     for link in al[f_j]:             # <<<<<<<<<<<<<<
  *                         cover[link] -= 1
  *             # Try to add a word to current non-terminal (if any), extract, extend
  */
-      __pyx_t_2 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_al, __pyx_v_f_j); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1955; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_al, __pyx_v_f_j); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       if (PyList_CheckExact(__pyx_t_2) || PyTuple_CheckExact(__pyx_t_2)) {
         __pyx_t_4 = __pyx_t_2; __Pyx_INCREF(__pyx_t_4); __pyx_t_7 = 0;
         __pyx_t_12 = NULL;
       } else {
-        __pyx_t_7 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1955; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_4);
         __pyx_t_12 = Py_TYPE(__pyx_t_4)->tp_iternext;
       }
@@ -58754,23 +58929,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
         if (!__pyx_t_12 && PyList_CheckExact(__pyx_t_4)) {
           if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_4)) break;
           #if CYTHON_COMPILING_IN_CPYTHON
-          __pyx_t_2 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_7); __Pyx_INCREF(__pyx_t_2); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1955; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_2 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_7); __Pyx_INCREF(__pyx_t_2); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           #else
-          __pyx_t_2 = PySequence_ITEM(__pyx_t_4, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1955; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_2 = PySequence_ITEM(__pyx_t_4, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           #endif
         } else if (!__pyx_t_12 && PyTuple_CheckExact(__pyx_t_4)) {
           if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
           #if CYTHON_COMPILING_IN_CPYTHON
-          __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_7); __Pyx_INCREF(__pyx_t_2); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1955; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_7); __Pyx_INCREF(__pyx_t_2); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           #else
-          __pyx_t_2 = PySequence_ITEM(__pyx_t_4, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1955; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_2 = PySequence_ITEM(__pyx_t_4, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           #endif
         } else {
           __pyx_t_2 = __pyx_t_12(__pyx_t_4);
           if (unlikely(!__pyx_t_2)) {
             if (PyErr_Occurred()) {
               if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-              else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1955; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             }
             break;
           }
@@ -58780,7 +58955,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
         __pyx_v_link = __pyx_t_2;
         __pyx_t_2 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1956
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1970
  *                     links.pop()
  *                     for link in al[f_j]:
  *                         cover[link] -= 1             # <<<<<<<<<<<<<<
@@ -58789,14 +58964,14 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
  */
         __Pyx_INCREF(__pyx_v_link);
         __pyx_t_2 = __pyx_v_link;
-        if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1956; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-        __pyx_t_15 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_cover, __pyx_t_2); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1970; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+        __pyx_t_15 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_cover, __pyx_t_2); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1970; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_15);
-        __pyx_t_8 = PyNumber_InPlaceSubtract(__pyx_t_15, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_8 = PyNumber_InPlaceSubtract(__pyx_t_15, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1970; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
-        if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1956; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-        if (PyObject_SetItem(__pyx_cur_scope->__pyx_v_cover, __pyx_t_2, __pyx_t_8) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1970; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+        if (PyObject_SetItem(__pyx_cur_scope->__pyx_v_cover, __pyx_t_2, __pyx_t_8) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1970; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       }
@@ -58808,26 +58983,26 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   }
   __pyx_L17:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1958
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1972
  *                         cover[link] -= 1
  *             # Try to add a word to current non-terminal (if any), extract, extend
  *             if nt and nt[-1][2] == f_j - 1:             # <<<<<<<<<<<<<<
  *                 # Add to non-terminal, checking for collisions
  *                 old_last_nt = nt[-1][:]
  */
-  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_nt); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1958; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_nt); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   if (__pyx_t_6) {
-    __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1958; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_4, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1958; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_4, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = PyNumber_Subtract(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1958; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyNumber_Subtract(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_8 = PyObject_RichCompare(__pyx_t_2, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_8); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1958; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyObject_RichCompare(__pyx_t_2, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_8); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1958; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
     __pyx_t_3 = __pyx_t_5;
   } else {
@@ -58835,70 +59010,70 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   }
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1960
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1974
  *             if nt and nt[-1][2] == f_j - 1:
  *                 # Add to non-terminal, checking for collisions
  *                 old_last_nt = nt[-1][:]             # <<<<<<<<<<<<<<
  *                 nt[-1][2] = f_j
  *                 if link_i < nt[-1][3]:
  */
-    __pyx_t_8 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1960; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1974; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
-    __pyx_t_4 = __Pyx_PySequence_GetSlice(__pyx_t_8, 0, PY_SSIZE_T_MAX); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1960; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_PySequence_GetSlice(__pyx_t_8, 0, PY_SSIZE_T_MAX); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1974; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
     __pyx_v_old_last_nt = __pyx_t_4;
     __pyx_t_4 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1961
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1975
  *                 # Add to non-terminal, checking for collisions
  *                 old_last_nt = nt[-1][:]
  *                 nt[-1][2] = f_j             # <<<<<<<<<<<<<<
  *                 if link_i < nt[-1][3]:
  *                     if not span_check(cover, link_i, nt[-1][3] - 1):
  */
-    __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1975; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    if (__Pyx_SetItemInt(__pyx_t_4, 2, __pyx_v_f_j, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (__Pyx_SetItemInt(__pyx_t_4, 2, __pyx_v_f_j, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1975; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1962
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1976
  *                 old_last_nt = nt[-1][:]
  *                 nt[-1][2] = f_j
  *                 if link_i < nt[-1][3]:             # <<<<<<<<<<<<<<
  *                     if not span_check(cover, link_i, nt[-1][3] - 1):
  *                         nt[-1] = old_last_nt
  */
-    __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1962; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1976; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_8 = __Pyx_GetItemInt(__pyx_t_4, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1962; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = __Pyx_GetItemInt(__pyx_t_4, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1976; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = PyObject_RichCompare(__pyx_v_link_i, __pyx_t_8, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1962; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_RichCompare(__pyx_v_link_i, __pyx_t_8, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1976; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1962; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1976; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     if (__pyx_t_3) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1963
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1977
  *                 nt[-1][2] = f_j
  *                 if link_i < nt[-1][3]:
  *                     if not span_check(cover, link_i, nt[-1][3] - 1):             # <<<<<<<<<<<<<<
  *                         nt[-1] = old_last_nt
  *                         return
  */
-      __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_check); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1963; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_check); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1963; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_8 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1963; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_8 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_8, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1963; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_8, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-      __pyx_t_8 = PyNumber_Subtract(__pyx_t_2, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1963; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyNumber_Subtract(__pyx_t_2, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1963; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_INCREF(__pyx_cur_scope->__pyx_v_cover);
       PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_cur_scope->__pyx_v_cover);
@@ -58909,25 +59084,25 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_t_8);
       __Pyx_GIVEREF(__pyx_t_8);
       __pyx_t_8 = 0;
-      __pyx_t_8 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1963; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
-      __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1963; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       __pyx_t_6 = (!__pyx_t_3);
       if (__pyx_t_6) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1964
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1978
  *                 if link_i < nt[-1][3]:
  *                     if not span_check(cover, link_i, nt[-1][3] - 1):
  *                         nt[-1] = old_last_nt             # <<<<<<<<<<<<<<
  *                         return
  *                     span_inc(cover, link_i, nt[-1][3] - 1)
  */
-        if (__Pyx_SetItemInt(__pyx_v_nt, -1, __pyx_v_old_last_nt, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1964; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (__Pyx_SetItemInt(__pyx_v_nt, -1, __pyx_v_old_last_nt, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1978; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1965
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1979
  *                     if not span_check(cover, link_i, nt[-1][3] - 1):
  *                         nt[-1] = old_last_nt
  *                         return             # <<<<<<<<<<<<<<
@@ -58941,24 +59116,24 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       }
       __pyx_L29:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1966
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1980
  *                         nt[-1] = old_last_nt
  *                         return
  *                     span_inc(cover, link_i, nt[-1][3] - 1)             # <<<<<<<<<<<<<<
  *                     span_inc(e_nt_cover, link_i, nt[-1][3] - 1)
  *                     nt[-1][3] = link_i
  */
-      __pyx_t_8 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_inc); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_inc); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_2, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_2, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_2 = PyNumber_Subtract(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_Subtract(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_INCREF(__pyx_cur_scope->__pyx_v_cover);
       PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_cur_scope->__pyx_v_cover);
@@ -58969,31 +59144,31 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_t_2);
       __Pyx_GIVEREF(__pyx_t_2);
       __pyx_t_2 = 0;
-      __pyx_t_2 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1967
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1981
  *                         return
  *                     span_inc(cover, link_i, nt[-1][3] - 1)
  *                     span_inc(e_nt_cover, link_i, nt[-1][3] - 1)             # <<<<<<<<<<<<<<
  *                     nt[-1][3] = link_i
  *                 if link_j > nt[-1][4]:
  */
-      __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_inc); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_inc); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      if (unlikely(!__pyx_cur_scope->__pyx_v_e_nt_cover)) { __Pyx_RaiseClosureNameError("e_nt_cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1967; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_e_nt_cover)) { __Pyx_RaiseClosureNameError("e_nt_cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1981; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_8 = __Pyx_GetItemInt(__pyx_t_4, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = __Pyx_GetItemInt(__pyx_t_4, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_4 = PyNumber_Subtract(__pyx_t_8, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyNumber_Subtract(__pyx_t_8, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-      __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e_nt_cover);
       PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_cur_scope->__pyx_v_e_nt_cover);
@@ -59004,64 +59179,64 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_t_4);
       __Pyx_GIVEREF(__pyx_t_4);
       __pyx_t_4 = 0;
-      __pyx_t_4 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_8)); __pyx_t_8 = 0;
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1968
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1982
  *                     span_inc(cover, link_i, nt[-1][3] - 1)
  *                     span_inc(e_nt_cover, link_i, nt[-1][3] - 1)
  *                     nt[-1][3] = link_i             # <<<<<<<<<<<<<<
  *                 if link_j > nt[-1][4]:
  *                     if not span_check(cover, nt[-1][4] + 1, link_j):
  */
-      __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      if (__Pyx_SetItemInt(__pyx_t_4, 3, __pyx_v_link_i, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (__Pyx_SetItemInt(__pyx_t_4, 3, __pyx_v_link_i, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       goto __pyx_L28;
     }
     __pyx_L28:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1969
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1983
  *                     span_inc(e_nt_cover, link_i, nt[-1][3] - 1)
  *                     nt[-1][3] = link_i
  *                 if link_j > nt[-1][4]:             # <<<<<<<<<<<<<<
  *                     if not span_check(cover, nt[-1][4] + 1, link_j):
  *                         nt[-1] = old_last_nt
  */
-    __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1983; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_8 = __Pyx_GetItemInt(__pyx_t_4, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = __Pyx_GetItemInt(__pyx_t_4, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1983; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = PyObject_RichCompare(__pyx_v_link_j, __pyx_t_8, Py_GT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_RichCompare(__pyx_v_link_j, __pyx_t_8, Py_GT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1983; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-    __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1983; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     if (__pyx_t_6) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1970
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1984
  *                     nt[-1][3] = link_i
  *                 if link_j > nt[-1][4]:
  *                     if not span_check(cover, nt[-1][4] + 1, link_j):             # <<<<<<<<<<<<<<
  *                         nt[-1] = old_last_nt
  *                         return
  */
-      __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_check); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1970; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_check); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1970; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_8 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1970; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1984; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_8 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_8, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1970; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_8, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-      __pyx_t_8 = PyNumber_Add(__pyx_t_2, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1970; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyNumber_Add(__pyx_t_2, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1970; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_INCREF(__pyx_cur_scope->__pyx_v_cover);
       PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_cur_scope->__pyx_v_cover);
@@ -59072,25 +59247,25 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_v_link_j);
       __Pyx_GIVEREF(__pyx_v_link_j);
       __pyx_t_8 = 0;
-      __pyx_t_8 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1970; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1970; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       __pyx_t_3 = (!__pyx_t_6);
       if (__pyx_t_3) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1971
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1985
  *                 if link_j > nt[-1][4]:
  *                     if not span_check(cover, nt[-1][4] + 1, link_j):
  *                         nt[-1] = old_last_nt             # <<<<<<<<<<<<<<
  *                         return
  *                     span_inc(cover, nt[-1][4] + 1, link_j)
  */
-        if (__Pyx_SetItemInt(__pyx_v_nt, -1, __pyx_v_old_last_nt, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1971; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (__Pyx_SetItemInt(__pyx_v_nt, -1, __pyx_v_old_last_nt, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1985; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1972
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1986
  *                     if not span_check(cover, nt[-1][4] + 1, link_j):
  *                         nt[-1] = old_last_nt
  *                         return             # <<<<<<<<<<<<<<
@@ -59104,24 +59279,24 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       }
       __pyx_L31:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1973
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1987
  *                         nt[-1] = old_last_nt
  *                         return
  *                     span_inc(cover, nt[-1][4] + 1, link_j)             # <<<<<<<<<<<<<<
  *                     span_inc(e_nt_cover, nt[-1][4] + 1, link_j)
  *                     nt[-1][4] = link_j
  */
-      __pyx_t_8 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_inc); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1973; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_inc); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1987; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1973; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1987; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_2, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1973; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_2, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1987; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_2 = PyNumber_Add(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1973; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_Add(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1987; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1973; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1987; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_INCREF(__pyx_cur_scope->__pyx_v_cover);
       PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_cur_scope->__pyx_v_cover);
@@ -59132,31 +59307,31 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_v_link_j);
       __Pyx_GIVEREF(__pyx_v_link_j);
       __pyx_t_2 = 0;
-      __pyx_t_2 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1973; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1987; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1974
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1988
  *                         return
  *                     span_inc(cover, nt[-1][4] + 1, link_j)
  *                     span_inc(e_nt_cover, nt[-1][4] + 1, link_j)             # <<<<<<<<<<<<<<
  *                     nt[-1][4] = link_j
  *                 if links and f_j >= new_min_bound:
  */
-      __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_inc); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1974; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_inc); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1988; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      if (unlikely(!__pyx_cur_scope->__pyx_v_e_nt_cover)) { __Pyx_RaiseClosureNameError("e_nt_cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1974; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1974; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_e_nt_cover)) { __Pyx_RaiseClosureNameError("e_nt_cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1988; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1988; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_8 = __Pyx_GetItemInt(__pyx_t_4, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1974; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = __Pyx_GetItemInt(__pyx_t_4, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1988; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_4 = PyNumber_Add(__pyx_t_8, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1974; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyNumber_Add(__pyx_t_8, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1988; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-      __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1974; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1988; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e_nt_cover);
       PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_cur_scope->__pyx_v_e_nt_cover);
@@ -59167,38 +59342,38 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_v_link_j);
       __Pyx_GIVEREF(__pyx_v_link_j);
       __pyx_t_4 = 0;
-      __pyx_t_4 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1974; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1988; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_8)); __pyx_t_8 = 0;
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1975
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1989
  *                     span_inc(cover, nt[-1][4] + 1, link_j)
  *                     span_inc(e_nt_cover, nt[-1][4] + 1, link_j)
  *                     nt[-1][4] = link_j             # <<<<<<<<<<<<<<
  *                 if links and f_j >= new_min_bound:
  *                     rules.add(self.form_rule(f_i, new_e_i, f_words[f_i:f_j + 1], e_words[new_e_i:new_e_j + 1], nt, links))
  */
-      __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1975; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      if (__Pyx_SetItemInt(__pyx_t_4, 4, __pyx_v_link_j, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1975; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (__Pyx_SetItemInt(__pyx_t_4, 4, __pyx_v_link_j, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       goto __pyx_L30;
     }
     __pyx_L30:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1976
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1990
  *                     span_inc(e_nt_cover, nt[-1][4] + 1, link_j)
  *                     nt[-1][4] = link_j
  *                 if links and f_j >= new_min_bound:             # <<<<<<<<<<<<<<
  *                     rules.add(self.form_rule(f_i, new_e_i, f_words[f_i:f_j + 1], e_words[new_e_i:new_e_j + 1], nt, links))
  *                 extract(f_i, f_j + 1, new_e_i, new_e_j, new_min_bound, wc, links, nt, False)
  */
-    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_links); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1976; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_links); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1990; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     if (__pyx_t_3) {
-      __pyx_t_4 = PyObject_RichCompare(__pyx_v_f_j, __pyx_v_new_min_bound, Py_GE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1976; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1976; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_f_j, __pyx_v_new_min_bound, Py_GE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1990; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1990; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __pyx_t_5 = __pyx_t_6;
     } else {
@@ -59206,35 +59381,35 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     }
     if (__pyx_t_5) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1977
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1991
  *                     nt[-1][4] = link_j
  *                 if links and f_j >= new_min_bound:
  *                     rules.add(self.form_rule(f_i, new_e_i, f_words[f_i:f_j + 1], e_words[new_e_i:new_e_j + 1], nt, links))             # <<<<<<<<<<<<<<
  *                 extract(f_i, f_j + 1, new_e_i, new_e_j, new_min_bound, wc, links, nt, False)
  *                 nt[-1] = old_last_nt
  */
-      if (unlikely(!__pyx_cur_scope->__pyx_v_rules)) { __Pyx_RaiseClosureNameError("rules"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_4 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_rules, __pyx_n_s__add); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_rules)) { __Pyx_RaiseClosureNameError("rules"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_4 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_rules, __pyx_n_s__add); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_8 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__form_rule); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__form_rule); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
-      if (unlikely(!__pyx_cur_scope->__pyx_v_f_words)) { __Pyx_RaiseClosureNameError("f_words"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_7 = __Pyx_PyIndex_AsSsize_t(__pyx_v_f_i); if (unlikely((__pyx_t_7 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_2 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_f_words)) { __Pyx_RaiseClosureNameError("f_words"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_7 = __Pyx_PyIndex_AsSsize_t(__pyx_v_f_i); if (unlikely((__pyx_t_7 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_14 = __Pyx_PyIndex_AsSsize_t(__pyx_t_2); if (unlikely((__pyx_t_14 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_14 = __Pyx_PyIndex_AsSsize_t(__pyx_t_2); if (unlikely((__pyx_t_14 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_2 = __Pyx_PySequence_GetSlice(__pyx_cur_scope->__pyx_v_f_words, __pyx_t_7, __pyx_t_14); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_PySequence_GetSlice(__pyx_cur_scope->__pyx_v_f_words, __pyx_t_7, __pyx_t_14); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      if (unlikely(!__pyx_cur_scope->__pyx_v_e_words)) { __Pyx_RaiseClosureNameError("e_words"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_14 = __Pyx_PyIndex_AsSsize_t(__pyx_v_new_e_i); if (unlikely((__pyx_t_14 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_15 = PyNumber_Add(__pyx_v_new_e_j, __pyx_int_1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_e_words)) { __Pyx_RaiseClosureNameError("e_words"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_14 = __Pyx_PyIndex_AsSsize_t(__pyx_v_new_e_i); if (unlikely((__pyx_t_14 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = PyNumber_Add(__pyx_v_new_e_j, __pyx_int_1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
-      __pyx_t_7 = __Pyx_PyIndex_AsSsize_t(__pyx_t_15); if (unlikely((__pyx_t_7 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = __Pyx_PyIndex_AsSsize_t(__pyx_t_15); if (unlikely((__pyx_t_7 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
-      __pyx_t_15 = __Pyx_PySequence_GetSlice(__pyx_cur_scope->__pyx_v_e_words, __pyx_t_14, __pyx_t_7); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = __Pyx_PySequence_GetSlice(__pyx_cur_scope->__pyx_v_e_words, __pyx_t_14, __pyx_t_7); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
-      __pyx_t_1 = PyTuple_New(6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyTuple_New(6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_INCREF(__pyx_v_f_i);
       PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_f_i);
@@ -59254,16 +59429,16 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       __Pyx_GIVEREF(__pyx_v_links);
       __pyx_t_2 = 0;
       __pyx_t_15 = 0;
-      __pyx_t_15 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-      __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_15);
       __Pyx_GIVEREF(__pyx_t_15);
       __pyx_t_15 = 0;
-      __pyx_t_15 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
@@ -59272,19 +59447,19 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     }
     __pyx_L32:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1978
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1992
  *                 if links and f_j >= new_min_bound:
  *                     rules.add(self.form_rule(f_i, new_e_i, f_words[f_i:f_j + 1], e_words[new_e_i:new_e_j + 1], nt, links))
  *                 extract(f_i, f_j + 1, new_e_i, new_e_j, new_min_bound, wc, links, nt, False)             # <<<<<<<<<<<<<<
  *                 nt[-1] = old_last_nt
  *                 if link_i < nt[-1][3]:
  */
-    if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1978; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-    __pyx_t_15 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1978; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1992; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+    __pyx_t_15 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1992; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_15);
-    __pyx_t_1 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1978; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1992; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_4 = PyTuple_New(9); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1978; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyTuple_New(9); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1992; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_INCREF(__pyx_v_f_i);
     PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_f_i);
@@ -59313,57 +59488,57 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     __Pyx_GIVEREF(__pyx_t_1);
     __pyx_t_15 = 0;
     __pyx_t_1 = 0;
-    __pyx_t_1 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1978; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1992; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1979
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1993
  *                     rules.add(self.form_rule(f_i, new_e_i, f_words[f_i:f_j + 1], e_words[new_e_i:new_e_j + 1], nt, links))
  *                 extract(f_i, f_j + 1, new_e_i, new_e_j, new_min_bound, wc, links, nt, False)
  *                 nt[-1] = old_last_nt             # <<<<<<<<<<<<<<
  *                 if link_i < nt[-1][3]:
  *                     span_dec(cover, link_i, nt[-1][3] - 1)
  */
-    if (__Pyx_SetItemInt(__pyx_v_nt, -1, __pyx_v_old_last_nt, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1979; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (__Pyx_SetItemInt(__pyx_v_nt, -1, __pyx_v_old_last_nt, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1980
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1994
  *                 extract(f_i, f_j + 1, new_e_i, new_e_j, new_min_bound, wc, links, nt, False)
  *                 nt[-1] = old_last_nt
  *                 if link_i < nt[-1][3]:             # <<<<<<<<<<<<<<
  *                     span_dec(cover, link_i, nt[-1][3] - 1)
  *                     span_dec(e_nt_cover, link_i, nt[-1][3] - 1)
  */
-    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_1, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_1, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __pyx_t_1 = PyObject_RichCompare(__pyx_v_link_i, __pyx_t_4, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_RichCompare(__pyx_v_link_i, __pyx_t_4, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     if (__pyx_t_5) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1981
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1995
  *                 nt[-1] = old_last_nt
  *                 if link_i < nt[-1][3]:
  *                     span_dec(cover, link_i, nt[-1][3] - 1)             # <<<<<<<<<<<<<<
  *                     span_dec(e_nt_cover, link_i, nt[-1][3] - 1)
  *                 if link_j > nt[-1][4]:
  */
-      __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_dec); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_dec); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1981; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1995; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_15 = __Pyx_GetItemInt(__pyx_t_4, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = __Pyx_GetItemInt(__pyx_t_4, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_4 = PyNumber_Subtract(__pyx_t_15, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyNumber_Subtract(__pyx_t_15, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
-      __pyx_t_15 = PyTuple_New(3); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = PyTuple_New(3); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
       __Pyx_INCREF(__pyx_cur_scope->__pyx_v_cover);
       PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_cur_scope->__pyx_v_cover);
@@ -59374,31 +59549,31 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       PyTuple_SET_ITEM(__pyx_t_15, 2, __pyx_t_4);
       __Pyx_GIVEREF(__pyx_t_4);
       __pyx_t_4 = 0;
-      __pyx_t_4 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1982
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1996
  *                 if link_i < nt[-1][3]:
  *                     span_dec(cover, link_i, nt[-1][3] - 1)
  *                     span_dec(e_nt_cover, link_i, nt[-1][3] - 1)             # <<<<<<<<<<<<<<
  *                 if link_j > nt[-1][4]:
  *                     span_dec(cover, nt[-1][4] + 1, link_j)
  */
-      __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_dec); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_dec); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      if (unlikely(!__pyx_cur_scope->__pyx_v_e_nt_cover)) { __Pyx_RaiseClosureNameError("e_nt_cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1982; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_15 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_e_nt_cover)) { __Pyx_RaiseClosureNameError("e_nt_cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_15 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_15, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_15, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
-      __pyx_t_15 = PyNumber_Subtract(__pyx_t_1, __pyx_int_1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = PyNumber_Subtract(__pyx_t_1, __pyx_int_1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e_nt_cover);
       PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_cur_scope->__pyx_v_e_nt_cover);
@@ -59409,7 +59584,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_t_15);
       __Pyx_GIVEREF(__pyx_t_15);
       __pyx_t_15 = 0;
-      __pyx_t_15 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
@@ -59418,43 +59593,43 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     }
     __pyx_L33:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1983
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1997
  *                     span_dec(cover, link_i, nt[-1][3] - 1)
  *                     span_dec(e_nt_cover, link_i, nt[-1][3] - 1)
  *                 if link_j > nt[-1][4]:             # <<<<<<<<<<<<<<
  *                     span_dec(cover, nt[-1][4] + 1, link_j)
  *                     span_dec(e_nt_cover, nt[-1][4] + 1, link_j)
  */
-    __pyx_t_15 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1983; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_15 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1997; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_15);
-    __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_15, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1983; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_15, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1997; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
-    __pyx_t_15 = PyObject_RichCompare(__pyx_v_link_j, __pyx_t_1, Py_GT); __Pyx_XGOTREF(__pyx_t_15); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1983; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_15 = PyObject_RichCompare(__pyx_v_link_j, __pyx_t_1, Py_GT); __Pyx_XGOTREF(__pyx_t_15); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1997; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_15); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1983; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_15); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1997; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
     if (__pyx_t_5) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1984
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1998
  *                     span_dec(e_nt_cover, link_i, nt[-1][3] - 1)
  *                 if link_j > nt[-1][4]:
  *                     span_dec(cover, nt[-1][4] + 1, link_j)             # <<<<<<<<<<<<<<
  *                     span_dec(e_nt_cover, nt[-1][4] + 1, link_j)
  *             # Try to start a new non-terminal, extract, extend
  */
-      __pyx_t_15 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_dec); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_dec); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
-      if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1984; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1998; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_1, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_1, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_1 = PyNumber_Add(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyNumber_Add(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_INCREF(__pyx_cur_scope->__pyx_v_cover);
       PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_cur_scope->__pyx_v_cover);
@@ -59465,31 +59640,31 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_v_link_j);
       __Pyx_GIVEREF(__pyx_v_link_j);
       __pyx_t_1 = 0;
-      __pyx_t_1 = PyObject_Call(__pyx_t_15, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_Call(__pyx_t_15, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1985
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1999
  *                 if link_j > nt[-1][4]:
  *                     span_dec(cover, nt[-1][4] + 1, link_j)
  *                     span_dec(e_nt_cover, nt[-1][4] + 1, link_j)             # <<<<<<<<<<<<<<
  *             # Try to start a new non-terminal, extract, extend
  *             if (not nt or f_j - nt[-1][2] > 1) and wc < self.max_length and len(nt) < self.max_nonterminals:
  */
-      __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_dec); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1985; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_dec); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      if (unlikely(!__pyx_cur_scope->__pyx_v_e_nt_cover)) { __Pyx_RaiseClosureNameError("e_nt_cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1985; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1985; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_e_nt_cover)) { __Pyx_RaiseClosureNameError("e_nt_cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1999; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_15 = __Pyx_GetItemInt(__pyx_t_4, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1985; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = __Pyx_GetItemInt(__pyx_t_4, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_4 = PyNumber_Add(__pyx_t_15, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1985; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyNumber_Add(__pyx_t_15, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
-      __pyx_t_15 = PyTuple_New(3); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1985; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = PyTuple_New(3); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
       __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e_nt_cover);
       PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_cur_scope->__pyx_v_e_nt_cover);
@@ -59500,7 +59675,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       PyTuple_SET_ITEM(__pyx_t_15, 2, __pyx_v_link_j);
       __Pyx_GIVEREF(__pyx_v_link_j);
       __pyx_t_4 = 0;
-      __pyx_t_4 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1985; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
@@ -59512,41 +59687,41 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   }
   __pyx_L27:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1987
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2001
  *                     span_dec(e_nt_cover, nt[-1][4] + 1, link_j)
  *             # Try to start a new non-terminal, extract, extend
  *             if (not nt or f_j - nt[-1][2] > 1) and wc < self.max_length and len(nt) < self.max_nonterminals:             # <<<<<<<<<<<<<<
  *                 # Check for collisions
  *                 if not span_check(cover, link_i, link_j):
  */
-  __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_nt); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1987; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_nt); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_t_3 = (!__pyx_t_5);
   if (!__pyx_t_3) {
-    __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1987; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_15 = __Pyx_GetItemInt(__pyx_t_4, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1987; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_15 = __Pyx_GetItemInt(__pyx_t_4, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_15);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = PyNumber_Subtract(__pyx_v_f_j, __pyx_t_15); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1987; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyNumber_Subtract(__pyx_v_f_j, __pyx_t_15); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
-    __pyx_t_15 = PyObject_RichCompare(__pyx_t_4, __pyx_int_1, Py_GT); __Pyx_XGOTREF(__pyx_t_15); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1987; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_15 = PyObject_RichCompare(__pyx_t_4, __pyx_int_1, Py_GT); __Pyx_XGOTREF(__pyx_t_15); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_15); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1987; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_15); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
     __pyx_t_6 = __pyx_t_5;
   } else {
     __pyx_t_6 = __pyx_t_3;
   }
   if (__pyx_t_6) {
-    __pyx_t_15 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_length); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1987; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_15 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_length); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_15);
-    __pyx_t_4 = PyObject_RichCompare(__pyx_v_wc, __pyx_t_15, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1987; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_RichCompare(__pyx_v_wc, __pyx_t_15, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
-    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1987; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     if (__pyx_t_3) {
-      __pyx_t_7 = PyObject_Length(__pyx_v_nt); if (unlikely(__pyx_t_7 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1987; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyObject_Length(__pyx_v_nt); if (unlikely(__pyx_t_7 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_t_5 = (__pyx_t_7 < __pyx_cur_scope->__pyx_v_self->max_nonterminals);
       __pyx_t_16 = __pyx_t_5;
     } else {
@@ -59558,17 +59733,17 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   }
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1989
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2003
  *             if (not nt or f_j - nt[-1][2] > 1) and wc < self.max_length and len(nt) < self.max_nonterminals:
  *                 # Check for collisions
  *                 if not span_check(cover, link_i, link_j):             # <<<<<<<<<<<<<<
  *                     return
  *                 span_inc(cover, link_i, link_j)
  */
-    __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_check); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_check); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2003; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1989; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-    __pyx_t_15 = PyTuple_New(3); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2003; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+    __pyx_t_15 = PyTuple_New(3); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2003; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_15);
     __Pyx_INCREF(__pyx_cur_scope->__pyx_v_cover);
     PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_cur_scope->__pyx_v_cover);
@@ -59579,16 +59754,16 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     __Pyx_INCREF(__pyx_v_link_j);
     PyTuple_SET_ITEM(__pyx_t_15, 2, __pyx_v_link_j);
     __Pyx_GIVEREF(__pyx_v_link_j);
-    __pyx_t_1 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2003; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
-    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2003; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __pyx_t_6 = (!__pyx_t_3);
     if (__pyx_t_6) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1990
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2004
  *                 # Check for collisions
  *                 if not span_check(cover, link_i, link_j):
  *                     return             # <<<<<<<<<<<<<<
@@ -59602,16 +59777,16 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     }
     __pyx_L36:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1991
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2005
  *                 if not span_check(cover, link_i, link_j):
  *                     return
  *                 span_inc(cover, link_i, link_j)             # <<<<<<<<<<<<<<
  *                 span_inc(e_nt_cover, link_i, link_j)
  *                 nt.append([(nt[-1][0] + 1) if nt else 1, f_j, f_j, link_i, link_j])
  */
-    __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_inc); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_inc); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2005; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_15 = PyTuple_New(3); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_15 = PyTuple_New(3); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2005; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_15);
     __Pyx_INCREF(__pyx_cur_scope->__pyx_v_cover);
     PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_cur_scope->__pyx_v_cover);
@@ -59622,23 +59797,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     __Pyx_INCREF(__pyx_v_link_j);
     PyTuple_SET_ITEM(__pyx_t_15, 2, __pyx_v_link_j);
     __Pyx_GIVEREF(__pyx_v_link_j);
-    __pyx_t_4 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2005; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1992
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2006
  *                     return
  *                 span_inc(cover, link_i, link_j)
  *                 span_inc(e_nt_cover, link_i, link_j)             # <<<<<<<<<<<<<<
  *                 nt.append([(nt[-1][0] + 1) if nt else 1, f_j, f_j, link_i, link_j])
  *                 # Require at least one word in phrase
  */
-    __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_inc); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1992; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_inc); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2006; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    if (unlikely(!__pyx_cur_scope->__pyx_v_e_nt_cover)) { __Pyx_RaiseClosureNameError("e_nt_cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1992; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-    __pyx_t_15 = PyTuple_New(3); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1992; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_cur_scope->__pyx_v_e_nt_cover)) { __Pyx_RaiseClosureNameError("e_nt_cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2006; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+    __pyx_t_15 = PyTuple_New(3); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2006; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_15);
     __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e_nt_cover);
     PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_cur_scope->__pyx_v_e_nt_cover);
@@ -59649,27 +59824,27 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     __Pyx_INCREF(__pyx_v_link_j);
     PyTuple_SET_ITEM(__pyx_t_15, 2, __pyx_v_link_j);
     __Pyx_GIVEREF(__pyx_v_link_j);
-    __pyx_t_1 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1992; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2006; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1993
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2007
  *                 span_inc(cover, link_i, link_j)
  *                 span_inc(e_nt_cover, link_i, link_j)
  *                 nt.append([(nt[-1][0] + 1) if nt else 1, f_j, f_j, link_i, link_j])             # <<<<<<<<<<<<<<
  *                 # Require at least one word in phrase
  *                 if links and f_j >= new_min_bound:
  */
-    __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_nt); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_nt); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     if (__pyx_t_6) {
-      __pyx_t_15 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
-      __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_15, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_15, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
-      __pyx_t_15 = PyNumber_Add(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = PyNumber_Add(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __pyx_t_1 = __pyx_t_15;
@@ -59678,7 +59853,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       __Pyx_INCREF(__pyx_int_1);
       __pyx_t_1 = __pyx_int_1;
     }
-    __pyx_t_15 = PyList_New(5); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_15 = PyList_New(5); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_15);
     PyList_SET_ITEM(__pyx_t_15, 0, __pyx_t_1);
     __Pyx_GIVEREF(__pyx_t_1);
@@ -59695,22 +59870,22 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     PyList_SET_ITEM(__pyx_t_15, 4, __pyx_v_link_j);
     __Pyx_GIVEREF(__pyx_v_link_j);
     __pyx_t_1 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Append(__pyx_v_nt, ((PyObject *)__pyx_t_15)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_PyObject_Append(__pyx_v_nt, ((PyObject *)__pyx_t_15)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1995
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2009
  *                 nt.append([(nt[-1][0] + 1) if nt else 1, f_j, f_j, link_i, link_j])
  *                 # Require at least one word in phrase
  *                 if links and f_j >= new_min_bound:             # <<<<<<<<<<<<<<
  *                     rules.add(self.form_rule(f_i, new_e_i, f_words[f_i:f_j + 1], e_words[new_e_i:new_e_j + 1], nt, links))
  *                 extract(f_i, f_j + 1, new_e_i, new_e_j, new_min_bound, wc + 1, links, nt, False)
  */
-    __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_links); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_links); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2009; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     if (__pyx_t_6) {
-      __pyx_t_1 = PyObject_RichCompare(__pyx_v_f_j, __pyx_v_new_min_bound, Py_GE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_RichCompare(__pyx_v_f_j, __pyx_v_new_min_bound, Py_GE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2009; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2009; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       __pyx_t_16 = __pyx_t_3;
     } else {
@@ -59718,35 +59893,35 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     }
     if (__pyx_t_16) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1996
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2010
  *                 # Require at least one word in phrase
  *                 if links and f_j >= new_min_bound:
  *                     rules.add(self.form_rule(f_i, new_e_i, f_words[f_i:f_j + 1], e_words[new_e_i:new_e_j + 1], nt, links))             # <<<<<<<<<<<<<<
  *                 extract(f_i, f_j + 1, new_e_i, new_e_j, new_min_bound, wc + 1, links, nt, False)
  *                 nt.pop()
  */
-      if (unlikely(!__pyx_cur_scope->__pyx_v_rules)) { __Pyx_RaiseClosureNameError("rules"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_1 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_rules, __pyx_n_s__add); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_rules)) { __Pyx_RaiseClosureNameError("rules"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_1 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_rules, __pyx_n_s__add); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_15 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__form_rule); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__form_rule); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
-      if (unlikely(!__pyx_cur_scope->__pyx_v_f_words)) { __Pyx_RaiseClosureNameError("f_words"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_7 = __Pyx_PyIndex_AsSsize_t(__pyx_v_f_i); if (unlikely((__pyx_t_7 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_4 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_f_words)) { __Pyx_RaiseClosureNameError("f_words"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_7 = __Pyx_PyIndex_AsSsize_t(__pyx_v_f_i); if (unlikely((__pyx_t_7 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_14 = __Pyx_PyIndex_AsSsize_t(__pyx_t_4); if (unlikely((__pyx_t_14 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_14 = __Pyx_PyIndex_AsSsize_t(__pyx_t_4); if (unlikely((__pyx_t_14 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_4 = __Pyx_PySequence_GetSlice(__pyx_cur_scope->__pyx_v_f_words, __pyx_t_7, __pyx_t_14); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_PySequence_GetSlice(__pyx_cur_scope->__pyx_v_f_words, __pyx_t_7, __pyx_t_14); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      if (unlikely(!__pyx_cur_scope->__pyx_v_e_words)) { __Pyx_RaiseClosureNameError("e_words"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_14 = __Pyx_PyIndex_AsSsize_t(__pyx_v_new_e_i); if (unlikely((__pyx_t_14 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_8 = PyNumber_Add(__pyx_v_new_e_j, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_e_words)) { __Pyx_RaiseClosureNameError("e_words"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_14 = __Pyx_PyIndex_AsSsize_t(__pyx_v_new_e_i); if (unlikely((__pyx_t_14 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyNumber_Add(__pyx_v_new_e_j, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
-      __pyx_t_7 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_7 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_7 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-      __pyx_t_8 = __Pyx_PySequence_GetSlice(__pyx_cur_scope->__pyx_v_e_words, __pyx_t_14, __pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = __Pyx_PySequence_GetSlice(__pyx_cur_scope->__pyx_v_e_words, __pyx_t_14, __pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
-      __pyx_t_2 = PyTuple_New(6); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyTuple_New(6); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_INCREF(__pyx_v_f_i);
       PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_f_i);
@@ -59766,16 +59941,16 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       __Pyx_GIVEREF(__pyx_v_links);
       __pyx_t_4 = 0;
       __pyx_t_8 = 0;
-      __pyx_t_8 = PyObject_Call(__pyx_t_15, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyObject_Call(__pyx_t_15, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
-      __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_8);
       __Pyx_GIVEREF(__pyx_t_8);
       __pyx_t_8 = 0;
-      __pyx_t_8 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
@@ -59784,21 +59959,21 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     }
     __pyx_L37:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1997
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2011
  *                 if links and f_j >= new_min_bound:
  *                     rules.add(self.form_rule(f_i, new_e_i, f_words[f_i:f_j + 1], e_words[new_e_i:new_e_j + 1], nt, links))
  *                 extract(f_i, f_j + 1, new_e_i, new_e_j, new_min_bound, wc + 1, links, nt, False)             # <<<<<<<<<<<<<<
  *                 nt.pop()
  *                 span_dec(cover, link_i, link_j)
  */
-    if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1997; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-    __pyx_t_8 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1997; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2011; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+    __pyx_t_8 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
-    __pyx_t_2 = PyNumber_Add(__pyx_v_wc, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1997; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyNumber_Add(__pyx_v_wc, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_1 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1997; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_15 = PyTuple_New(9); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1997; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_15 = PyTuple_New(9); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_15);
     __Pyx_INCREF(__pyx_v_f_i);
     PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_v_f_i);
@@ -59827,32 +60002,32 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     __pyx_t_8 = 0;
     __pyx_t_2 = 0;
     __pyx_t_1 = 0;
-    __pyx_t_1 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1997; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1998
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2012
  *                     rules.add(self.form_rule(f_i, new_e_i, f_words[f_i:f_j + 1], e_words[new_e_i:new_e_j + 1], nt, links))
  *                 extract(f_i, f_j + 1, new_e_i, new_e_j, new_min_bound, wc + 1, links, nt, False)
  *                 nt.pop()             # <<<<<<<<<<<<<<
  *                 span_dec(cover, link_i, link_j)
  *                 span_dec(e_nt_cover, link_i, link_j)
  */
-    __pyx_t_1 = __Pyx_PyObject_Pop(__pyx_v_nt); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_PyObject_Pop(__pyx_v_nt); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1999
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2013
  *                 extract(f_i, f_j + 1, new_e_i, new_e_j, new_min_bound, wc + 1, links, nt, False)
  *                 nt.pop()
  *                 span_dec(cover, link_i, link_j)             # <<<<<<<<<<<<<<
  *                 span_dec(e_nt_cover, link_i, link_j)
  * 
  */
-    __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_dec); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_dec); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_15 = PyTuple_New(3); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_15 = PyTuple_New(3); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_15);
     __Pyx_INCREF(__pyx_cur_scope->__pyx_v_cover);
     PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_cur_scope->__pyx_v_cover);
@@ -59863,22 +60038,22 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     __Pyx_INCREF(__pyx_v_link_j);
     PyTuple_SET_ITEM(__pyx_t_15, 2, __pyx_v_link_j);
     __Pyx_GIVEREF(__pyx_v_link_j);
-    __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2000
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2014
  *                 nt.pop()
  *                 span_dec(cover, link_i, link_j)
  *                 span_dec(e_nt_cover, link_i, link_j)             # <<<<<<<<<<<<<<
  * 
  *         # Try to extract phrases from every f index
  */
-    __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_dec); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2000; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_dec); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2014; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_15 = PyTuple_New(3); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2000; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_15 = PyTuple_New(3); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2014; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_15);
     __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e_nt_cover);
     PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_cur_scope->__pyx_v_e_nt_cover);
@@ -59889,7 +60064,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     __Pyx_INCREF(__pyx_v_link_j);
     PyTuple_SET_ITEM(__pyx_t_15, 2, __pyx_v_link_j);
     __Pyx_GIVEREF(__pyx_v_link_j);
-    __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2000; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2014; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
@@ -59923,7 +60098,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1863
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1877
  *     # Aggregate stats from a training instance
  *     # (Extract rules, update counts)
  *     def add_instance(self, f_words, e_words, alignment):             # <<<<<<<<<<<<<<
@@ -59938,6 +60113,8 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
   PyObject *__pyx_v_e = NULL;
   CYTHON_UNUSED PyObject *__pyx_v_f_nt_cover = NULL;
   long __pyx_v_f_i;
+  CYTHON_UNUSED PyObject *__pyx_v_lex_i = NULL;
+  CYTHON_UNUSED PyObject *__pyx_v_lex_j = NULL;
   PyObject *__pyx_v_rule = NULL;
   PyObject *__pyx_v_f_ph = NULL;
   PyObject *__pyx_v_e_ph = NULL;
@@ -59982,7 +60159,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
   __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e_words);
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_e_words);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1865
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1879
  *     def add_instance(self, f_words, e_words, alignment):
  * 
  *         self.online = True             # <<<<<<<<<<<<<<
@@ -59991,20 +60168,20 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
  */
   __pyx_cur_scope->__pyx_v_self->online = 1;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1872
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1886
  *         # span more than once.
  *         # (f, e, al, lex_f_i, lex_f_j)
  *         rules = set()             # <<<<<<<<<<<<<<
  * 
  *         f_len = len(f_words)
  */
-  __pyx_t_1 = PySet_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1872; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PySet_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
   __pyx_cur_scope->__pyx_v_rules = ((PyObject *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1874
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1888
  *         rules = set()
  * 
  *         f_len = len(f_words)             # <<<<<<<<<<<<<<
@@ -60013,15 +60190,15 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
  */
   __pyx_t_1 = __pyx_cur_scope->__pyx_v_f_words;
   __Pyx_INCREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_1);
   __pyx_cur_scope->__pyx_v_f_len = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1875
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1889
  * 
  *         f_len = len(f_words)
  *         e_len = len(e_words)             # <<<<<<<<<<<<<<
@@ -60030,35 +60207,35 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
  */
   __pyx_t_1 = __pyx_cur_scope->__pyx_v_e_words;
   __Pyx_INCREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1875; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1889; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1875; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1889; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_e_len = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1878
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1892
  * 
  *         # Pre-compute alignment info
  *         al = [[] for i in range(f_len)]             # <<<<<<<<<<<<<<
  *         fe_span = [[e_len + 1, -1] for i in range(f_len)]
  *         ef_span = [[f_len + 1, -1] for i in range(e_len)]
  */
-  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1878; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1892; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1878; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1892; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f_len);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_cur_scope->__pyx_v_f_len);
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_f_len);
-  __pyx_t_4 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1878; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1892; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
   if (PyList_CheckExact(__pyx_t_4) || PyTuple_CheckExact(__pyx_t_4)) {
     __pyx_t_3 = __pyx_t_4; __Pyx_INCREF(__pyx_t_3); __pyx_t_2 = 0;
     __pyx_t_5 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1878; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1892; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_5 = Py_TYPE(__pyx_t_3)->tp_iternext;
   }
@@ -60067,23 +60244,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_3)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_3)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_4 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1878; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1892; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_3, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1878; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_3, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1892; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_3)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1878; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1892; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_3, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1878; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_3, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1892; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_4 = __pyx_t_5(__pyx_t_3);
       if (unlikely(!__pyx_t_4)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1878; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1892; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -60092,9 +60269,9 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     __Pyx_XDECREF(__pyx_v_i);
     __pyx_v_i = __pyx_t_4;
     __pyx_t_4 = 0;
-    __pyx_t_4 = PyList_New(0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1878; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyList_New(0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1892; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    if (unlikely(__Pyx_PyList_Append(__pyx_t_1, (PyObject*)__pyx_t_4))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1878; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(__Pyx_PyList_Append(__pyx_t_1, (PyObject*)__pyx_t_4))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1892; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
   }
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -60103,28 +60280,28 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
   __pyx_cur_scope->__pyx_v_al = ((PyObject *)__pyx_t_1);
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1879
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1893
  *         # Pre-compute alignment info
  *         al = [[] for i in range(f_len)]
  *         fe_span = [[e_len + 1, -1] for i in range(f_len)]             # <<<<<<<<<<<<<<
  *         ef_span = [[f_len + 1, -1] for i in range(e_len)]
  *         for (f, e) in alignment:
  */
-  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f_len);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_cur_scope->__pyx_v_f_len);
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_f_len);
-  __pyx_t_4 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
   if (PyList_CheckExact(__pyx_t_4) || PyTuple_CheckExact(__pyx_t_4)) {
     __pyx_t_3 = __pyx_t_4; __Pyx_INCREF(__pyx_t_3); __pyx_t_2 = 0;
     __pyx_t_5 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_5 = Py_TYPE(__pyx_t_3)->tp_iternext;
   }
@@ -60133,23 +60310,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_3)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_3)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_4 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_3, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_3, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_3)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_3, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_3, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_4 = __pyx_t_5(__pyx_t_3);
       if (unlikely(!__pyx_t_4)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -60158,9 +60335,9 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     __Pyx_XDECREF(__pyx_v_i);
     __pyx_v_i = __pyx_t_4;
     __pyx_t_4 = 0;
-    __pyx_t_4 = PyNumber_Add(__pyx_v_e_len, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyNumber_Add(__pyx_v_e_len, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = PyList_New(2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyList_New(2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     PyList_SET_ITEM(__pyx_t_6, 0, __pyx_t_4);
     __Pyx_GIVEREF(__pyx_t_4);
@@ -60168,7 +60345,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     PyList_SET_ITEM(__pyx_t_6, 1, __pyx_int_neg_1);
     __Pyx_GIVEREF(__pyx_int_neg_1);
     __pyx_t_4 = 0;
-    if (unlikely(__Pyx_PyList_Append(__pyx_t_1, (PyObject*)__pyx_t_6))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(__Pyx_PyList_Append(__pyx_t_1, (PyObject*)__pyx_t_6))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
   }
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -60177,28 +60354,28 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
   __pyx_cur_scope->__pyx_v_fe_span = ((PyObject *)__pyx_t_1);
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1880
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1894
  *         al = [[] for i in range(f_len)]
  *         fe_span = [[e_len + 1, -1] for i in range(f_len)]
  *         ef_span = [[f_len + 1, -1] for i in range(e_len)]             # <<<<<<<<<<<<<<
  *         for (f, e) in alignment:
  *             al[f].append(e)
  */
-  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_INCREF(__pyx_v_e_len);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_e_len);
   __Pyx_GIVEREF(__pyx_v_e_len);
-  __pyx_t_6 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_6 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_6);
   __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
   if (PyList_CheckExact(__pyx_t_6) || PyTuple_CheckExact(__pyx_t_6)) {
     __pyx_t_3 = __pyx_t_6; __Pyx_INCREF(__pyx_t_3); __pyx_t_2 = 0;
     __pyx_t_5 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_t_6); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_t_6); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_5 = Py_TYPE(__pyx_t_3)->tp_iternext;
   }
@@ -60207,23 +60384,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_3)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_3)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_6 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_2); __Pyx_INCREF(__pyx_t_6); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_2); __Pyx_INCREF(__pyx_t_6); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_6 = PySequence_ITEM(__pyx_t_3, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PySequence_ITEM(__pyx_t_3, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_3)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_6 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_2); __Pyx_INCREF(__pyx_t_6); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_2); __Pyx_INCREF(__pyx_t_6); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_6 = PySequence_ITEM(__pyx_t_3, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PySequence_ITEM(__pyx_t_3, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_6 = __pyx_t_5(__pyx_t_3);
       if (unlikely(!__pyx_t_6)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -60232,9 +60409,9 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     __Pyx_XDECREF(__pyx_v_i);
     __pyx_v_i = __pyx_t_6;
     __pyx_t_6 = 0;
-    __pyx_t_6 = PyNumber_Add(__pyx_cur_scope->__pyx_v_f_len, __pyx_int_1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyNumber_Add(__pyx_cur_scope->__pyx_v_f_len, __pyx_int_1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_4 = PyList_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyList_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     PyList_SET_ITEM(__pyx_t_4, 0, __pyx_t_6);
     __Pyx_GIVEREF(__pyx_t_6);
@@ -60242,7 +60419,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     PyList_SET_ITEM(__pyx_t_4, 1, __pyx_int_neg_1);
     __Pyx_GIVEREF(__pyx_int_neg_1);
     __pyx_t_6 = 0;
-    if (unlikely(__Pyx_PyList_Append(__pyx_t_1, (PyObject*)__pyx_t_4))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(__Pyx_PyList_Append(__pyx_t_1, (PyObject*)__pyx_t_4))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
   }
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -60251,7 +60428,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
   __pyx_cur_scope->__pyx_v_ef_span = ((PyObject *)__pyx_t_1);
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1881
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1895
  *         fe_span = [[e_len + 1, -1] for i in range(f_len)]
  *         ef_span = [[f_len + 1, -1] for i in range(e_len)]
  *         for (f, e) in alignment:             # <<<<<<<<<<<<<<
@@ -60262,7 +60439,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     __pyx_t_1 = __pyx_v_alignment; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
     __pyx_t_5 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_alignment); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_alignment); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_5 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -60270,23 +60447,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 1881; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_3 = __pyx_t_5(__pyx_t_1);
       if (unlikely(!__pyx_t_3)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -60302,7 +60479,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
       if (unlikely(size != 2)) {
         if (size > 2) __Pyx_RaiseTooManyValuesError(2);
         else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       }
       #if CYTHON_COMPILING_IN_CPYTHON
       if (likely(PyTuple_CheckExact(sequence))) {
@@ -60315,14 +60492,14 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
       __Pyx_INCREF(__pyx_t_4);
       __Pyx_INCREF(__pyx_t_6);
       #else
-      __pyx_t_4 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     } else
     {
       Py_ssize_t index = -1;
-      __pyx_t_7 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_7);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
       __pyx_t_8 = Py_TYPE(__pyx_t_7)->tp_iternext;
@@ -60330,7 +60507,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
       __Pyx_GOTREF(__pyx_t_4);
       index = 1; __pyx_t_6 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_6)) goto __pyx_L11_unpacking_failed;
       __Pyx_GOTREF(__pyx_t_6);
-      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_t_8 = NULL;
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       goto __pyx_L12_unpacking_done;
@@ -60338,7 +60515,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       __pyx_t_8 = NULL;
       if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_L12_unpacking_done:;
     }
     __Pyx_XDECREF(__pyx_v_f);
@@ -60348,21 +60525,21 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     __pyx_v_e = __pyx_t_6;
     __pyx_t_6 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1882
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1896
  *         ef_span = [[f_len + 1, -1] for i in range(e_len)]
  *         for (f, e) in alignment:
  *             al[f].append(e)             # <<<<<<<<<<<<<<
  *             fe_span[f][0] = min(fe_span[f][0], e)
  *             fe_span[f][1] = max(fe_span[f][1], e)
  */
-    __pyx_t_3 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_al, __pyx_v_f); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1882; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_al, __pyx_v_f); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1896; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_6 = __Pyx_PyObject_Append(__pyx_t_3, __pyx_v_e); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1882; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = __Pyx_PyObject_Append(__pyx_t_3, __pyx_v_e); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1896; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1883
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1897
  *         for (f, e) in alignment:
  *             al[f].append(e)
  *             fe_span[f][0] = min(fe_span[f][0], e)             # <<<<<<<<<<<<<<
@@ -60371,13 +60548,13 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
  */
     __Pyx_INCREF(__pyx_v_e);
     __pyx_t_6 = __pyx_v_e;
-    __pyx_t_3 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fe_span, __pyx_v_f); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1883; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fe_span, __pyx_v_f); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_3, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1883; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_3, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __pyx_t_7 = PyObject_RichCompare(__pyx_t_6, __pyx_t_4, Py_LT); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1883; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_9 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1883; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyObject_RichCompare(__pyx_t_6, __pyx_t_4, Py_LT); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_9 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     if (__pyx_t_9) {
       __Pyx_INCREF(__pyx_t_6);
@@ -60388,13 +60565,13 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     }
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fe_span, __pyx_v_f); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1883; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fe_span, __pyx_v_f); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
-    if (__Pyx_SetItemInt(__pyx_t_6, 0, __pyx_t_3, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1883; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (__Pyx_SetItemInt(__pyx_t_6, 0, __pyx_t_3, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1884
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1898
  *             al[f].append(e)
  *             fe_span[f][0] = min(fe_span[f][0], e)
  *             fe_span[f][1] = max(fe_span[f][1], e)             # <<<<<<<<<<<<<<
@@ -60403,13 +60580,13 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
  */
     __Pyx_INCREF(__pyx_v_e);
     __pyx_t_3 = __pyx_v_e;
-    __pyx_t_6 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fe_span, __pyx_v_f); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1884; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fe_span, __pyx_v_f); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1898; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_6, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1884; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_6, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1898; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_7 = PyObject_RichCompare(__pyx_t_3, __pyx_t_4, Py_GT); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1884; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_9 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1884; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyObject_RichCompare(__pyx_t_3, __pyx_t_4, Py_GT); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1898; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_9 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1898; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     if (__pyx_t_9) {
       __Pyx_INCREF(__pyx_t_3);
@@ -60420,13 +60597,13 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     }
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __pyx_t_3 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fe_span, __pyx_v_f); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1884; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fe_span, __pyx_v_f); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1898; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
-    if (__Pyx_SetItemInt(__pyx_t_3, 1, __pyx_t_6, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1884; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (__Pyx_SetItemInt(__pyx_t_3, 1, __pyx_t_6, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1898; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1885
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1899
  *             fe_span[f][0] = min(fe_span[f][0], e)
  *             fe_span[f][1] = max(fe_span[f][1], e)
  *             ef_span[e][0] = min(ef_span[e][0], f)             # <<<<<<<<<<<<<<
@@ -60435,13 +60612,13 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
  */
     __Pyx_INCREF(__pyx_v_f);
     __pyx_t_6 = __pyx_v_f;
-    __pyx_t_3 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_e); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_e); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_3, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_3, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __pyx_t_7 = PyObject_RichCompare(__pyx_t_6, __pyx_t_4, Py_LT); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_9 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyObject_RichCompare(__pyx_t_6, __pyx_t_4, Py_LT); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_9 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     if (__pyx_t_9) {
       __Pyx_INCREF(__pyx_t_6);
@@ -60452,13 +60629,13 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     }
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_e); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_e); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
-    if (__Pyx_SetItemInt(__pyx_t_6, 0, __pyx_t_3, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (__Pyx_SetItemInt(__pyx_t_6, 0, __pyx_t_3, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1886
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1900
  *             fe_span[f][1] = max(fe_span[f][1], e)
  *             ef_span[e][0] = min(ef_span[e][0], f)
  *             ef_span[e][1] = max(ef_span[e][1], f)             # <<<<<<<<<<<<<<
@@ -60467,13 +60644,13 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
  */
     __Pyx_INCREF(__pyx_v_f);
     __pyx_t_3 = __pyx_v_f;
-    __pyx_t_6 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_e); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_e); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1900; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_6, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_6, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1900; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_7 = PyObject_RichCompare(__pyx_t_3, __pyx_t_4, Py_GT); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_9 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyObject_RichCompare(__pyx_t_3, __pyx_t_4, Py_GT); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1900; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_9 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1900; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     if (__pyx_t_9) {
       __Pyx_INCREF(__pyx_t_3);
@@ -60484,27 +60661,27 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     }
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __pyx_t_3 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_e); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_e); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1900; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
-    if (__Pyx_SetItemInt(__pyx_t_3, 1, __pyx_t_6, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (__Pyx_SetItemInt(__pyx_t_3, 1, __pyx_t_6, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1900; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1889
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1903
  * 
  *         # Target side word coverage
  *         cover = [0] * e_len             # <<<<<<<<<<<<<<
  *         # Non-terminal coverage
  *         f_nt_cover = [0] * f_len
  */
-  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1889; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1903; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(__pyx_int_0);
   PyList_SET_ITEM(__pyx_t_1, 0, __pyx_int_0);
   __Pyx_GIVEREF(__pyx_int_0);
-  { PyObject* __pyx_temp = PyNumber_InPlaceMultiply(__pyx_t_1, __pyx_v_e_len); if (unlikely(!__pyx_temp)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1889; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  { PyObject* __pyx_temp = PyNumber_InPlaceMultiply(__pyx_t_1, __pyx_v_e_len); if (unlikely(!__pyx_temp)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1903; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_temp);
     __Pyx_DECREF(__pyx_t_1);
     __pyx_t_1 = __pyx_temp;
@@ -60513,19 +60690,19 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
   __pyx_cur_scope->__pyx_v_cover = ((PyObject *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1891
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1905
  *         cover = [0] * e_len
  *         # Non-terminal coverage
  *         f_nt_cover = [0] * f_len             # <<<<<<<<<<<<<<
  *         e_nt_cover = [0] * e_len
  * 
  */
-  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1891; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(__pyx_int_0);
   PyList_SET_ITEM(__pyx_t_1, 0, __pyx_int_0);
   __Pyx_GIVEREF(__pyx_int_0);
-  { PyObject* __pyx_temp = PyNumber_InPlaceMultiply(__pyx_t_1, __pyx_cur_scope->__pyx_v_f_len); if (unlikely(!__pyx_temp)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1891; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  { PyObject* __pyx_temp = PyNumber_InPlaceMultiply(__pyx_t_1, __pyx_cur_scope->__pyx_v_f_len); if (unlikely(!__pyx_temp)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_temp);
     __Pyx_DECREF(__pyx_t_1);
     __pyx_t_1 = __pyx_temp;
@@ -60533,19 +60710,19 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
   __pyx_v_f_nt_cover = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1892
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1906
  *         # Non-terminal coverage
  *         f_nt_cover = [0] * f_len
  *         e_nt_cover = [0] * e_len             # <<<<<<<<<<<<<<
  * 
  *         # Extract all possible hierarchical phrases starting at a source index
  */
-  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1892; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(__pyx_int_0);
   PyList_SET_ITEM(__pyx_t_1, 0, __pyx_int_0);
   __Pyx_GIVEREF(__pyx_int_0);
-  { PyObject* __pyx_temp = PyNumber_InPlaceMultiply(__pyx_t_1, __pyx_v_e_len); if (unlikely(!__pyx_temp)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1892; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  { PyObject* __pyx_temp = PyNumber_InPlaceMultiply(__pyx_t_1, __pyx_v_e_len); if (unlikely(!__pyx_temp)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_temp);
     __Pyx_DECREF(__pyx_t_1);
     __pyx_t_1 = __pyx_temp;
@@ -60554,44 +60731,44 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
   __pyx_cur_scope->__pyx_v_e_nt_cover = ((PyObject *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1897
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1911
  *         # f_ i and j are current, e_ i and j are previous
  *         # We care _considering_ f_j, so it is not yet in counts
  *         def extract(f_i, f_j, e_i, e_j, min_bound, wc, links, nt, nt_open):             # <<<<<<<<<<<<<<
  *             # Phrase extraction limits
  *             if f_j > (f_len - 1) or (f_j - f_i) + 1 > self.max_initial_size:
  */
-  __pyx_t_1 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_12add_instance_1extract, 0, ((PyObject*)__pyx_cur_scope), __pyx_n_s___sa, ((PyObject *)__pyx_k_codeobj_135)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_12add_instance_1extract, 0, ((PyObject*)__pyx_cur_scope), __pyx_n_s___sa, ((PyObject *)__pyx_k_codeobj_135)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_1);
   __pyx_cur_scope->__pyx_v_extract = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2003
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2017
  * 
  *         # Try to extract phrases from every f index
  *         for f_i from 0 <= f_i < f_len:             # <<<<<<<<<<<<<<
  *             # Skip if phrases won't be tight on left side
  *             if not al[f_i]:
  */
-  __pyx_t_10 = __Pyx_PyInt_AsLong(__pyx_cur_scope->__pyx_v_f_len); if (unlikely((__pyx_t_10 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2003; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_10 = __Pyx_PyInt_AsLong(__pyx_cur_scope->__pyx_v_f_len); if (unlikely((__pyx_t_10 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2017; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   for (__pyx_v_f_i = 0; __pyx_v_f_i < __pyx_t_10; __pyx_v_f_i++) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2005
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2019
  *         for f_i from 0 <= f_i < f_len:
  *             # Skip if phrases won't be tight on left side
  *             if not al[f_i]:             # <<<<<<<<<<<<<<
  *                 continue
  *             extract(f_i, f_i, f_len + 1, -1, f_i, 0, [], [], False)
  */
-    __pyx_t_1 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_al, __pyx_v_f_i, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2005; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_al, __pyx_v_f_i, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2019; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_9 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2005; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_9 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2019; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __pyx_t_11 = (!__pyx_t_9);
     if (__pyx_t_11) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2006
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2020
  *             # Skip if phrases won't be tight on left side
  *             if not al[f_i]:
  *                 continue             # <<<<<<<<<<<<<<
@@ -60603,28 +60780,28 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     }
     __pyx_L15:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2007
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2021
  *             if not al[f_i]:
  *                 continue
  *             extract(f_i, f_i, f_len + 1, -1, f_i, 0, [], [], False)             # <<<<<<<<<<<<<<
  * 
- *         # Update phrase counts
+ *         # Update possible phrases (samples)
  */
-    __pyx_t_1 = PyInt_FromLong(__pyx_v_f_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyInt_FromLong(__pyx_v_f_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_6 = PyInt_FromLong(__pyx_v_f_i); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyInt_FromLong(__pyx_v_f_i); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_3 = PyNumber_Add(__pyx_cur_scope->__pyx_v_f_len, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyNumber_Add(__pyx_cur_scope->__pyx_v_f_len, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_4 = PyInt_FromLong(__pyx_v_f_i); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyInt_FromLong(__pyx_v_f_i); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_7 = PyList_New(0); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyList_New(0); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_7);
-    __pyx_t_12 = PyList_New(0); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_12 = PyList_New(0); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_12);
-    __pyx_t_13 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_13 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_13);
-    __pyx_t_14 = PyTuple_New(9); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_14 = PyTuple_New(9); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_14);
     PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_t_1);
     __Pyx_GIVEREF(__pyx_t_1);
@@ -60653,14 +60830,155 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     __pyx_t_7 = 0;
     __pyx_t_12 = 0;
     __pyx_t_13 = 0;
-    __pyx_t_13 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_13 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_13);
     __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
     __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
     __pyx_L13_continue:;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2010
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2026
+ *         # This could be more efficiently integrated with extraction
+ *         # at the cost of readability
+ *         for (f, lex_i, lex_j) in self.get_f_phrases(f_words):             # <<<<<<<<<<<<<<
+ *             self.samples_f[f] += 1
+ * 
+ */
+  __pyx_t_13 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__get_f_phrases); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_13);
+  __pyx_t_14 = PyTuple_New(1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_14);
+  __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f_words);
+  PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_cur_scope->__pyx_v_f_words);
+  __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_f_words);
+  __pyx_t_12 = PyObject_Call(__pyx_t_13, ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_12);
+  __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+  __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
+  if (PyList_CheckExact(__pyx_t_12) || PyTuple_CheckExact(__pyx_t_12)) {
+    __pyx_t_14 = __pyx_t_12; __Pyx_INCREF(__pyx_t_14); __pyx_t_2 = 0;
+    __pyx_t_5 = NULL;
+  } else {
+    __pyx_t_2 = -1; __pyx_t_14 = PyObject_GetIter(__pyx_t_12); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_14);
+    __pyx_t_5 = Py_TYPE(__pyx_t_14)->tp_iternext;
+  }
+  __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+  for (;;) {
+    if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_14)) {
+      if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_14)) break;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      __pyx_t_12 = PyList_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_12); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #else
+      __pyx_t_12 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #endif
+    } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_14)) {
+      if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_14)) break;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      __pyx_t_12 = PyTuple_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_12); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #else
+      __pyx_t_12 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #endif
+    } else {
+      __pyx_t_12 = __pyx_t_5(__pyx_t_14);
+      if (unlikely(!__pyx_t_12)) {
+        if (PyErr_Occurred()) {
+          if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_12);
+    }
+    if ((likely(PyTuple_CheckExact(__pyx_t_12))) || (PyList_CheckExact(__pyx_t_12))) {
+      PyObject* sequence = __pyx_t_12;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      Py_ssize_t size = Py_SIZE(sequence);
+      #else
+      Py_ssize_t size = PySequence_Size(sequence);
+      #endif
+      if (unlikely(size != 3)) {
+        if (size > 3) __Pyx_RaiseTooManyValuesError(3);
+        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      #if CYTHON_COMPILING_IN_CPYTHON
+      if (likely(PyTuple_CheckExact(sequence))) {
+        __pyx_t_13 = PyTuple_GET_ITEM(sequence, 0); 
+        __pyx_t_7 = PyTuple_GET_ITEM(sequence, 1); 
+        __pyx_t_4 = PyTuple_GET_ITEM(sequence, 2); 
+      } else {
+        __pyx_t_13 = PyList_GET_ITEM(sequence, 0); 
+        __pyx_t_7 = PyList_GET_ITEM(sequence, 1); 
+        __pyx_t_4 = PyList_GET_ITEM(sequence, 2); 
+      }
+      __Pyx_INCREF(__pyx_t_13);
+      __Pyx_INCREF(__pyx_t_7);
+      __Pyx_INCREF(__pyx_t_4);
+      #else
+      __pyx_t_13 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      #endif
+      __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+    } else
+    {
+      Py_ssize_t index = -1;
+      __pyx_t_3 = PyObject_GetIter(__pyx_t_12); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+      __pyx_t_8 = Py_TYPE(__pyx_t_3)->tp_iternext;
+      index = 0; __pyx_t_13 = __pyx_t_8(__pyx_t_3); if (unlikely(!__pyx_t_13)) goto __pyx_L18_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_13);
+      index = 1; __pyx_t_7 = __pyx_t_8(__pyx_t_3); if (unlikely(!__pyx_t_7)) goto __pyx_L18_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_7);
+      index = 2; __pyx_t_4 = __pyx_t_8(__pyx_t_3); if (unlikely(!__pyx_t_4)) goto __pyx_L18_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_4);
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_3), 3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = NULL;
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      goto __pyx_L19_unpacking_done;
+      __pyx_L18_unpacking_failed:;
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_8 = NULL;
+      if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_L19_unpacking_done:;
+    }
+    __Pyx_XDECREF(__pyx_v_f);
+    __pyx_v_f = __pyx_t_13;
+    __pyx_t_13 = 0;
+    __Pyx_XDECREF(__pyx_v_lex_i);
+    __pyx_v_lex_i = __pyx_t_7;
+    __pyx_t_7 = 0;
+    __Pyx_XDECREF(__pyx_v_lex_j);
+    __pyx_v_lex_j = __pyx_t_4;
+    __pyx_t_4 = 0;
+
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2027
+ *         # at the cost of readability
+ *         for (f, lex_i, lex_j) in self.get_f_phrases(f_words):
+ *             self.samples_f[f] += 1             # <<<<<<<<<<<<<<
+ * 
+ *         # Update phrase counts
+ */
+    __Pyx_INCREF(__pyx_cur_scope->__pyx_v_self->samples_f);
+    __pyx_t_12 = __pyx_cur_scope->__pyx_v_self->samples_f;
+    __Pyx_INCREF(__pyx_v_f);
+    __pyx_t_4 = __pyx_v_f;
+    __pyx_t_7 = PyObject_GetItem(__pyx_t_12, __pyx_t_4); if (!__pyx_t_7) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2027; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __pyx_t_13 = PyNumber_InPlaceAdd(__pyx_t_7, __pyx_int_1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2027; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_13);
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    if (PyObject_SetItem(__pyx_t_12, __pyx_t_4, __pyx_t_13) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2027; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2030
  * 
  *         # Update phrase counts
  *         for rule in rules:             # <<<<<<<<<<<<<<
@@ -60668,54 +60986,54 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
  *             self.phrases_f[f_ph] += 1
  */
   if (PyList_CheckExact(__pyx_cur_scope->__pyx_v_rules) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_v_rules)) {
-    __pyx_t_13 = __pyx_cur_scope->__pyx_v_rules; __Pyx_INCREF(__pyx_t_13); __pyx_t_2 = 0;
+    __pyx_t_14 = __pyx_cur_scope->__pyx_v_rules; __Pyx_INCREF(__pyx_t_14); __pyx_t_2 = 0;
     __pyx_t_5 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_13 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_rules); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_13);
-    __pyx_t_5 = Py_TYPE(__pyx_t_13)->tp_iternext;
+    __pyx_t_2 = -1; __pyx_t_14 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_rules); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_14);
+    __pyx_t_5 = Py_TYPE(__pyx_t_14)->tp_iternext;
   }
   for (;;) {
-    if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_13)) {
-      if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_13)) break;
+    if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_14)) {
+      if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_14)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_14 = PyList_GET_ITEM(__pyx_t_13, __pyx_t_2); __Pyx_INCREF(__pyx_t_14); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_12 = PyList_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_12); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_14 = PySequence_ITEM(__pyx_t_13, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_12 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
-    } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_13)) {
-      if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_13)) break;
+    } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_14)) {
+      if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_14)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_14 = PyTuple_GET_ITEM(__pyx_t_13, __pyx_t_2); __Pyx_INCREF(__pyx_t_14); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_12 = PyTuple_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_12); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_14 = PySequence_ITEM(__pyx_t_13, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_12 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
-      __pyx_t_14 = __pyx_t_5(__pyx_t_13);
-      if (unlikely(!__pyx_t_14)) {
+      __pyx_t_12 = __pyx_t_5(__pyx_t_14);
+      if (unlikely(!__pyx_t_12)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
-      __Pyx_GOTREF(__pyx_t_14);
+      __Pyx_GOTREF(__pyx_t_12);
     }
     __Pyx_XDECREF(__pyx_v_rule);
-    __pyx_v_rule = __pyx_t_14;
-    __pyx_t_14 = 0;
+    __pyx_v_rule = __pyx_t_12;
+    __pyx_t_12 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2011
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2031
  *         # Update phrase counts
  *         for rule in rules:
  *             (f_ph, e_ph, al) = rule[:3]             # <<<<<<<<<<<<<<
  *             self.phrases_f[f_ph] += 1
  *             self.phrases_e[e_ph] += 1
  */
-    __pyx_t_14 = __Pyx_PySequence_GetSlice(__pyx_v_rule, 0, 3); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_14);
-    if ((likely(PyTuple_CheckExact(__pyx_t_14))) || (PyList_CheckExact(__pyx_t_14))) {
-      PyObject* sequence = __pyx_t_14;
+    __pyx_t_12 = __Pyx_PySequence_GetSlice(__pyx_v_rule, 0, 3); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2031; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_12);
+    if ((likely(PyTuple_CheckExact(__pyx_t_12))) || (PyList_CheckExact(__pyx_t_12))) {
+      PyObject* sequence = __pyx_t_12;
       #if CYTHON_COMPILING_IN_CPYTHON
       Py_ssize_t size = Py_SIZE(sequence);
       #else
@@ -60724,64 +61042,64 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
       if (unlikely(size != 3)) {
         if (size > 3) __Pyx_RaiseTooManyValuesError(3);
         else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2031; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       }
       #if CYTHON_COMPILING_IN_CPYTHON
       if (likely(PyTuple_CheckExact(sequence))) {
-        __pyx_t_12 = PyTuple_GET_ITEM(sequence, 0); 
-        __pyx_t_7 = PyTuple_GET_ITEM(sequence, 1); 
-        __pyx_t_4 = PyTuple_GET_ITEM(sequence, 2); 
+        __pyx_t_4 = PyTuple_GET_ITEM(sequence, 0); 
+        __pyx_t_13 = PyTuple_GET_ITEM(sequence, 1); 
+        __pyx_t_7 = PyTuple_GET_ITEM(sequence, 2); 
       } else {
-        __pyx_t_12 = PyList_GET_ITEM(sequence, 0); 
-        __pyx_t_7 = PyList_GET_ITEM(sequence, 1); 
-        __pyx_t_4 = PyList_GET_ITEM(sequence, 2); 
+        __pyx_t_4 = PyList_GET_ITEM(sequence, 0); 
+        __pyx_t_13 = PyList_GET_ITEM(sequence, 1); 
+        __pyx_t_7 = PyList_GET_ITEM(sequence, 2); 
       }
-      __Pyx_INCREF(__pyx_t_12);
-      __Pyx_INCREF(__pyx_t_7);
       __Pyx_INCREF(__pyx_t_4);
+      __Pyx_INCREF(__pyx_t_13);
+      __Pyx_INCREF(__pyx_t_7);
       #else
-      __pyx_t_12 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_7 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_4 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2031; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_13 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2031; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2031; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
-      __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+      __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
     } else
     {
       Py_ssize_t index = -1;
-      __pyx_t_3 = PyObject_GetIter(__pyx_t_14); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyObject_GetIter(__pyx_t_12); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2031; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
-      __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+      __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
       __pyx_t_8 = Py_TYPE(__pyx_t_3)->tp_iternext;
-      index = 0; __pyx_t_12 = __pyx_t_8(__pyx_t_3); if (unlikely(!__pyx_t_12)) goto __pyx_L18_unpacking_failed;
-      __Pyx_GOTREF(__pyx_t_12);
-      index = 1; __pyx_t_7 = __pyx_t_8(__pyx_t_3); if (unlikely(!__pyx_t_7)) goto __pyx_L18_unpacking_failed;
-      __Pyx_GOTREF(__pyx_t_7);
-      index = 2; __pyx_t_4 = __pyx_t_8(__pyx_t_3); if (unlikely(!__pyx_t_4)) goto __pyx_L18_unpacking_failed;
+      index = 0; __pyx_t_4 = __pyx_t_8(__pyx_t_3); if (unlikely(!__pyx_t_4)) goto __pyx_L22_unpacking_failed;
       __Pyx_GOTREF(__pyx_t_4);
-      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_3), 3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      index = 1; __pyx_t_13 = __pyx_t_8(__pyx_t_3); if (unlikely(!__pyx_t_13)) goto __pyx_L22_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_13);
+      index = 2; __pyx_t_7 = __pyx_t_8(__pyx_t_3); if (unlikely(!__pyx_t_7)) goto __pyx_L22_unpacking_failed;
+      __Pyx_GOTREF(__pyx_t_7);
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_3), 3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2031; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_t_8 = NULL;
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      goto __pyx_L19_unpacking_done;
-      __pyx_L18_unpacking_failed:;
+      goto __pyx_L23_unpacking_done;
+      __pyx_L22_unpacking_failed:;
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
       __pyx_t_8 = NULL;
       if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_L19_unpacking_done:;
+      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2031; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_L23_unpacking_done:;
     }
     __Pyx_XDECREF(__pyx_v_f_ph);
-    __pyx_v_f_ph = __pyx_t_12;
-    __pyx_t_12 = 0;
+    __pyx_v_f_ph = __pyx_t_4;
+    __pyx_t_4 = 0;
     __Pyx_XDECREF(__pyx_v_e_ph);
-    __pyx_v_e_ph = __pyx_t_7;
-    __pyx_t_7 = 0;
+    __pyx_v_e_ph = __pyx_t_13;
+    __pyx_t_13 = 0;
     __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_al);
     __Pyx_DECREF(__pyx_cur_scope->__pyx_v_al);
-    __Pyx_GIVEREF(__pyx_t_4);
-    __pyx_cur_scope->__pyx_v_al = __pyx_t_4;
-    __pyx_t_4 = 0;
+    __Pyx_GIVEREF(__pyx_t_7);
+    __pyx_cur_scope->__pyx_v_al = __pyx_t_7;
+    __pyx_t_7 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2012
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2032
  *         for rule in rules:
  *             (f_ph, e_ph, al) = rule[:3]
  *             self.phrases_f[f_ph] += 1             # <<<<<<<<<<<<<<
@@ -60789,20 +61107,20 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
  *             self.phrases_fe[f_ph][e_ph] += 1
  */
     __Pyx_INCREF(__pyx_cur_scope->__pyx_v_self->phrases_f);
-    __pyx_t_14 = __pyx_cur_scope->__pyx_v_self->phrases_f;
+    __pyx_t_12 = __pyx_cur_scope->__pyx_v_self->phrases_f;
     __Pyx_INCREF(__pyx_v_f_ph);
-    __pyx_t_4 = __pyx_v_f_ph;
-    __pyx_t_7 = PyObject_GetItem(__pyx_t_14, __pyx_t_4); if (!__pyx_t_7) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_7);
-    __pyx_t_12 = PyNumber_InPlaceAdd(__pyx_t_7, __pyx_int_1); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_12);
+    __pyx_t_7 = __pyx_v_f_ph;
+    __pyx_t_13 = PyObject_GetItem(__pyx_t_12, __pyx_t_7); if (!__pyx_t_13) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2032; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_13);
+    __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_t_13, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2032; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+    if (PyObject_SetItem(__pyx_t_12, __pyx_t_7, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2032; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (PyObject_SetItem(__pyx_t_14, __pyx_t_4, __pyx_t_12) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2013
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2033
  *             (f_ph, e_ph, al) = rule[:3]
  *             self.phrases_f[f_ph] += 1
  *             self.phrases_e[e_ph] += 1             # <<<<<<<<<<<<<<
@@ -60810,75 +61128,75 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
  *             if not self.phrases_al[f_ph][e_ph]:
  */
     __Pyx_INCREF(__pyx_cur_scope->__pyx_v_self->phrases_e);
-    __pyx_t_14 = __pyx_cur_scope->__pyx_v_self->phrases_e;
+    __pyx_t_12 = __pyx_cur_scope->__pyx_v_self->phrases_e;
     __Pyx_INCREF(__pyx_v_e_ph);
-    __pyx_t_4 = __pyx_v_e_ph;
-    __pyx_t_12 = PyObject_GetItem(__pyx_t_14, __pyx_t_4); if (!__pyx_t_12) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_12);
-    __pyx_t_7 = PyNumber_InPlaceAdd(__pyx_t_12, __pyx_int_1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_7);
-    __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
-    if (PyObject_SetItem(__pyx_t_14, __pyx_t_4, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __pyx_t_7 = __pyx_v_e_ph;
+    __pyx_t_4 = PyObject_GetItem(__pyx_t_12, __pyx_t_7); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_13 = PyNumber_InPlaceAdd(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_13);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+    if (PyObject_SetItem(__pyx_t_12, __pyx_t_7, __pyx_t_13) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2014
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2034
  *             self.phrases_f[f_ph] += 1
  *             self.phrases_e[e_ph] += 1
  *             self.phrases_fe[f_ph][e_ph] += 1             # <<<<<<<<<<<<<<
  *             if not self.phrases_al[f_ph][e_ph]:
  *                 self.phrases_al[f_ph][e_ph] = al
  */
-    __pyx_t_14 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_self->phrases_fe, __pyx_v_f_ph); if (!__pyx_t_14) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2014; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_14);
-    __Pyx_INCREF(__pyx_v_e_ph);
-    __pyx_t_4 = __pyx_v_e_ph;
-    __pyx_t_7 = PyObject_GetItem(__pyx_t_14, __pyx_t_4); if (!__pyx_t_7) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2014; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_7);
-    __pyx_t_12 = PyNumber_InPlaceAdd(__pyx_t_7, __pyx_int_1); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2014; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_12 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_self->phrases_fe, __pyx_v_f_ph); if (!__pyx_t_12) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2034; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_12);
+    __Pyx_INCREF(__pyx_v_e_ph);
+    __pyx_t_7 = __pyx_v_e_ph;
+    __pyx_t_13 = PyObject_GetItem(__pyx_t_12, __pyx_t_7); if (!__pyx_t_13) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2034; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_13);
+    __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_t_13, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2034; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+    if (PyObject_SetItem(__pyx_t_12, __pyx_t_7, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2034; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (PyObject_SetItem(__pyx_t_14, __pyx_t_4, __pyx_t_12) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2014; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2015
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2035
  *             self.phrases_e[e_ph] += 1
  *             self.phrases_fe[f_ph][e_ph] += 1
  *             if not self.phrases_al[f_ph][e_ph]:             # <<<<<<<<<<<<<<
  *                 self.phrases_al[f_ph][e_ph] = al
  * 
  */
-    __pyx_t_14 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_self->phrases_al, __pyx_v_f_ph); if (!__pyx_t_14) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2015; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_14);
-    __pyx_t_4 = PyObject_GetItem(__pyx_t_14, __pyx_v_e_ph); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2015; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
-    __pyx_t_11 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_11 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2015; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_12 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_self->phrases_al, __pyx_v_f_ph); if (!__pyx_t_12) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_12);
+    __pyx_t_7 = PyObject_GetItem(__pyx_t_12, __pyx_v_e_ph); if (!__pyx_t_7) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+    __pyx_t_11 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_11 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     __pyx_t_9 = (!__pyx_t_11);
     if (__pyx_t_9) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2016
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2036
  *             self.phrases_fe[f_ph][e_ph] += 1
  *             if not self.phrases_al[f_ph][e_ph]:
  *                 self.phrases_al[f_ph][e_ph] = al             # <<<<<<<<<<<<<<
  * 
  *         # Update Bilexical counts
  */
-      __pyx_t_4 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_self->phrases_al, __pyx_v_f_ph); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2016; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_4);
-      if (PyObject_SetItem(__pyx_t_4, __pyx_v_e_ph, __pyx_cur_scope->__pyx_v_al) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2016; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      goto __pyx_L20;
+      __pyx_t_7 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_self->phrases_al, __pyx_v_f_ph); if (!__pyx_t_7) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2036; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      if (PyObject_SetItem(__pyx_t_7, __pyx_v_e_ph, __pyx_cur_scope->__pyx_v_al) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2036; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      goto __pyx_L24;
     }
-    __pyx_L20:;
+    __pyx_L24:;
   }
-  __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+  __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2019
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2039
  * 
  *         # Update Bilexical counts
  *         for e_w in e_words:             # <<<<<<<<<<<<<<
@@ -60886,44 +61204,44 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
  *         for f_w in f_words:
  */
   if (PyList_CheckExact(__pyx_cur_scope->__pyx_v_e_words) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_v_e_words)) {
-    __pyx_t_13 = __pyx_cur_scope->__pyx_v_e_words; __Pyx_INCREF(__pyx_t_13); __pyx_t_2 = 0;
+    __pyx_t_14 = __pyx_cur_scope->__pyx_v_e_words; __Pyx_INCREF(__pyx_t_14); __pyx_t_2 = 0;
     __pyx_t_5 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_13 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_e_words); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2019; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_13);
-    __pyx_t_5 = Py_TYPE(__pyx_t_13)->tp_iternext;
+    __pyx_t_2 = -1; __pyx_t_14 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_e_words); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_14);
+    __pyx_t_5 = Py_TYPE(__pyx_t_14)->tp_iternext;
   }
   for (;;) {
-    if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_13)) {
-      if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_13)) break;
+    if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_14)) {
+      if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_14)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_4 = PyList_GET_ITEM(__pyx_t_13, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2019; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyList_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_7); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_13, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2019; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
-    } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_13)) {
-      if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_13)) break;
+    } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_14)) {
+      if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_14)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_13, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2019; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_7); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_13, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2019; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
-      __pyx_t_4 = __pyx_t_5(__pyx_t_13);
-      if (unlikely(!__pyx_t_4)) {
+      __pyx_t_7 = __pyx_t_5(__pyx_t_14);
+      if (unlikely(!__pyx_t_7)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2019; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
-      __Pyx_GOTREF(__pyx_t_4);
+      __Pyx_GOTREF(__pyx_t_7);
     }
     __Pyx_XDECREF(__pyx_v_e_w);
-    __pyx_v_e_w = __pyx_t_4;
-    __pyx_t_4 = 0;
+    __pyx_v_e_w = __pyx_t_7;
+    __pyx_t_7 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2020
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2040
  *         # Update Bilexical counts
  *         for e_w in e_words:
  *             self.bilex_e[e_w] += 1             # <<<<<<<<<<<<<<
@@ -60931,22 +61249,22 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
  *             self.bilex_f[f_w] += 1
  */
     __Pyx_INCREF(__pyx_cur_scope->__pyx_v_self->bilex_e);
-    __pyx_t_4 = __pyx_cur_scope->__pyx_v_self->bilex_e;
+    __pyx_t_7 = __pyx_cur_scope->__pyx_v_self->bilex_e;
     __Pyx_INCREF(__pyx_v_e_w);
-    __pyx_t_14 = __pyx_v_e_w;
-    __pyx_t_12 = PyObject_GetItem(__pyx_t_4, __pyx_t_14); if (!__pyx_t_12) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2020; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_12);
-    __pyx_t_7 = PyNumber_InPlaceAdd(__pyx_t_12, __pyx_int_1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2020; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_7);
+    __pyx_t_12 = __pyx_v_e_w;
+    __pyx_t_4 = PyObject_GetItem(__pyx_t_7, __pyx_t_12); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2040; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_13 = PyNumber_InPlaceAdd(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2040; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_13);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    if (PyObject_SetItem(__pyx_t_7, __pyx_t_12, __pyx_t_13) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2040; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
     __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
-    if (PyObject_SetItem(__pyx_t_4, __pyx_t_14, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2020; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-    __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   }
-  __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+  __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2021
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2041
  *         for e_w in e_words:
  *             self.bilex_e[e_w] += 1
  *         for f_w in f_words:             # <<<<<<<<<<<<<<
@@ -60954,44 +61272,44 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
  *             for e_w in e_words:
  */
   if (PyList_CheckExact(__pyx_cur_scope->__pyx_v_f_words) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_v_f_words)) {
-    __pyx_t_13 = __pyx_cur_scope->__pyx_v_f_words; __Pyx_INCREF(__pyx_t_13); __pyx_t_2 = 0;
+    __pyx_t_14 = __pyx_cur_scope->__pyx_v_f_words; __Pyx_INCREF(__pyx_t_14); __pyx_t_2 = 0;
     __pyx_t_5 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_13 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_f_words); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_13);
-    __pyx_t_5 = Py_TYPE(__pyx_t_13)->tp_iternext;
+    __pyx_t_2 = -1; __pyx_t_14 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_f_words); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2041; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_14);
+    __pyx_t_5 = Py_TYPE(__pyx_t_14)->tp_iternext;
   }
   for (;;) {
-    if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_13)) {
-      if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_13)) break;
+    if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_14)) {
+      if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_14)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_4 = PyList_GET_ITEM(__pyx_t_13, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyList_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_7); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2041; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_13, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2041; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
-    } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_13)) {
-      if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_13)) break;
+    } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_14)) {
+      if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_14)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_13, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_7); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2041; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_13, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2041; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
-      __pyx_t_4 = __pyx_t_5(__pyx_t_13);
-      if (unlikely(!__pyx_t_4)) {
+      __pyx_t_7 = __pyx_t_5(__pyx_t_14);
+      if (unlikely(!__pyx_t_7)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2041; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
-      __Pyx_GOTREF(__pyx_t_4);
+      __Pyx_GOTREF(__pyx_t_7);
     }
     __Pyx_XDECREF(__pyx_v_f_w);
-    __pyx_v_f_w = __pyx_t_4;
-    __pyx_t_4 = 0;
+    __pyx_v_f_w = __pyx_t_7;
+    __pyx_t_7 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2022
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2042
  *             self.bilex_e[e_w] += 1
  *         for f_w in f_words:
  *             self.bilex_f[f_w] += 1             # <<<<<<<<<<<<<<
@@ -60999,20 +61317,20 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
  *                 self.bilex_fe[f_w][e_w] += 1
  */
     __Pyx_INCREF(__pyx_cur_scope->__pyx_v_self->bilex_f);
-    __pyx_t_4 = __pyx_cur_scope->__pyx_v_self->bilex_f;
+    __pyx_t_7 = __pyx_cur_scope->__pyx_v_self->bilex_f;
     __Pyx_INCREF(__pyx_v_f_w);
-    __pyx_t_14 = __pyx_v_f_w;
-    __pyx_t_7 = PyObject_GetItem(__pyx_t_4, __pyx_t_14); if (!__pyx_t_7) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2022; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_7);
-    __pyx_t_12 = PyNumber_InPlaceAdd(__pyx_t_7, __pyx_int_1); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2022; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_12);
-    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (PyObject_SetItem(__pyx_t_4, __pyx_t_14, __pyx_t_12) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2022; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
-    __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+    __pyx_t_12 = __pyx_v_f_w;
+    __pyx_t_13 = PyObject_GetItem(__pyx_t_7, __pyx_t_12); if (!__pyx_t_13) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2042; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_13);
+    __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_t_13, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2042; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+    if (PyObject_SetItem(__pyx_t_7, __pyx_t_12, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2042; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2023
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2043
  *         for f_w in f_words:
  *             self.bilex_f[f_w] += 1
  *             for e_w in e_words:             # <<<<<<<<<<<<<<
@@ -61020,67 +61338,67 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
  * 
  */
     if (PyList_CheckExact(__pyx_cur_scope->__pyx_v_e_words) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_v_e_words)) {
-      __pyx_t_4 = __pyx_cur_scope->__pyx_v_e_words; __Pyx_INCREF(__pyx_t_4); __pyx_t_15 = 0;
+      __pyx_t_7 = __pyx_cur_scope->__pyx_v_e_words; __Pyx_INCREF(__pyx_t_7); __pyx_t_15 = 0;
       __pyx_t_16 = NULL;
     } else {
-      __pyx_t_15 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_e_words); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_16 = Py_TYPE(__pyx_t_4)->tp_iternext;
+      __pyx_t_15 = -1; __pyx_t_7 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_e_words); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      __pyx_t_16 = Py_TYPE(__pyx_t_7)->tp_iternext;
     }
     for (;;) {
-      if (!__pyx_t_16 && PyList_CheckExact(__pyx_t_4)) {
-        if (__pyx_t_15 >= PyList_GET_SIZE(__pyx_t_4)) break;
+      if (!__pyx_t_16 && PyList_CheckExact(__pyx_t_7)) {
+        if (__pyx_t_15 >= PyList_GET_SIZE(__pyx_t_7)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_14 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_15); __Pyx_INCREF(__pyx_t_14); __pyx_t_15++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_12 = PyList_GET_ITEM(__pyx_t_7, __pyx_t_15); __Pyx_INCREF(__pyx_t_12); __pyx_t_15++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_14 = PySequence_ITEM(__pyx_t_4, __pyx_t_15); __pyx_t_15++; if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_12 = PySequence_ITEM(__pyx_t_7, __pyx_t_15); __pyx_t_15++; if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
-      } else if (!__pyx_t_16 && PyTuple_CheckExact(__pyx_t_4)) {
-        if (__pyx_t_15 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
+      } else if (!__pyx_t_16 && PyTuple_CheckExact(__pyx_t_7)) {
+        if (__pyx_t_15 >= PyTuple_GET_SIZE(__pyx_t_7)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_14 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_15); __Pyx_INCREF(__pyx_t_14); __pyx_t_15++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_12 = PyTuple_GET_ITEM(__pyx_t_7, __pyx_t_15); __Pyx_INCREF(__pyx_t_12); __pyx_t_15++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_14 = PySequence_ITEM(__pyx_t_4, __pyx_t_15); __pyx_t_15++; if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_12 = PySequence_ITEM(__pyx_t_7, __pyx_t_15); __pyx_t_15++; if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else {
-        __pyx_t_14 = __pyx_t_16(__pyx_t_4);
-        if (unlikely(!__pyx_t_14)) {
+        __pyx_t_12 = __pyx_t_16(__pyx_t_7);
+        if (unlikely(!__pyx_t_12)) {
           if (PyErr_Occurred()) {
             if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           }
           break;
         }
-        __Pyx_GOTREF(__pyx_t_14);
+        __Pyx_GOTREF(__pyx_t_12);
       }
       __Pyx_XDECREF(__pyx_v_e_w);
-      __pyx_v_e_w = __pyx_t_14;
-      __pyx_t_14 = 0;
+      __pyx_v_e_w = __pyx_t_12;
+      __pyx_t_12 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2024
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2044
  *             self.bilex_f[f_w] += 1
  *             for e_w in e_words:
  *                 self.bilex_fe[f_w][e_w] += 1             # <<<<<<<<<<<<<<
  * 
  *     # Create a rule from source, target, non-terminals, and alignments
  */
-      __pyx_t_14 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_self->bilex_fe, __pyx_v_f_w); if (!__pyx_t_14) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2024; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_14);
+      __pyx_t_12 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_self->bilex_fe, __pyx_v_f_w); if (!__pyx_t_12) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2044; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_12);
       __Pyx_INCREF(__pyx_v_e_w);
-      __pyx_t_12 = __pyx_v_e_w;
-      __pyx_t_7 = PyObject_GetItem(__pyx_t_14, __pyx_t_12); if (!__pyx_t_7) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2024; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_7);
-      __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_t_7, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2024; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __pyx_v_e_w;
+      __pyx_t_13 = PyObject_GetItem(__pyx_t_12, __pyx_t_4); if (!__pyx_t_13) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2044; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_13);
+      __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_t_13, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2044; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
-      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-      if (PyObject_SetItem(__pyx_t_14, __pyx_t_12, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2024; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+      if (PyObject_SetItem(__pyx_t_12, __pyx_t_4, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2044; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
-      __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
     }
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
   }
-  __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+  __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
 
   __pyx_r = Py_None; __Pyx_INCREF(Py_None);
   goto __pyx_L0;
@@ -61100,6 +61418,8 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
   __Pyx_XDECREF(__pyx_v_f);
   __Pyx_XDECREF(__pyx_v_e);
   __Pyx_XDECREF(__pyx_v_f_nt_cover);
+  __Pyx_XDECREF(__pyx_v_lex_i);
+  __Pyx_XDECREF(__pyx_v_lex_j);
   __Pyx_XDECREF(__pyx_v_rule);
   __Pyx_XDECREF(__pyx_v_f_ph);
   __Pyx_XDECREF(__pyx_v_e_ph);
@@ -61148,31 +61468,31 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_28form_rule(PyObject *_
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__e_i)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("form_rule", 1, 6, 6, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2027; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("form_rule", 1, 6, 6, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2047; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__f_span)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("form_rule", 1, 6, 6, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2027; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("form_rule", 1, 6, 6, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2047; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  3:
         if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__e_span)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("form_rule", 1, 6, 6, 3); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2027; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("form_rule", 1, 6, 6, 3); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2047; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  4:
         if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__nt)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("form_rule", 1, 6, 6, 4); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2027; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("form_rule", 1, 6, 6, 4); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2047; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  5:
         if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__al)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("form_rule", 1, 6, 6, 5); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2027; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("form_rule", 1, 6, 6, 5); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2047; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "form_rule") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2027; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "form_rule") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2047; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 6) {
       goto __pyx_L5_argtuple_error;
@@ -61193,7 +61513,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_28form_rule(PyObject *_
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("form_rule", 1, 6, 6, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2027; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("form_rule", 1, 6, 6, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2047; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.form_rule", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -61233,11 +61553,11 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_9form_rule_lambda7(PyOb
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__y)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("lambda7", 1, 2, 2, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2030; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("lambda7", 1, 2, 2, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2050; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "lambda7") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2030; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "lambda7") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2050; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -61250,7 +61570,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_9form_rule_lambda7(PyOb
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("lambda7", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2030; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("lambda7", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2050; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.form_rule.lambda7", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -61261,7 +61581,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_9form_rule_lambda7(PyOb
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2030
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2050
  * 
  *         # Substitute in non-terminals
  *         nt_inv = sorted(nt, cmp=lambda x, y: cmp(x[3], y[3]))             # <<<<<<<<<<<<<<
@@ -61280,11 +61600,11 @@ static PyObject *__pyx_lambda_funcdef_lambda7(CYTHON_UNUSED PyObject *__pyx_self
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("lambda7", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_x, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_x, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_y, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_y, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_1);
@@ -61292,7 +61612,7 @@ static PyObject *__pyx_lambda_funcdef_lambda7(CYTHON_UNUSED PyObject *__pyx_self
   __Pyx_GIVEREF(__pyx_t_2);
   __pyx_t_1 = 0;
   __pyx_t_2 = 0;
-  __pyx_t_2 = PyObject_Call(__pyx_builtin_cmp, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Call(__pyx_builtin_cmp, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
   __pyx_r = __pyx_t_2;
@@ -61342,11 +61662,11 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_9form_rule_1lambda8(PyO
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__y)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("lambda8", 1, 2, 2, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2054; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("lambda8", 1, 2, 2, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2074; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "lambda8") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2054; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "lambda8") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2074; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -61359,7 +61679,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_9form_rule_1lambda8(PyO
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("lambda8", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2054; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("lambda8", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2074; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.form_rule.lambda8", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -61370,7 +61690,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_9form_rule_1lambda8(PyO
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2054
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2074
  *         # Adjusting alignment links takes some doing
  *         links = [list(link) for sub in al for link in sub]
  *         links_inv = sorted(links, cmp=lambda x, y: cmp(x[1], y[1]))             # <<<<<<<<<<<<<<
@@ -61389,11 +61709,11 @@ static PyObject *__pyx_lambda_funcdef_lambda8(CYTHON_UNUSED PyObject *__pyx_self
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("lambda8", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_x, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2054; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_x, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2074; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_y, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2054; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_y, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2074; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2054; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2074; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_1);
@@ -61401,7 +61721,7 @@ static PyObject *__pyx_lambda_funcdef_lambda8(CYTHON_UNUSED PyObject *__pyx_self
   __Pyx_GIVEREF(__pyx_t_2);
   __pyx_t_1 = 0;
   __pyx_t_2 = 0;
-  __pyx_t_2 = PyObject_Call(__pyx_builtin_cmp, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2054; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Call(__pyx_builtin_cmp, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2074; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
   __pyx_r = __pyx_t_2;
@@ -61423,7 +61743,7 @@ static PyObject *__pyx_lambda_funcdef_lambda8(CYTHON_UNUSED PyObject *__pyx_self
 }
 static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_9form_rule_4generator15(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value); /* proto */
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2088
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2108
  *         f = Phrase(f_sym)
  *         e = Phrase(e_sym)
  *         a = tuple(self.alignment.link(i, j) for (i, j) in links)             # <<<<<<<<<<<<<<
@@ -61449,7 +61769,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_9form_rule_2genexpr(PyO
   __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_outer_scope));
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_outer_scope);
   {
-    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_23HieroCachingRuleFactory_9form_rule_4generator15, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2088; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_23HieroCachingRuleFactory_9form_rule_4generator15, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_cur_scope);
     __Pyx_RefNannyFinishContext();
     return (PyObject *) gen;
@@ -61491,13 +61811,13 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_9form_rule_4generator15
     return NULL;
   }
   __pyx_L3_first_run:;
-  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2088; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_links)) { __Pyx_RaiseClosureNameError("links"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2088; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_links)) { __Pyx_RaiseClosureNameError("links"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
   if (PyList_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_links) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_links)) {
     __pyx_t_1 = __pyx_cur_scope->__pyx_outer_scope->__pyx_v_links; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
     __pyx_t_3 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_links); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2088; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_links); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -61505,23 +61825,23 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_9form_rule_4generator15
     if (!__pyx_t_3 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 2088; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2088; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_3 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 2088; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2088; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_4 = __pyx_t_3(__pyx_t_1);
       if (unlikely(!__pyx_t_4)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2088; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -61537,7 +61857,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_9form_rule_4generator15
       if (unlikely(size != 2)) {
         if (size > 2) __Pyx_RaiseTooManyValuesError(2);
         else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2088; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       }
       #if CYTHON_COMPILING_IN_CPYTHON
       if (likely(PyTuple_CheckExact(sequence))) {
@@ -61550,14 +61870,14 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_9form_rule_4generator15
       __Pyx_INCREF(__pyx_t_5);
       __Pyx_INCREF(__pyx_t_6);
       #else
-      __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2088; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2088; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     } else
     {
       Py_ssize_t index = -1;
-      __pyx_t_7 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2088; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __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;
@@ -61565,7 +61885,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_9form_rule_4generator15
       __Pyx_GOTREF(__pyx_t_5);
       index = 1; __pyx_t_6 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_6)) goto __pyx_L6_unpacking_failed;
       __Pyx_GOTREF(__pyx_t_6);
-      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2088; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_t_8 = NULL;
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       goto __pyx_L7_unpacking_done;
@@ -61573,7 +61893,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_9form_rule_4generator15
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       __pyx_t_8 = NULL;
       if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2088; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_L7_unpacking_done:;
     }
     __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_i);
@@ -61586,10 +61906,10 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_9form_rule_4generator15
     __Pyx_GIVEREF(__pyx_t_6);
     __pyx_cur_scope->__pyx_v_j = __pyx_t_6;
     __pyx_t_6 = 0;
-    if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_self)) { __Pyx_RaiseClosureNameError("self"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2088; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-    __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_cur_scope->__pyx_v_i); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2088; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_10 = __Pyx_PyInt_AsInt(__pyx_cur_scope->__pyx_v_j); if (unlikely((__pyx_t_10 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2088; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_4 = PyInt_FromLong(((struct __pyx_vtabstruct_3_sa_Alignment *)__pyx_cur_scope->__pyx_outer_scope->__pyx_v_self->alignment->__pyx_vtab)->link(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_self->alignment, __pyx_t_9, __pyx_t_10)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2088; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_self)) { __Pyx_RaiseClosureNameError("self"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+    __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_cur_scope->__pyx_v_i); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = __Pyx_PyInt_AsInt(__pyx_cur_scope->__pyx_v_j); if (unlikely((__pyx_t_10 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyInt_FromLong(((struct __pyx_vtabstruct_3_sa_Alignment *)__pyx_cur_scope->__pyx_outer_scope->__pyx_v_self->alignment->__pyx_vtab)->link(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_self->alignment, __pyx_t_9, __pyx_t_10)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __pyx_r = __pyx_t_4;
     __pyx_t_4 = 0;
@@ -61608,7 +61928,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_9form_rule_4generator15
     __Pyx_XGOTREF(__pyx_t_1);
     __pyx_t_2 = __pyx_cur_scope->__pyx_t_1;
     __pyx_t_3 = __pyx_cur_scope->__pyx_t_2;
-    if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2088; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyErr_SetNone(PyExc_StopIteration);
@@ -61628,7 +61948,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_9form_rule_4generator15
   return NULL;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2027
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2047
  * 
  *     # Create a rule from source, target, non-terminals, and alignments
  *     def form_rule(self, f_i, e_i, f_span, e_span, nt, al):             # <<<<<<<<<<<<<<
@@ -61685,52 +62005,52 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
   __Pyx_INCREF((PyObject *)__pyx_cur_scope->__pyx_v_self);
   __Pyx_GIVEREF((PyObject *)__pyx_cur_scope->__pyx_v_self);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2030
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2050
  * 
  *         # Substitute in non-terminals
  *         nt_inv = sorted(nt, cmp=lambda x, y: cmp(x[3], y[3]))             # <<<<<<<<<<<<<<
  *         f_sym = list(f_span[:])
  *         off = f_i
  */
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(__pyx_v_nt);
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_nt);
   __Pyx_GIVEREF(__pyx_v_nt);
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_2));
-  __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_9form_rule_lambda7, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_9form_rule_lambda7, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
-  if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__cmp), __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__cmp), __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_3 = PyObject_Call(__pyx_builtin_sorted, ((PyObject *)__pyx_t_1), ((PyObject *)__pyx_t_2)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Call(__pyx_builtin_sorted, ((PyObject *)__pyx_t_1), ((PyObject *)__pyx_t_2)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
   __pyx_v_nt_inv = __pyx_t_3;
   __pyx_t_3 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2031
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2051
  *         # Substitute in non-terminals
  *         nt_inv = sorted(nt, cmp=lambda x, y: cmp(x[3], y[3]))
  *         f_sym = list(f_span[:])             # <<<<<<<<<<<<<<
  *         off = f_i
  *         for next_nt in nt:
  */
-  __pyx_t_3 = __Pyx_PySequence_GetSlice(__pyx_v_f_span, 0, PY_SSIZE_T_MAX); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2031; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = __Pyx_PySequence_GetSlice(__pyx_v_f_span, 0, PY_SSIZE_T_MAX); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2051; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2031; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2051; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_3);
   __Pyx_GIVEREF(__pyx_t_3);
   __pyx_t_3 = 0;
-  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)(&PyList_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2031; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)(&PyList_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2051; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
   __pyx_v_f_sym = ((PyObject*)__pyx_t_3);
   __pyx_t_3 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2032
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2052
  *         nt_inv = sorted(nt, cmp=lambda x, y: cmp(x[3], y[3]))
  *         f_sym = list(f_span[:])
  *         off = f_i             # <<<<<<<<<<<<<<
@@ -61740,7 +62060,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
   __Pyx_INCREF(__pyx_v_f_i);
   __pyx_v_off = __pyx_v_f_i;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2033
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2053
  *         f_sym = list(f_span[:])
  *         off = f_i
  *         for next_nt in nt:             # <<<<<<<<<<<<<<
@@ -61751,7 +62071,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
     __pyx_t_3 = __pyx_v_nt; __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_nt); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_nt); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_5 = Py_TYPE(__pyx_t_3)->tp_iternext;
   }
@@ -61759,23 +62079,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
     if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_3)) {
       if (__pyx_t_4 >= PyList_GET_SIZE(__pyx_t_3)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_2 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_2); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_2); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_3)) {
       if (__pyx_t_4 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_2); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_2); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_2 = __pyx_t_5(__pyx_t_3);
       if (unlikely(!__pyx_t_2)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -61785,29 +62105,29 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
     __pyx_v_next_nt = __pyx_t_2;
     __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2034
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2054
  *         off = f_i
  *         for next_nt in nt:
  *             nt_len = (next_nt[2] - next_nt[1]) + 1             # <<<<<<<<<<<<<<
  *             i = 0
  *             while i < nt_len:
  */
-    __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_next_nt, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2034; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_next_nt, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2054; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_next_nt, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2034; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_next_nt, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2054; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_6 = PyNumber_Subtract(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2034; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyNumber_Subtract(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2054; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __pyx_t_1 = PyNumber_Add(__pyx_t_6, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2034; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyNumber_Add(__pyx_t_6, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2054; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_XDECREF(__pyx_v_nt_len);
     __pyx_v_nt_len = __pyx_t_1;
     __pyx_t_1 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2035
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2055
  *         for next_nt in nt:
  *             nt_len = (next_nt[2] - next_nt[1]) + 1
  *             i = 0             # <<<<<<<<<<<<<<
@@ -61818,7 +62138,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
     __Pyx_XDECREF(__pyx_v_i);
     __pyx_v_i = __pyx_int_0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2036
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2056
  *             nt_len = (next_nt[2] - next_nt[1]) + 1
  *             i = 0
  *             while i < nt_len:             # <<<<<<<<<<<<<<
@@ -61826,83 +62146,83 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
  *                 i += 1
  */
     while (1) {
-      __pyx_t_1 = PyObject_RichCompare(__pyx_v_i, __pyx_v_nt_len, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2036; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2036; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_RichCompare(__pyx_v_i, __pyx_v_nt_len, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2056; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2056; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       if (!__pyx_t_7) break;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2037
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2057
  *             i = 0
  *             while i < nt_len:
  *                 f_sym.pop(next_nt[1] - off)             # <<<<<<<<<<<<<<
  *                 i += 1
  *             f_sym.insert(next_nt[1] - off, sym_setindex(self.category, next_nt[0]))
  */
-      __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_f_sym), __pyx_n_s__pop); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_f_sym), __pyx_n_s__pop); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_6 = __Pyx_GetItemInt(__pyx_v_next_nt, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_GetItemInt(__pyx_v_next_nt, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_6);
-      __pyx_t_2 = PyNumber_Subtract(__pyx_t_6, __pyx_v_off); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_Subtract(__pyx_t_6, __pyx_v_off); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-      __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_6);
       PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_2);
       __Pyx_GIVEREF(__pyx_t_2);
       __pyx_t_2 = 0;
-      __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2038
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2058
  *             while i < nt_len:
  *                 f_sym.pop(next_nt[1] - off)
  *                 i += 1             # <<<<<<<<<<<<<<
  *             f_sym.insert(next_nt[1] - off, sym_setindex(self.category, next_nt[0]))
  *             off += (nt_len - 1)
  */
-      __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_i, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2038; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_i, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2058; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_v_i);
       __pyx_v_i = __pyx_t_2;
       __pyx_t_2 = 0;
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2039
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2059
  *                 f_sym.pop(next_nt[1] - off)
  *                 i += 1
  *             f_sym.insert(next_nt[1] - off, sym_setindex(self.category, next_nt[0]))             # <<<<<<<<<<<<<<
  *             off += (nt_len - 1)
  *         e_sym = list(e_span[:])
  */
-    __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_next_nt, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_next_nt, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2059; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_6 = PyNumber_Subtract(__pyx_t_2, __pyx_v_off); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyNumber_Subtract(__pyx_t_2, __pyx_v_off); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2059; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_8 = __Pyx_PyIndex_AsSsize_t(__pyx_t_6); if (unlikely((__pyx_t_8 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = __Pyx_PyIndex_AsSsize_t(__pyx_t_6); if (unlikely((__pyx_t_8 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2059; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = __Pyx_GetItemInt(__pyx_v_next_nt, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = __Pyx_GetItemInt(__pyx_v_next_nt, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2059; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_t_6); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_t_6); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2059; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_cur_scope->__pyx_v_self->category, __pyx_t_9)); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_cur_scope->__pyx_v_self->category, __pyx_t_9)); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2059; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_10 = PyList_Insert(__pyx_v_f_sym, __pyx_t_8, __pyx_t_6); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = PyList_Insert(__pyx_v_f_sym, __pyx_t_8, __pyx_t_6); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2059; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2040
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2060
  *                 i += 1
  *             f_sym.insert(next_nt[1] - off, sym_setindex(self.category, next_nt[0]))
  *             off += (nt_len - 1)             # <<<<<<<<<<<<<<
  *         e_sym = list(e_span[:])
  *         off = e_i
  */
-    __pyx_t_6 = PyNumber_Subtract(__pyx_v_nt_len, __pyx_int_1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2040; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyNumber_Subtract(__pyx_v_nt_len, __pyx_int_1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2060; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_off, __pyx_t_6); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2040; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_off, __pyx_t_6); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2060; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_DECREF(__pyx_v_off);
@@ -61911,27 +62231,27 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
   }
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2041
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2061
  *             f_sym.insert(next_nt[1] - off, sym_setindex(self.category, next_nt[0]))
  *             off += (nt_len - 1)
  *         e_sym = list(e_span[:])             # <<<<<<<<<<<<<<
  *         off = e_i
  *         for next_nt in nt_inv:
  */
-  __pyx_t_3 = __Pyx_PySequence_GetSlice(__pyx_v_e_span, 0, PY_SSIZE_T_MAX); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2041; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = __Pyx_PySequence_GetSlice(__pyx_v_e_span, 0, PY_SSIZE_T_MAX); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2061; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2041; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2061; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_3);
   __Pyx_GIVEREF(__pyx_t_3);
   __pyx_t_3 = 0;
-  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)(&PyList_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2041; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)(&PyList_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2061; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
   __pyx_v_e_sym = ((PyObject*)__pyx_t_3);
   __pyx_t_3 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2042
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2062
  *             off += (nt_len - 1)
  *         e_sym = list(e_span[:])
  *         off = e_i             # <<<<<<<<<<<<<<
@@ -61942,7 +62262,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
   __Pyx_DECREF(__pyx_v_off);
   __pyx_v_off = __pyx_v_e_i;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2043
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2063
  *         e_sym = list(e_span[:])
  *         off = e_i
  *         for next_nt in nt_inv:             # <<<<<<<<<<<<<<
@@ -61953,7 +62273,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
     __pyx_t_3 = __pyx_v_nt_inv; __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_nt_inv); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_nt_inv); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2063; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_5 = Py_TYPE(__pyx_t_3)->tp_iternext;
   }
@@ -61961,23 +62281,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
     if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_3)) {
       if (__pyx_t_4 >= PyList_GET_SIZE(__pyx_t_3)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_2 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_2); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_2); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2063; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2063; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_3)) {
       if (__pyx_t_4 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_2); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_2); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2063; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2063; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_2 = __pyx_t_5(__pyx_t_3);
       if (unlikely(!__pyx_t_2)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2063; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -61987,29 +62307,29 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
     __pyx_v_next_nt = __pyx_t_2;
     __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2044
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2064
  *         off = e_i
  *         for next_nt in nt_inv:
  *             nt_len = (next_nt[4] - next_nt[3]) + 1             # <<<<<<<<<<<<<<
  *             i = 0
  *             while i < nt_len:
  */
-    __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_next_nt, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2044; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_next_nt, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2064; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_6 = __Pyx_GetItemInt(__pyx_v_next_nt, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2044; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = __Pyx_GetItemInt(__pyx_v_next_nt, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2064; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_t_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2044; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_t_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2064; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = PyNumber_Add(__pyx_t_1, __pyx_int_1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2044; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyNumber_Add(__pyx_t_1, __pyx_int_1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2064; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_XDECREF(__pyx_v_nt_len);
     __pyx_v_nt_len = __pyx_t_6;
     __pyx_t_6 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2045
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2065
  *         for next_nt in nt_inv:
  *             nt_len = (next_nt[4] - next_nt[3]) + 1
  *             i = 0             # <<<<<<<<<<<<<<
@@ -62020,7 +62340,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
     __Pyx_XDECREF(__pyx_v_i);
     __pyx_v_i = __pyx_int_0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2046
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2066
  *             nt_len = (next_nt[4] - next_nt[3]) + 1
  *             i = 0
  *             while i < nt_len:             # <<<<<<<<<<<<<<
@@ -62028,83 +62348,83 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
  *                 i += 1
  */
     while (1) {
-      __pyx_t_6 = PyObject_RichCompare(__pyx_v_i, __pyx_v_nt_len, Py_LT); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2046; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2046; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PyObject_RichCompare(__pyx_v_i, __pyx_v_nt_len, Py_LT); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2066; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2066; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       if (!__pyx_t_7) break;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2047
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2067
  *             i = 0
  *             while i < nt_len:
  *                 e_sym.pop(next_nt[3] - off)             # <<<<<<<<<<<<<<
  *                 i += 1
  *             e_sym.insert(next_nt[3] - off, sym_setindex(self.category, next_nt[0]))
  */
-      __pyx_t_6 = PyObject_GetAttr(((PyObject *)__pyx_v_e_sym), __pyx_n_s__pop); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2047; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PyObject_GetAttr(((PyObject *)__pyx_v_e_sym), __pyx_n_s__pop); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_6);
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_next_nt, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2047; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_next_nt, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_2 = PyNumber_Subtract(__pyx_t_1, __pyx_v_off); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2047; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_Subtract(__pyx_t_1, __pyx_v_off); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2047; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
       __Pyx_GIVEREF(__pyx_t_2);
       __pyx_t_2 = 0;
-      __pyx_t_2 = PyObject_Call(__pyx_t_6, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2047; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_Call(__pyx_t_6, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2048
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2068
  *             while i < nt_len:
  *                 e_sym.pop(next_nt[3] - off)
  *                 i += 1             # <<<<<<<<<<<<<<
  *             e_sym.insert(next_nt[3] - off, sym_setindex(self.category, next_nt[0]))
  *             off += (nt_len - 1)
  */
-      __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_i, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2048; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_i, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2068; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_v_i);
       __pyx_v_i = __pyx_t_2;
       __pyx_t_2 = 0;
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2049
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2069
  *                 e_sym.pop(next_nt[3] - off)
  *                 i += 1
  *             e_sym.insert(next_nt[3] - off, sym_setindex(self.category, next_nt[0]))             # <<<<<<<<<<<<<<
  *             off += (nt_len - 1)
  * 
  */
-    __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_next_nt, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2049; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_next_nt, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_v_off); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2049; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_v_off); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_8 = __Pyx_PyIndex_AsSsize_t(__pyx_t_1); if (unlikely((__pyx_t_8 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2049; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = __Pyx_PyIndex_AsSsize_t(__pyx_t_1); if (unlikely((__pyx_t_8 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_next_nt, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2049; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_next_nt, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2049; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __pyx_t_1 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_cur_scope->__pyx_v_self->category, __pyx_t_9)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2049; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_cur_scope->__pyx_v_self->category, __pyx_t_9)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_10 = PyList_Insert(__pyx_v_e_sym, __pyx_t_8, __pyx_t_1); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2049; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = PyList_Insert(__pyx_v_e_sym, __pyx_t_8, __pyx_t_1); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2050
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2070
  *                 i += 1
  *             e_sym.insert(next_nt[3] - off, sym_setindex(self.category, next_nt[0]))
  *             off += (nt_len - 1)             # <<<<<<<<<<<<<<
  * 
  *         # Adjusting alignment links takes some doing
  */
-    __pyx_t_1 = PyNumber_Subtract(__pyx_v_nt_len, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyNumber_Subtract(__pyx_v_nt_len, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2070; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_off, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_off, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2070; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_DECREF(__pyx_v_off);
@@ -62113,20 +62433,20 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
   }
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2053
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2073
  * 
  *         # Adjusting alignment links takes some doing
  *         links = [list(link) for sub in al for link in sub]             # <<<<<<<<<<<<<<
  *         links_inv = sorted(links, cmp=lambda x, y: cmp(x[1], y[1]))
  *         links_len = len(links)
  */
-  __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   if (PyList_CheckExact(__pyx_v_al) || PyTuple_CheckExact(__pyx_v_al)) {
     __pyx_t_2 = __pyx_v_al; __Pyx_INCREF(__pyx_t_2); __pyx_t_4 = 0;
     __pyx_t_5 = NULL;
   } else {
-    __pyx_t_4 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_al); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_al); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_5 = Py_TYPE(__pyx_t_2)->tp_iternext;
   }
@@ -62134,23 +62454,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
     if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_2)) {
       if (__pyx_t_4 >= PyList_GET_SIZE(__pyx_t_2)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_1 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_4); __Pyx_INCREF(__pyx_t_1); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_4); __Pyx_INCREF(__pyx_t_1); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_1 = PySequence_ITEM(__pyx_t_2, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PySequence_ITEM(__pyx_t_2, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_2)) {
       if (__pyx_t_4 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_4); __Pyx_INCREF(__pyx_t_1); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_4); __Pyx_INCREF(__pyx_t_1); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_1 = PySequence_ITEM(__pyx_t_2, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PySequence_ITEM(__pyx_t_2, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_1 = __pyx_t_5(__pyx_t_2);
       if (unlikely(!__pyx_t_1)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -62163,7 +62483,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
       __pyx_t_1 = __pyx_v_sub; __Pyx_INCREF(__pyx_t_1); __pyx_t_8 = 0;
       __pyx_t_11 = NULL;
     } else {
-      __pyx_t_8 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_sub); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_sub); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __pyx_t_11 = Py_TYPE(__pyx_t_1)->tp_iternext;
     }
@@ -62171,23 +62491,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
       if (!__pyx_t_11 && PyList_CheckExact(__pyx_t_1)) {
         if (__pyx_t_8 >= PyList_GET_SIZE(__pyx_t_1)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_6 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_8); __Pyx_INCREF(__pyx_t_6); __pyx_t_8++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_6 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_8); __Pyx_INCREF(__pyx_t_6); __pyx_t_8++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_6 = PySequence_ITEM(__pyx_t_1, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_6 = PySequence_ITEM(__pyx_t_1, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else if (!__pyx_t_11 && PyTuple_CheckExact(__pyx_t_1)) {
         if (__pyx_t_8 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_6 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_8); __Pyx_INCREF(__pyx_t_6); __pyx_t_8++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_6 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_8); __Pyx_INCREF(__pyx_t_6); __pyx_t_8++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_6 = PySequence_ITEM(__pyx_t_1, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_6 = PySequence_ITEM(__pyx_t_1, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else {
         __pyx_t_6 = __pyx_t_11(__pyx_t_1);
         if (unlikely(!__pyx_t_6)) {
           if (PyErr_Occurred()) {
             if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           }
           break;
         }
@@ -62196,15 +62516,15 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
       __Pyx_XDECREF(__pyx_v_link);
       __pyx_v_link = __pyx_t_6;
       __pyx_t_6 = 0;
-      __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_6);
       __Pyx_INCREF(__pyx_v_link);
       PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_v_link);
       __Pyx_GIVEREF(__pyx_v_link);
-      __pyx_t_12 = PyObject_Call(((PyObject *)((PyObject*)(&PyList_Type))), ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_12 = PyObject_Call(((PyObject *)((PyObject*)(&PyList_Type))), ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_12);
       __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
-      if (unlikely(__Pyx_PyList_Append(__pyx_t_3, (PyObject*)__pyx_t_12))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(__Pyx_PyList_Append(__pyx_t_3, (PyObject*)__pyx_t_12))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
     }
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -62215,32 +62535,32 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
   __pyx_cur_scope->__pyx_v_links = ((PyObject *)__pyx_t_3);
   __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2054
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2074
  *         # Adjusting alignment links takes some doing
  *         links = [list(link) for sub in al for link in sub]
  *         links_inv = sorted(links, cmp=lambda x, y: cmp(x[1], y[1]))             # <<<<<<<<<<<<<<
  *         links_len = len(links)
  *         nt_len = len(nt)
  */
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2054; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2074; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_INCREF(__pyx_cur_scope->__pyx_v_links);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_cur_scope->__pyx_v_links);
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_links);
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2054; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2074; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_2));
-  __pyx_t_1 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_9form_rule_1lambda8, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2054; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_9form_rule_1lambda8, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2074; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__cmp), __pyx_t_1) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2054; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__cmp), __pyx_t_1) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2074; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_builtin_sorted, ((PyObject *)__pyx_t_3), ((PyObject *)__pyx_t_2)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2054; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(__pyx_builtin_sorted, ((PyObject *)__pyx_t_3), ((PyObject *)__pyx_t_2)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2074; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
   __pyx_v_links_inv = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2055
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2075
  *         links = [list(link) for sub in al for link in sub]
  *         links_inv = sorted(links, cmp=lambda x, y: cmp(x[1], y[1]))
  *         links_len = len(links)             # <<<<<<<<<<<<<<
@@ -62249,28 +62569,28 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
  */
   __pyx_t_1 = __pyx_cur_scope->__pyx_v_links;
   __Pyx_INCREF(__pyx_t_1);
-  __pyx_t_4 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2055; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2075; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2055; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2075; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_links_len = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2056
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2076
  *         links_inv = sorted(links, cmp=lambda x, y: cmp(x[1], y[1]))
  *         links_len = len(links)
  *         nt_len = len(nt)             # <<<<<<<<<<<<<<
  *         nt_i = 0
  *         off = f_i
  */
-  __pyx_t_4 = PyObject_Length(__pyx_v_nt); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2056; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2056; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyObject_Length(__pyx_v_nt); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2076; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2076; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_XDECREF(__pyx_v_nt_len);
   __pyx_v_nt_len = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2057
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2077
  *         links_len = len(links)
  *         nt_len = len(nt)
  *         nt_i = 0             # <<<<<<<<<<<<<<
@@ -62280,7 +62600,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
   __Pyx_INCREF(__pyx_int_0);
   __pyx_v_nt_i = __pyx_int_0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2058
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2078
  *         nt_len = len(nt)
  *         nt_i = 0
  *         off = f_i             # <<<<<<<<<<<<<<
@@ -62291,7 +62611,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
   __Pyx_DECREF(__pyx_v_off);
   __pyx_v_off = __pyx_v_f_i;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2059
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2079
  *         nt_i = 0
  *         off = f_i
  *         i = 0             # <<<<<<<<<<<<<<
@@ -62302,7 +62622,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
   __Pyx_XDECREF(__pyx_v_i);
   __pyx_v_i = __pyx_int_0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2060
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2080
  *         off = f_i
  *         i = 0
  *         while i < links_len:             # <<<<<<<<<<<<<<
@@ -62310,12 +62630,12 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
  *                 off += (nt[nt_i][2] - nt[nt_i][1])
  */
   while (1) {
-    __pyx_t_1 = PyObject_RichCompare(__pyx_v_i, __pyx_v_links_len, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2060; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2060; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_RichCompare(__pyx_v_i, __pyx_v_links_len, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2080; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2080; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     if (!__pyx_t_7) break;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2061
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2081
  *         i = 0
  *         while i < links_len:
  *             while nt_i < nt_len and links[i][0] > nt[nt_i][1]:             # <<<<<<<<<<<<<<
@@ -62323,24 +62643,24 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
  *                 nt_i += 1
  */
     while (1) {
-      __pyx_t_1 = PyObject_RichCompare(__pyx_v_nt_i, __pyx_v_nt_len, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2061; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2061; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_RichCompare(__pyx_v_nt_i, __pyx_v_nt_len, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       if (__pyx_t_7) {
-        __pyx_t_1 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_links, __pyx_v_i); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2061; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_links, __pyx_v_i); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
-        __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2061; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-        __pyx_t_1 = PyObject_GetItem(__pyx_v_nt, __pyx_v_nt_i); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2061; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyObject_GetItem(__pyx_v_nt, __pyx_v_nt_i); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
-        __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2061; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-        __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_3, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2061; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_3, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_13 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_13 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2061; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_13 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_13 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
         __pyx_t_14 = __pyx_t_13;
       } else {
@@ -62348,82 +62668,82 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
       }
       if (!__pyx_t_14) break;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2062
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2082
  *         while i < links_len:
  *             while nt_i < nt_len and links[i][0] > nt[nt_i][1]:
  *                 off += (nt[nt_i][2] - nt[nt_i][1])             # <<<<<<<<<<<<<<
  *                 nt_i += 1
  *             links[i][0] -= off
  */
-      __pyx_t_1 = PyObject_GetItem(__pyx_v_nt, __pyx_v_nt_i); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2062; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_GetItem(__pyx_v_nt, __pyx_v_nt_i); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2082; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2062; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2082; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_1 = PyObject_GetItem(__pyx_v_nt, __pyx_v_nt_i); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2062; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_GetItem(__pyx_v_nt, __pyx_v_nt_i); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2082; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2062; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2082; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_1 = PyNumber_Subtract(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2062; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyNumber_Subtract(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2082; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_off, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2062; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_off, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2082; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       __Pyx_DECREF(__pyx_v_off);
       __pyx_v_off = __pyx_t_2;
       __pyx_t_2 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2063
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2083
  *             while nt_i < nt_len and links[i][0] > nt[nt_i][1]:
  *                 off += (nt[nt_i][2] - nt[nt_i][1])
  *                 nt_i += 1             # <<<<<<<<<<<<<<
  *             links[i][0] -= off
  *             i += 1
  */
-      __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_nt_i, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2063; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_nt_i, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2083; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_v_nt_i);
       __pyx_v_nt_i = __pyx_t_2;
       __pyx_t_2 = 0;
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2064
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2084
  *                 off += (nt[nt_i][2] - nt[nt_i][1])
  *                 nt_i += 1
  *             links[i][0] -= off             # <<<<<<<<<<<<<<
  *             i += 1
  *         nt_i = 0
  */
-    __pyx_t_2 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_links, __pyx_v_i); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2064; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_links, __pyx_v_i); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2084; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_4 = 0;
-    __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_2, __pyx_t_4, sizeof(Py_ssize_t), PyInt_FromSsize_t); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2064; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_2, __pyx_t_4, sizeof(Py_ssize_t), PyInt_FromSsize_t); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2084; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_3 = PyNumber_InPlaceSubtract(__pyx_t_1, __pyx_v_off); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2064; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyNumber_InPlaceSubtract(__pyx_t_1, __pyx_v_off); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2084; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    if (__Pyx_SetItemInt(__pyx_t_2, __pyx_t_4, __pyx_t_3, sizeof(Py_ssize_t), PyInt_FromSsize_t) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2064; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (__Pyx_SetItemInt(__pyx_t_2, __pyx_t_4, __pyx_t_3, sizeof(Py_ssize_t), PyInt_FromSsize_t) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2084; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2065
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2085
  *                 nt_i += 1
  *             links[i][0] -= off
  *             i += 1             # <<<<<<<<<<<<<<
  *         nt_i = 0
  *         off = e_i
  */
-    __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_i, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2065; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_i, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2085; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_v_i);
     __pyx_v_i = __pyx_t_2;
     __pyx_t_2 = 0;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2066
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2086
  *             links[i][0] -= off
  *             i += 1
  *         nt_i = 0             # <<<<<<<<<<<<<<
@@ -62434,7 +62754,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
   __Pyx_DECREF(__pyx_v_nt_i);
   __pyx_v_nt_i = __pyx_int_0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2067
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2087
  *             i += 1
  *         nt_i = 0
  *         off = e_i             # <<<<<<<<<<<<<<
@@ -62445,7 +62765,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
   __Pyx_DECREF(__pyx_v_off);
   __pyx_v_off = __pyx_v_e_i;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2068
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2088
  *         nt_i = 0
  *         off = e_i
  *         i = 0             # <<<<<<<<<<<<<<
@@ -62456,7 +62776,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
   __Pyx_DECREF(__pyx_v_i);
   __pyx_v_i = __pyx_int_0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2069
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2089
  *         off = e_i
  *         i = 0
  *         while i < links_len:             # <<<<<<<<<<<<<<
@@ -62464,12 +62784,12 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
  *                 off += (nt_inv[nt_i][4] - nt_inv[nt_i][3])
  */
   while (1) {
-    __pyx_t_2 = PyObject_RichCompare(__pyx_v_i, __pyx_v_links_len, Py_LT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_14 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_14 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyObject_RichCompare(__pyx_v_i, __pyx_v_links_len, Py_LT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2089; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_14 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_14 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2089; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     if (!__pyx_t_14) break;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2070
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2090
  *         i = 0
  *         while i < links_len:
  *             while nt_i < nt_len and links_inv[i][1] > nt_inv[nt_i][3]:             # <<<<<<<<<<<<<<
@@ -62477,24 +62797,24 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
  *                 nt_i += 1
  */
     while (1) {
-      __pyx_t_2 = PyObject_RichCompare(__pyx_v_nt_i, __pyx_v_nt_len, Py_LT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2070; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_14 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_14 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2070; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_RichCompare(__pyx_v_nt_i, __pyx_v_nt_len, Py_LT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2090; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_14 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_14 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2090; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       if (__pyx_t_14) {
-        __pyx_t_2 = PyObject_GetItem(__pyx_v_links_inv, __pyx_v_i); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2070; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_2 = PyObject_GetItem(__pyx_v_links_inv, __pyx_v_i); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2090; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
-        __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_2, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2070; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_2, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2090; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-        __pyx_t_2 = PyObject_GetItem(__pyx_v_nt_inv, __pyx_v_nt_i); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2070; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_2 = PyObject_GetItem(__pyx_v_nt_inv, __pyx_v_nt_i); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2090; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
-        __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_2, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2070; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_2, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2090; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-        __pyx_t_2 = PyObject_RichCompare(__pyx_t_3, __pyx_t_1, Py_GT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2070; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_2 = PyObject_RichCompare(__pyx_t_3, __pyx_t_1, Py_GT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2090; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-        __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2070; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2090; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_t_13 = __pyx_t_7;
       } else {
@@ -62502,82 +62822,82 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
       }
       if (!__pyx_t_13) break;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2071
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2091
  *         while i < links_len:
  *             while nt_i < nt_len and links_inv[i][1] > nt_inv[nt_i][3]:
  *                 off += (nt_inv[nt_i][4] - nt_inv[nt_i][3])             # <<<<<<<<<<<<<<
  *                 nt_i += 1
  *             links_inv[i][1] -= off
  */
-      __pyx_t_2 = PyObject_GetItem(__pyx_v_nt_inv, __pyx_v_nt_i); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2071; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_GetItem(__pyx_v_nt_inv, __pyx_v_nt_i); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2091; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_2, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2071; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_2, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2091; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_2 = PyObject_GetItem(__pyx_v_nt_inv, __pyx_v_nt_i); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2071; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_GetItem(__pyx_v_nt_inv, __pyx_v_nt_i); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2091; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_2, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2071; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_2, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2091; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_2 = PyNumber_Subtract(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2071; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_Subtract(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2091; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_off, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2071; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_off, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2091; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_v_off);
       __pyx_v_off = __pyx_t_3;
       __pyx_t_3 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2072
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2092
  *             while nt_i < nt_len and links_inv[i][1] > nt_inv[nt_i][3]:
  *                 off += (nt_inv[nt_i][4] - nt_inv[nt_i][3])
  *                 nt_i += 1             # <<<<<<<<<<<<<<
  *             links_inv[i][1] -= off
  *             i += 1
  */
-      __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_nt_i, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2072; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_nt_i, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2092; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_v_nt_i);
       __pyx_v_nt_i = __pyx_t_3;
       __pyx_t_3 = 0;
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2073
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2093
  *                 off += (nt_inv[nt_i][4] - nt_inv[nt_i][3])
  *                 nt_i += 1
  *             links_inv[i][1] -= off             # <<<<<<<<<<<<<<
  *             i += 1
  * 
  */
-    __pyx_t_3 = PyObject_GetItem(__pyx_v_links_inv, __pyx_v_i); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_GetItem(__pyx_v_links_inv, __pyx_v_i); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = 1;
-    __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_3, __pyx_t_4, sizeof(Py_ssize_t), PyInt_FromSsize_t); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_3, __pyx_t_4, sizeof(Py_ssize_t), PyInt_FromSsize_t); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_1 = PyNumber_InPlaceSubtract(__pyx_t_2, __pyx_v_off); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyNumber_InPlaceSubtract(__pyx_t_2, __pyx_v_off); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    if (__Pyx_SetItemInt(__pyx_t_3, __pyx_t_4, __pyx_t_1, sizeof(Py_ssize_t), PyInt_FromSsize_t) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (__Pyx_SetItemInt(__pyx_t_3, __pyx_t_4, __pyx_t_1, sizeof(Py_ssize_t), PyInt_FromSsize_t) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2074
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2094
  *                 nt_i += 1
  *             links_inv[i][1] -= off
  *             i += 1             # <<<<<<<<<<<<<<
  * 
  *         # Find lexical span
  */
-    __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_i, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2074; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_i, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2094; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_v_i);
     __pyx_v_i = __pyx_t_3;
     __pyx_t_3 = 0;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2077
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2097
  * 
  *         # Find lexical span
  *         lex_f_i = f_i             # <<<<<<<<<<<<<<
@@ -62587,75 +62907,75 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
   __Pyx_INCREF(__pyx_v_f_i);
   __pyx_v_lex_f_i = __pyx_v_f_i;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2078
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2098
  *         # Find lexical span
  *         lex_f_i = f_i
  *         lex_f_j = f_i + (len(f_span) - 1)             # <<<<<<<<<<<<<<
  *         if nt:
  *             if nt[0][1] == lex_f_i:
  */
-  __pyx_t_4 = PyObject_Length(__pyx_v_f_span); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2078; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_3 = PyInt_FromSsize_t((__pyx_t_4 - 1)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2078; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyObject_Length(__pyx_v_f_span); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2098; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyInt_FromSsize_t((__pyx_t_4 - 1)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2098; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_1 = PyNumber_Add(__pyx_v_f_i, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2078; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyNumber_Add(__pyx_v_f_i, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2098; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __pyx_v_lex_f_j = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2079
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2099
  *         lex_f_i = f_i
  *         lex_f_j = f_i + (len(f_span) - 1)
  *         if nt:             # <<<<<<<<<<<<<<
  *             if nt[0][1] == lex_f_i:
  *                 lex_f_i += (nt[0][2] - nt[0][1]) + 1
  */
-  __pyx_t_13 = __Pyx_PyObject_IsTrue(__pyx_v_nt); if (unlikely(__pyx_t_13 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2079; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_13 = __Pyx_PyObject_IsTrue(__pyx_v_nt); if (unlikely(__pyx_t_13 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2099; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   if (__pyx_t_13) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2080
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2100
  *         lex_f_j = f_i + (len(f_span) - 1)
  *         if nt:
  *             if nt[0][1] == lex_f_i:             # <<<<<<<<<<<<<<
  *                 lex_f_i += (nt[0][2] - nt[0][1]) + 1
  *             if nt[-1][2] == lex_f_j:
  */
-    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2080; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2080; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __pyx_t_1 = PyObject_RichCompare(__pyx_t_3, __pyx_v_lex_f_i, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2080; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_RichCompare(__pyx_t_3, __pyx_v_lex_f_i, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __pyx_t_13 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_13 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2080; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_13 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_13 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     if (__pyx_t_13) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2081
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2101
  *         if nt:
  *             if nt[0][1] == lex_f_i:
  *                 lex_f_i += (nt[0][2] - nt[0][1]) + 1             # <<<<<<<<<<<<<<
  *             if nt[-1][2] == lex_f_j:
  *                 lex_f_j -= (nt[-1][2] - nt[-1][1]) + 1
  */
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_1 = PyNumber_Subtract(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyNumber_Subtract(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_lex_f_i, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_lex_f_i, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_v_lex_f_i);
@@ -62665,49 +62985,49 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
     }
     __pyx_L24:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2082
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2102
  *             if nt[0][1] == lex_f_i:
  *                 lex_f_i += (nt[0][2] - nt[0][1]) + 1
  *             if nt[-1][2] == lex_f_j:             # <<<<<<<<<<<<<<
  *                 lex_f_j -= (nt[-1][2] - nt[-1][1]) + 1
  * 
  */
-    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2082; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2082; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_v_lex_f_j, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2082; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_v_lex_f_j, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_13 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_13 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2082; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_13 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_13 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     if (__pyx_t_13) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2083
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2103
  *                 lex_f_i += (nt[0][2] - nt[0][1]) + 1
  *             if nt[-1][2] == lex_f_j:
  *                 lex_f_j -= (nt[-1][2] - nt[-1][1]) + 1             # <<<<<<<<<<<<<<
  * 
  *         # Create rule (f_phrase, e_phrase, links, f_link_min, f_link_max)
  */
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2083; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2083; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2083; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2083; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2083; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_3 = PyNumber_Add(__pyx_t_1, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2083; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyNumber_Add(__pyx_t_1, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_1 = PyNumber_InPlaceSubtract(__pyx_v_lex_f_j, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2083; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyNumber_InPlaceSubtract(__pyx_v_lex_f_j, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
       __Pyx_DECREF(__pyx_v_lex_f_j);
@@ -62720,63 +63040,63 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
   }
   __pyx_L23:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2086
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2106
  * 
  *         # Create rule (f_phrase, e_phrase, links, f_link_min, f_link_max)
  *         f = Phrase(f_sym)             # <<<<<<<<<<<<<<
  *         e = Phrase(e_sym)
  *         a = tuple(self.alignment.link(i, j) for (i, j) in links)
  */
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2086; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(((PyObject *)__pyx_v_f_sym));
   PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_v_f_sym));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_f_sym));
-  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2086; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
   __pyx_v_f = ((struct __pyx_obj_3_sa_Phrase *)__pyx_t_3);
   __pyx_t_3 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2087
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2107
  *         # Create rule (f_phrase, e_phrase, links, f_link_min, f_link_max)
  *         f = Phrase(f_sym)
  *         e = Phrase(e_sym)             # <<<<<<<<<<<<<<
  *         a = tuple(self.alignment.link(i, j) for (i, j) in links)
  *         return (f, e, a, lex_f_i, lex_f_j)
  */
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2087; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_INCREF(((PyObject *)__pyx_v_e_sym));
   PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_v_e_sym));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_e_sym));
-  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2087; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
   __pyx_v_e = ((struct __pyx_obj_3_sa_Phrase *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2088
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2108
  *         f = Phrase(f_sym)
  *         e = Phrase(e_sym)
  *         a = tuple(self.alignment.link(i, j) for (i, j) in links)             # <<<<<<<<<<<<<<
  *         return (f, e, a, lex_f_i, lex_f_j)
  * 
  */
-  __pyx_t_1 = __pyx_pf_3_sa_23HieroCachingRuleFactory_9form_rule_2genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2088; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __pyx_pf_3_sa_23HieroCachingRuleFactory_9form_rule_2genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2088; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_1);
   __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2088; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
   __pyx_v_a = ((PyObject*)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2089
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2109
  *         e = Phrase(e_sym)
  *         a = tuple(self.alignment.link(i, j) for (i, j) in links)
  *         return (f, e, a, lex_f_i, lex_f_j)             # <<<<<<<<<<<<<<
@@ -62784,7 +63104,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
  *     # Rule string from rule
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2089; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(((PyObject *)__pyx_v_f));
   PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_v_f));
@@ -62869,16 +63189,16 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_30fmt_rule(PyObject *__
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__e)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("fmt_rule", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2092; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("fmt_rule", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2112; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__a)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("fmt_rule", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2092; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("fmt_rule", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2112; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "fmt_rule") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2092; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "fmt_rule") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2112; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
       goto __pyx_L5_argtuple_error;
@@ -62893,7 +63213,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_30fmt_rule(PyObject *__
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("fmt_rule", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2092; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("fmt_rule", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2112; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.fmt_rule", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -62905,7 +63225,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_30fmt_rule(PyObject *__
 }
 static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_8fmt_rule_2generator16(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value); /* proto */
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2093
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2113
  *     # Rule string from rule
  *     def fmt_rule(self, f, e, a):
  *         a_str = ' '.join('{0}-{1}'.format(*self.alignment.unlink(packed)) for packed in a)             # <<<<<<<<<<<<<<
@@ -62931,7 +63251,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8fmt_rule_genexpr(PyObj
   __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_outer_scope));
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_outer_scope);
   {
-    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_23HieroCachingRuleFactory_8fmt_rule_2generator16, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_23HieroCachingRuleFactory_8fmt_rule_2generator16, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_cur_scope);
     __Pyx_RefNannyFinishContext();
     return (PyObject *) gen;
@@ -62970,13 +63290,13 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_8fmt_rule_2generator16(
     return NULL;
   }
   __pyx_L3_first_run:;
-  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_a)) { __Pyx_RaiseClosureNameError("a"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_a)) { __Pyx_RaiseClosureNameError("a"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
   if (PyList_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_a) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_a)) {
     __pyx_t_1 = __pyx_cur_scope->__pyx_outer_scope->__pyx_v_a; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
     __pyx_t_3 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_a); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_a); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -62984,23 +63304,23 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_8fmt_rule_2generator16(
     if (!__pyx_t_3 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_3 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_4 = __pyx_t_3(__pyx_t_1);
       if (unlikely(!__pyx_t_4)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -63011,24 +63331,24 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_8fmt_rule_2generator16(
     __Pyx_GIVEREF(__pyx_t_4);
     __pyx_cur_scope->__pyx_v_packed = __pyx_t_4;
     __pyx_t_4 = 0;
-    __pyx_t_4 = PyObject_GetAttr(((PyObject *)__pyx_kp_s_137), __pyx_n_s__format); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_GetAttr(((PyObject *)__pyx_kp_s_137), __pyx_n_s__format); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_self)) { __Pyx_RaiseClosureNameError("self"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-    __pyx_t_5 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_outer_scope->__pyx_v_self->alignment), __pyx_n_s__unlink); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_self)) { __Pyx_RaiseClosureNameError("self"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+    __pyx_t_5 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_outer_scope->__pyx_v_self->alignment), __pyx_n_s__unlink); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_INCREF(__pyx_cur_scope->__pyx_v_packed);
     PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_cur_scope->__pyx_v_packed);
     __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_packed);
-    __pyx_t_7 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_7);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
-    __pyx_t_6 = PySequence_Tuple(__pyx_t_7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PySequence_Tuple(__pyx_t_7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(((PyObject *)__pyx_t_6));
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-    __pyx_t_7 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_7);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
@@ -63049,7 +63369,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_8fmt_rule_2generator16(
     __Pyx_XGOTREF(__pyx_t_1);
     __pyx_t_2 = __pyx_cur_scope->__pyx_t_1;
     __pyx_t_3 = __pyx_cur_scope->__pyx_t_2;
-    if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyErr_SetNone(PyExc_StopIteration);
@@ -63069,7 +63389,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_8fmt_rule_2generator16(
   return NULL;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2092
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2112
  * 
  *     # Rule string from rule
  *     def fmt_rule(self, f, e, a):             # <<<<<<<<<<<<<<
@@ -63102,30 +63422,30 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_29fmt_rule(struct __pyx
   __Pyx_INCREF(__pyx_cur_scope->__pyx_v_a);
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_a);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2093
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2113
  *     # Rule string from rule
  *     def fmt_rule(self, f, e, a):
  *         a_str = ' '.join('{0}-{1}'.format(*self.alignment.unlink(packed)) for packed in a)             # <<<<<<<<<<<<<<
  *         return '[X] ||| {0} ||| {1} ||| {2}'.format(f, e, a_str)
  * 
  */
-  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_kp_s_67), __pyx_n_s__join); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_kp_s_67), __pyx_n_s__join); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __pyx_pf_3_sa_23HieroCachingRuleFactory_8fmt_rule_genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __pyx_pf_3_sa_23HieroCachingRuleFactory_8fmt_rule_genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
   __Pyx_GIVEREF(__pyx_t_2);
   __pyx_t_2 = 0;
-  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
   __pyx_v_a_str = __pyx_t_2;
   __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2094
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2114
  *     def fmt_rule(self, f, e, a):
  *         a_str = ' '.join('{0}-{1}'.format(*self.alignment.unlink(packed)) for packed in a)
  *         return '[X] ||| {0} ||| {1} ||| {2}'.format(f, e, a_str)             # <<<<<<<<<<<<<<
@@ -63133,9 +63453,9 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_29fmt_rule(struct __pyx
  *     # Debugging
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = PyObject_GetAttr(((PyObject *)__pyx_kp_s_138), __pyx_n_s__format); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2094; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_GetAttr(((PyObject *)__pyx_kp_s_138), __pyx_n_s__format); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2094; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_INCREF(__pyx_v_f);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_f);
@@ -63146,7 +63466,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_29fmt_rule(struct __pyx
   __Pyx_INCREF(__pyx_v_a_str);
   PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_v_a_str);
   __Pyx_GIVEREF(__pyx_v_a_str);
-  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2094; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
@@ -63181,7 +63501,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_32dump_online_stats(PyO
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2097
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2117
  * 
  *     # Debugging
  *     def dump_online_stats(self):             # <<<<<<<<<<<<<<
@@ -63193,7 +63513,6 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
   PyObject *__pyx_v_w = NULL;
   PyObject *__pyx_v_w2 = NULL;
   PyObject *__pyx_v_ph = NULL;
-  PyObject *__pyx_v_ph2 = NULL;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -63207,82 +63526,80 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
   Py_ssize_t __pyx_t_9;
   PyObject *(*__pyx_t_10)(PyObject *);
   PyObject *__pyx_t_11 = NULL;
-  PyObject *__pyx_t_12 = NULL;
-  PyObject *__pyx_t_13 = NULL;
   int __pyx_lineno = 0;
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("dump_online_stats", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2098
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2118
  *     # Debugging
  *     def dump_online_stats(self):
  *         logger.info('------------------------------')             # <<<<<<<<<<<<<<
  *         logger.info('         Online Stats         ')
  *         logger.info('------------------------------')
  */
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2098; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2098; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_k_tuple_140), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2098; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_k_tuple_140), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2099
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2119
  *     def dump_online_stats(self):
  *         logger.info('------------------------------')
  *         logger.info('         Online Stats         ')             # <<<<<<<<<<<<<<
  *         logger.info('------------------------------')
  *         logger.info('f')
  */
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2099; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2099; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_k_tuple_142), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2099; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_k_tuple_142), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2100
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2120
  *         logger.info('------------------------------')
  *         logger.info('         Online Stats         ')
  *         logger.info('------------------------------')             # <<<<<<<<<<<<<<
  *         logger.info('f')
  *         for w in self.bilex_f:
  */
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_k_tuple_143), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_k_tuple_143), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2101
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2121
  *         logger.info('         Online Stats         ')
  *         logger.info('------------------------------')
  *         logger.info('f')             # <<<<<<<<<<<<<<
  *         for w in self.bilex_f:
  *             logger.info(sym_tostring(w) + ' : ' + str(self.bilex_f[w]))
  */
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_k_tuple_144), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_k_tuple_144), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2102
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2122
  *         logger.info('------------------------------')
  *         logger.info('f')
  *         for w in self.bilex_f:             # <<<<<<<<<<<<<<
@@ -63293,7 +63610,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
     __pyx_t_1 = __pyx_v_self->bilex_f; __Pyx_INCREF(__pyx_t_1); __pyx_t_3 = 0;
     __pyx_t_4 = NULL;
   } else {
-    __pyx_t_3 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_self->bilex_f); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_self->bilex_f); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_4 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -63301,23 +63618,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
     if (!__pyx_t_4 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_2 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_2); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_2); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_4 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_2); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_2); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_2 = __pyx_t_4(__pyx_t_1);
       if (unlikely(!__pyx_t_2)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -63327,44 +63644,44 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
     __pyx_v_w = __pyx_t_2;
     __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2103
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2123
  *         logger.info('f')
  *         for w in self.bilex_f:
  *             logger.info(sym_tostring(w) + ' : ' + str(self.bilex_f[w]))             # <<<<<<<<<<<<<<
  *         logger.info('e')
  *         for w in self.bilex_e:
  */
-    __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_5 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__info); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__info); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_w); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_2 = PyBytes_FromString(__pyx_f_3_sa_sym_tostring(__pyx_t_6)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_w); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyBytes_FromString(__pyx_f_3_sa_sym_tostring(__pyx_t_6)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(((PyObject *)__pyx_t_2));
-    __pyx_t_7 = PyNumber_Add(((PyObject *)__pyx_t_2), ((PyObject *)__pyx_kp_s_145)); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyNumber_Add(((PyObject *)__pyx_t_2), ((PyObject *)__pyx_kp_s_145)); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_7);
     __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
-    __pyx_t_2 = PyObject_GetItem(__pyx_v_self->bilex_f, __pyx_v_w); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyObject_GetItem(__pyx_v_self->bilex_f, __pyx_v_w); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
     PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_2);
     __Pyx_GIVEREF(__pyx_t_2);
     __pyx_t_2 = 0;
-    __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(((PyObject *)__pyx_t_8)); __pyx_t_8 = 0;
-    __pyx_t_8 = PyNumber_Add(__pyx_t_7, __pyx_t_2); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyNumber_Add(__pyx_t_7, __pyx_t_2); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_8);
     __Pyx_GIVEREF(__pyx_t_8);
     __pyx_t_8 = 0;
-    __pyx_t_8 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
@@ -63372,24 +63689,24 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2104
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2124
  *         for w in self.bilex_f:
  *             logger.info(sym_tostring(w) + ' : ' + str(self.bilex_f[w]))
  *         logger.info('e')             # <<<<<<<<<<<<<<
  *         for w in self.bilex_e:
  *             logger.info(sym_tostring(w) + ' : ' + str(self.bilex_e[w]))
  */
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_8 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_8 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_8);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_k_tuple_146), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_k_tuple_146), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2105
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2125
  *             logger.info(sym_tostring(w) + ' : ' + str(self.bilex_f[w]))
  *         logger.info('e')
  *         for w in self.bilex_e:             # <<<<<<<<<<<<<<
@@ -63400,7 +63717,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
     __pyx_t_1 = __pyx_v_self->bilex_e; __Pyx_INCREF(__pyx_t_1); __pyx_t_3 = 0;
     __pyx_t_4 = NULL;
   } else {
-    __pyx_t_3 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_self->bilex_e); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_self->bilex_e); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_4 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -63408,23 +63725,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
     if (!__pyx_t_4 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_8 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_8); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_8); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_8 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_4 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_8 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_8); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_8); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_8 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_8 = __pyx_t_4(__pyx_t_1);
       if (unlikely(!__pyx_t_8)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -63434,44 +63751,44 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
     __pyx_v_w = __pyx_t_8;
     __pyx_t_8 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2106
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2126
  *         logger.info('e')
  *         for w in self.bilex_e:
  *             logger.info(sym_tostring(w) + ' : ' + str(self.bilex_e[w]))             # <<<<<<<<<<<<<<
  *         logger.info('fe')
  *         for w in self.bilex_fe:
  */
-    __pyx_t_8 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
-    __pyx_t_2 = PyObject_GetAttr(__pyx_t_8, __pyx_n_s__info); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyObject_GetAttr(__pyx_t_8, __pyx_n_s__info); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-    __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_w); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_8 = PyBytes_FromString(__pyx_f_3_sa_sym_tostring(__pyx_t_6)); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_w); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyBytes_FromString(__pyx_f_3_sa_sym_tostring(__pyx_t_6)); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(((PyObject *)__pyx_t_8));
-    __pyx_t_5 = PyNumber_Add(((PyObject *)__pyx_t_8), ((PyObject *)__pyx_kp_s_145)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyNumber_Add(((PyObject *)__pyx_t_8), ((PyObject *)__pyx_kp_s_145)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(((PyObject *)__pyx_t_8)); __pyx_t_8 = 0;
-    __pyx_t_8 = PyObject_GetItem(__pyx_v_self->bilex_e, __pyx_v_w); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyObject_GetItem(__pyx_v_self->bilex_e, __pyx_v_w); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
-    __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_7);
     PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_8);
     __Pyx_GIVEREF(__pyx_t_8);
     __pyx_t_8 = 0;
-    __pyx_t_8 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_7), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_7), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
     __Pyx_DECREF(((PyObject *)__pyx_t_7)); __pyx_t_7 = 0;
-    __pyx_t_7 = PyNumber_Add(__pyx_t_5, __pyx_t_8); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyNumber_Add(__pyx_t_5, __pyx_t_8); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_7);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-    __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
     PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7);
     __Pyx_GIVEREF(__pyx_t_7);
     __pyx_t_7 = 0;
-    __pyx_t_7 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_7);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_8)); __pyx_t_8 = 0;
@@ -63479,24 +63796,24 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2107
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2127
  *         for w in self.bilex_e:
  *             logger.info(sym_tostring(w) + ' : ' + str(self.bilex_e[w]))
  *         logger.info('fe')             # <<<<<<<<<<<<<<
  *         for w in self.bilex_fe:
  *             for w2 in self.bilex_fe[w]:
  */
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_7 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_7 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_7);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_t_7, ((PyObject *)__pyx_k_tuple_147), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(__pyx_t_7, ((PyObject *)__pyx_k_tuple_147), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2108
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2128
  *             logger.info(sym_tostring(w) + ' : ' + str(self.bilex_e[w]))
  *         logger.info('fe')
  *         for w in self.bilex_fe:             # <<<<<<<<<<<<<<
@@ -63507,7 +63824,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
     __pyx_t_1 = __pyx_v_self->bilex_fe; __Pyx_INCREF(__pyx_t_1); __pyx_t_3 = 0;
     __pyx_t_4 = NULL;
   } else {
-    __pyx_t_3 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_self->bilex_fe); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_self->bilex_fe); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_4 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -63515,23 +63832,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
     if (!__pyx_t_4 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_7 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_7); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_7); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_7 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_4 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_7); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_7); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_7 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_7 = __pyx_t_4(__pyx_t_1);
       if (unlikely(!__pyx_t_7)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -63541,20 +63858,20 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
     __pyx_v_w = __pyx_t_7;
     __pyx_t_7 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2109
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2129
  *         logger.info('fe')
  *         for w in self.bilex_fe:
  *             for w2 in self.bilex_fe[w]:             # <<<<<<<<<<<<<<
  *                 logger.info(sym_tostring(w) + ' : ' + sym_tostring(w2) + ' : ' + str(self.bilex_fe[w][w2]))
  *         logger.info('F')
  */
-    __pyx_t_7 = PyObject_GetItem(__pyx_v_self->bilex_fe, __pyx_v_w); if (!__pyx_t_7) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyObject_GetItem(__pyx_v_self->bilex_fe, __pyx_v_w); if (!__pyx_t_7) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_7);
     if (PyList_CheckExact(__pyx_t_7) || PyTuple_CheckExact(__pyx_t_7)) {
       __pyx_t_8 = __pyx_t_7; __Pyx_INCREF(__pyx_t_8); __pyx_t_9 = 0;
       __pyx_t_10 = NULL;
     } else {
-      __pyx_t_9 = -1; __pyx_t_8 = PyObject_GetIter(__pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_9 = -1; __pyx_t_8 = PyObject_GetIter(__pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __pyx_t_10 = Py_TYPE(__pyx_t_8)->tp_iternext;
     }
@@ -63563,23 +63880,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
       if (!__pyx_t_10 && PyList_CheckExact(__pyx_t_8)) {
         if (__pyx_t_9 >= PyList_GET_SIZE(__pyx_t_8)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_7 = PyList_GET_ITEM(__pyx_t_8, __pyx_t_9); __Pyx_INCREF(__pyx_t_7); __pyx_t_9++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PyList_GET_ITEM(__pyx_t_8, __pyx_t_9); __Pyx_INCREF(__pyx_t_7); __pyx_t_9++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_7 = PySequence_ITEM(__pyx_t_8, __pyx_t_9); __pyx_t_9++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PySequence_ITEM(__pyx_t_8, __pyx_t_9); __pyx_t_9++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else if (!__pyx_t_10 && PyTuple_CheckExact(__pyx_t_8)) {
         if (__pyx_t_9 >= PyTuple_GET_SIZE(__pyx_t_8)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_8, __pyx_t_9); __Pyx_INCREF(__pyx_t_7); __pyx_t_9++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_8, __pyx_t_9); __Pyx_INCREF(__pyx_t_7); __pyx_t_9++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_7 = PySequence_ITEM(__pyx_t_8, __pyx_t_9); __pyx_t_9++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PySequence_ITEM(__pyx_t_8, __pyx_t_9); __pyx_t_9++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else {
         __pyx_t_7 = __pyx_t_10(__pyx_t_8);
         if (unlikely(!__pyx_t_7)) {
           if (PyErr_Occurred()) {
             if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           }
           break;
         }
@@ -63589,57 +63906,57 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
       __pyx_v_w2 = __pyx_t_7;
       __pyx_t_7 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2110
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2130
  *         for w in self.bilex_fe:
  *             for w2 in self.bilex_fe[w]:
  *                 logger.info(sym_tostring(w) + ' : ' + sym_tostring(w2) + ' : ' + str(self.bilex_fe[w][w2]))             # <<<<<<<<<<<<<<
  *         logger.info('F')
  *         for ph in self.phrases_f:
  */
-      __pyx_t_7 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_7);
-      __pyx_t_2 = PyObject_GetAttr(__pyx_t_7, __pyx_n_s__info); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_GetAttr(__pyx_t_7, __pyx_n_s__info); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-      __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_w); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_7 = PyBytes_FromString(__pyx_f_3_sa_sym_tostring(__pyx_t_6)); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_w); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyBytes_FromString(__pyx_f_3_sa_sym_tostring(__pyx_t_6)); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(((PyObject *)__pyx_t_7));
-      __pyx_t_5 = PyNumber_Add(((PyObject *)__pyx_t_7), ((PyObject *)__pyx_kp_s_145)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyNumber_Add(((PyObject *)__pyx_t_7), ((PyObject *)__pyx_kp_s_145)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_DECREF(((PyObject *)__pyx_t_7)); __pyx_t_7 = 0;
-      __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_w2); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_7 = PyBytes_FromString(__pyx_f_3_sa_sym_tostring(__pyx_t_6)); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_w2); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyBytes_FromString(__pyx_f_3_sa_sym_tostring(__pyx_t_6)); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(((PyObject *)__pyx_t_7));
-      __pyx_t_11 = PyNumber_Add(__pyx_t_5, ((PyObject *)__pyx_t_7)); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_11 = PyNumber_Add(__pyx_t_5, ((PyObject *)__pyx_t_7)); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_11);
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_7)); __pyx_t_7 = 0;
-      __pyx_t_7 = PyNumber_Add(__pyx_t_11, ((PyObject *)__pyx_kp_s_145)); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyNumber_Add(__pyx_t_11, ((PyObject *)__pyx_kp_s_145)); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_7);
       __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-      __pyx_t_11 = PyObject_GetItem(__pyx_v_self->bilex_fe, __pyx_v_w); if (!__pyx_t_11) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_11 = PyObject_GetItem(__pyx_v_self->bilex_fe, __pyx_v_w); if (!__pyx_t_11) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_11);
-      __pyx_t_5 = PyObject_GetItem(__pyx_t_11, __pyx_v_w2); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyObject_GetItem(__pyx_t_11, __pyx_v_w2); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-      __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_11);
       PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_5);
       __Pyx_GIVEREF(__pyx_t_5);
       __pyx_t_5 = 0;
-      __pyx_t_5 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_11), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_11), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_DECREF(((PyObject *)__pyx_t_11)); __pyx_t_11 = 0;
-      __pyx_t_11 = PyNumber_Add(__pyx_t_7, __pyx_t_5); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_11 = PyNumber_Add(__pyx_t_7, __pyx_t_5); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_11);
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
       PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_11);
       __Pyx_GIVEREF(__pyx_t_11);
       __pyx_t_11 = 0;
-      __pyx_t_11 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_11 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_11);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
@@ -63649,24 +63966,24 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2111
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2131
  *             for w2 in self.bilex_fe[w]:
  *                 logger.info(sym_tostring(w) + ' : ' + sym_tostring(w2) + ' : ' + str(self.bilex_fe[w][w2]))
  *         logger.info('F')             # <<<<<<<<<<<<<<
  *         for ph in self.phrases_f:
  *             logger.info(str(ph) + ' ||| ' + str(self.phrases_f[ph]))
  */
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_8 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_8 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_8);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_k_tuple_148), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_k_tuple_148), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2112
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2132
  *                 logger.info(sym_tostring(w) + ' : ' + sym_tostring(w2) + ' : ' + str(self.bilex_fe[w][w2]))
  *         logger.info('F')
  *         for ph in self.phrases_f:             # <<<<<<<<<<<<<<
@@ -63677,7 +63994,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
     __pyx_t_1 = __pyx_v_self->phrases_f; __Pyx_INCREF(__pyx_t_1); __pyx_t_3 = 0;
     __pyx_t_4 = NULL;
   } else {
-    __pyx_t_3 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_self->phrases_f); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_self->phrases_f); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_4 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -63685,23 +64002,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
     if (!__pyx_t_4 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_8 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_8); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_8); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_8 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_4 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_8 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_8); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_8); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_8 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_8 = __pyx_t_4(__pyx_t_1);
       if (unlikely(!__pyx_t_8)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -63711,49 +64028,49 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
     __pyx_v_ph = __pyx_t_8;
     __pyx_t_8 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2113
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2133
  *         logger.info('F')
  *         for ph in self.phrases_f:
  *             logger.info(str(ph) + ' ||| ' + str(self.phrases_f[ph]))             # <<<<<<<<<<<<<<
  *         logger.info('E')
  *         for ph in self.phrases_e:
  */
-    __pyx_t_8 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
-    __pyx_t_11 = PyObject_GetAttr(__pyx_t_8, __pyx_n_s__info); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_11 = PyObject_GetAttr(__pyx_t_8, __pyx_n_s__info); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_11);
     __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-    __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
     __Pyx_INCREF(__pyx_v_ph);
     PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_ph);
     __Pyx_GIVEREF(__pyx_v_ph);
-    __pyx_t_5 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(((PyObject *)__pyx_t_8)); __pyx_t_8 = 0;
-    __pyx_t_8 = PyNumber_Add(__pyx_t_5, ((PyObject *)__pyx_kp_s_18)); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyNumber_Add(__pyx_t_5, ((PyObject *)__pyx_kp_s_18)); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __pyx_t_5 = PyObject_GetItem(__pyx_v_self->phrases_f, __pyx_v_ph); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyObject_GetItem(__pyx_v_self->phrases_f, __pyx_v_ph); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_5);
     __Pyx_GIVEREF(__pyx_t_5);
     __pyx_t_5 = 0;
-    __pyx_t_5 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
-    __pyx_t_2 = PyNumber_Add(__pyx_t_8, __pyx_t_5); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyNumber_Add(__pyx_t_8, __pyx_t_5); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2133; __pyx_clineno = __LINE__; goto __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_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2);
     __Pyx_GIVEREF(__pyx_t_2);
     __pyx_t_2 = 0;
-    __pyx_t_2 = PyObject_Call(__pyx_t_11, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyObject_Call(__pyx_t_11, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
@@ -63761,24 +64078,24 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2114
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2134
  *         for ph in self.phrases_f:
  *             logger.info(str(ph) + ' ||| ' + str(self.phrases_f[ph]))
  *         logger.info('E')             # <<<<<<<<<<<<<<
  *         for ph in self.phrases_e:
  *             logger.info(str(ph) + ' ||| ' + str(self.phrases_e[ph]))
  */
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_k_tuple_149), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_k_tuple_149), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2115
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2135
  *             logger.info(str(ph) + ' ||| ' + str(self.phrases_f[ph]))
  *         logger.info('E')
  *         for ph in self.phrases_e:             # <<<<<<<<<<<<<<
@@ -63789,7 +64106,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
     __pyx_t_1 = __pyx_v_self->phrases_e; __Pyx_INCREF(__pyx_t_1); __pyx_t_3 = 0;
     __pyx_t_4 = NULL;
   } else {
-    __pyx_t_3 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_self->phrases_e); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_self->phrases_e); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_4 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -63797,23 +64114,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
     if (!__pyx_t_4 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_2 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_2); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_2); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_4 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_2); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_2); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_2 = __pyx_t_4(__pyx_t_1);
       if (unlikely(!__pyx_t_2)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -63823,49 +64140,49 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
     __pyx_v_ph = __pyx_t_2;
     __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2116
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2136
  *         logger.info('E')
  *         for ph in self.phrases_e:
  *             logger.info(str(ph) + ' ||| ' + str(self.phrases_e[ph]))             # <<<<<<<<<<<<<<
  *         logger.info('FE')
- *         for ph in self.phrases_fe:
+ *         self.dump_online_rules()
  */
-    __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_5 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__info); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__info); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_INCREF(__pyx_v_ph);
     PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_ph);
     __Pyx_GIVEREF(__pyx_v_ph);
-    __pyx_t_11 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_11 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_11);
     __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
-    __pyx_t_2 = PyNumber_Add(__pyx_t_11, ((PyObject *)__pyx_kp_s_18)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyNumber_Add(__pyx_t_11, ((PyObject *)__pyx_kp_s_18)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-    __pyx_t_11 = PyObject_GetItem(__pyx_v_self->phrases_e, __pyx_v_ph); if (!__pyx_t_11) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_11 = PyObject_GetItem(__pyx_v_self->phrases_e, __pyx_v_ph); if (!__pyx_t_11) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_11);
-    __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
     PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_11);
     __Pyx_GIVEREF(__pyx_t_11);
     __pyx_t_11 = 0;
-    __pyx_t_11 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_11 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_11);
     __Pyx_DECREF(((PyObject *)__pyx_t_8)); __pyx_t_8 = 0;
-    __pyx_t_8 = PyNumber_Add(__pyx_t_2, __pyx_t_11); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyNumber_Add(__pyx_t_2, __pyx_t_11); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-    __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_11);
     PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_8);
     __Pyx_GIVEREF(__pyx_t_8);
     __pyx_t_8 = 0;
-    __pyx_t_8 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_11), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_11), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_11)); __pyx_t_11 = 0;
@@ -63873,198 +64190,273 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2117
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2137
  *         for ph in self.phrases_e:
  *             logger.info(str(ph) + ' ||| ' + str(self.phrases_e[ph]))
  *         logger.info('FE')             # <<<<<<<<<<<<<<
- *         for ph in self.phrases_fe:
- *             for ph2 in self.phrases_fe[ph]:
+ *         self.dump_online_rules()
+ * 
  */
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_8 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_8 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_8);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_k_tuple_150), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_k_tuple_150), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2118
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2138
  *             logger.info(str(ph) + ' ||| ' + str(self.phrases_e[ph]))
  *         logger.info('FE')
+ *         self.dump_online_rules()             # <<<<<<<<<<<<<<
+ * 
+ *     def dump_online_rules(self):
+ */
+  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__dump_online_rules); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_8 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_XDECREF(__pyx_t_11);
+  __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.dump_online_stats", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_w);
+  __Pyx_XDECREF(__pyx_v_w2);
+  __Pyx_XDECREF(__pyx_v_ph);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_34dump_online_rules(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_34dump_online_rules(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("dump_online_rules (wrapper)", 0);
+  __pyx_r = __pyx_pf_3_sa_23HieroCachingRuleFactory_33dump_online_rules(((struct __pyx_obj_3_sa_HieroCachingRuleFactory *)__pyx_v_self));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2140
+ *         self.dump_online_rules()
+ * 
+ *     def dump_online_rules(self):             # <<<<<<<<<<<<<<
+ *         for ph in self.phrases_fe:
+ *             for ph2 in self.phrases_fe[ph]:
+ */
+
+static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_33dump_online_rules(struct __pyx_obj_3_sa_HieroCachingRuleFactory *__pyx_v_self) {
+  PyObject *__pyx_v_ph = NULL;
+  PyObject *__pyx_v_ph2 = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  Py_ssize_t __pyx_t_2;
+  PyObject *(*__pyx_t_3)(PyObject *);
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  Py_ssize_t __pyx_t_6;
+  PyObject *(*__pyx_t_7)(PyObject *);
+  PyObject *__pyx_t_8 = NULL;
+  PyObject *__pyx_t_9 = NULL;
+  PyObject *__pyx_t_10 = NULL;
+  PyObject *__pyx_t_11 = NULL;
+  PyObject *__pyx_t_12 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("dump_online_rules", 0);
+
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2141
+ * 
+ *     def dump_online_rules(self):
  *         for ph in self.phrases_fe:             # <<<<<<<<<<<<<<
  *             for ph2 in self.phrases_fe[ph]:
  *                 logger.info(self.fmt_rule(str(ph), str(ph2), self.phrases_al[ph][ph2]) + ' ||| ' + str(self.phrases_fe[ph][ph2]))
  */
   if (PyList_CheckExact(__pyx_v_self->phrases_fe) || PyTuple_CheckExact(__pyx_v_self->phrases_fe)) {
-    __pyx_t_1 = __pyx_v_self->phrases_fe; __Pyx_INCREF(__pyx_t_1); __pyx_t_3 = 0;
-    __pyx_t_4 = NULL;
+    __pyx_t_1 = __pyx_v_self->phrases_fe; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
+    __pyx_t_3 = NULL;
   } else {
-    __pyx_t_3 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_self->phrases_fe); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_self->phrases_fe); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_4 = Py_TYPE(__pyx_t_1)->tp_iternext;
+    __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
   for (;;) {
-    if (!__pyx_t_4 && PyList_CheckExact(__pyx_t_1)) {
-      if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_1)) break;
+    if (!__pyx_t_3 && PyList_CheckExact(__pyx_t_1)) {
+      if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_8 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_8); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2118; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 2141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_8 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
-    } else if (!__pyx_t_4 && PyTuple_CheckExact(__pyx_t_1)) {
-      if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+    } else if (!__pyx_t_3 && PyTuple_CheckExact(__pyx_t_1)) {
+      if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_8 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_8); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2118; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 2141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_8 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
-      __pyx_t_8 = __pyx_t_4(__pyx_t_1);
-      if (unlikely(!__pyx_t_8)) {
+      __pyx_t_4 = __pyx_t_3(__pyx_t_1);
+      if (unlikely(!__pyx_t_4)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
-      __Pyx_GOTREF(__pyx_t_8);
+      __Pyx_GOTREF(__pyx_t_4);
     }
     __Pyx_XDECREF(__pyx_v_ph);
-    __pyx_v_ph = __pyx_t_8;
-    __pyx_t_8 = 0;
+    __pyx_v_ph = __pyx_t_4;
+    __pyx_t_4 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2119
- *         logger.info('FE')
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2142
+ *     def dump_online_rules(self):
  *         for ph in self.phrases_fe:
  *             for ph2 in self.phrases_fe[ph]:             # <<<<<<<<<<<<<<
  *                 logger.info(self.fmt_rule(str(ph), str(ph2), self.phrases_al[ph][ph2]) + ' ||| ' + str(self.phrases_fe[ph][ph2]))
  * 
  */
-    __pyx_t_8 = PyObject_GetItem(__pyx_v_self->phrases_fe, __pyx_v_ph); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_8);
-    if (PyList_CheckExact(__pyx_t_8) || PyTuple_CheckExact(__pyx_t_8)) {
-      __pyx_t_11 = __pyx_t_8; __Pyx_INCREF(__pyx_t_11); __pyx_t_9 = 0;
-      __pyx_t_10 = NULL;
+    __pyx_t_4 = PyObject_GetItem(__pyx_v_self->phrases_fe, __pyx_v_ph); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    if (PyList_CheckExact(__pyx_t_4) || PyTuple_CheckExact(__pyx_t_4)) {
+      __pyx_t_5 = __pyx_t_4; __Pyx_INCREF(__pyx_t_5); __pyx_t_6 = 0;
+      __pyx_t_7 = NULL;
     } else {
-      __pyx_t_9 = -1; __pyx_t_11 = PyObject_GetIter(__pyx_t_8); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_11);
-      __pyx_t_10 = Py_TYPE(__pyx_t_11)->tp_iternext;
+      __pyx_t_6 = -1; __pyx_t_5 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_7 = Py_TYPE(__pyx_t_5)->tp_iternext;
     }
-    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     for (;;) {
-      if (!__pyx_t_10 && PyList_CheckExact(__pyx_t_11)) {
-        if (__pyx_t_9 >= PyList_GET_SIZE(__pyx_t_11)) break;
+      if (!__pyx_t_7 && PyList_CheckExact(__pyx_t_5)) {
+        if (__pyx_t_6 >= PyList_GET_SIZE(__pyx_t_5)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_8 = PyList_GET_ITEM(__pyx_t_11, __pyx_t_9); __Pyx_INCREF(__pyx_t_8); __pyx_t_9++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyList_GET_ITEM(__pyx_t_5, __pyx_t_6); __Pyx_INCREF(__pyx_t_4); __pyx_t_6++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_8 = PySequence_ITEM(__pyx_t_11, __pyx_t_9); __pyx_t_9++; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PySequence_ITEM(__pyx_t_5, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
-      } else if (!__pyx_t_10 && PyTuple_CheckExact(__pyx_t_11)) {
-        if (__pyx_t_9 >= PyTuple_GET_SIZE(__pyx_t_11)) break;
+      } else if (!__pyx_t_7 && PyTuple_CheckExact(__pyx_t_5)) {
+        if (__pyx_t_6 >= PyTuple_GET_SIZE(__pyx_t_5)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_8 = PyTuple_GET_ITEM(__pyx_t_11, __pyx_t_9); __Pyx_INCREF(__pyx_t_8); __pyx_t_9++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_5, __pyx_t_6); __Pyx_INCREF(__pyx_t_4); __pyx_t_6++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_8 = PySequence_ITEM(__pyx_t_11, __pyx_t_9); __pyx_t_9++; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PySequence_ITEM(__pyx_t_5, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else {
-        __pyx_t_8 = __pyx_t_10(__pyx_t_11);
-        if (unlikely(!__pyx_t_8)) {
+        __pyx_t_4 = __pyx_t_7(__pyx_t_5);
+        if (unlikely(!__pyx_t_4)) {
           if (PyErr_Occurred()) {
             if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           }
           break;
         }
-        __Pyx_GOTREF(__pyx_t_8);
+        __Pyx_GOTREF(__pyx_t_4);
       }
       __Pyx_XDECREF(__pyx_v_ph2);
-      __pyx_v_ph2 = __pyx_t_8;
-      __pyx_t_8 = 0;
+      __pyx_v_ph2 = __pyx_t_4;
+      __pyx_t_4 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2120
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2143
  *         for ph in self.phrases_fe:
  *             for ph2 in self.phrases_fe[ph]:
  *                 logger.info(self.fmt_rule(str(ph), str(ph2), self.phrases_al[ph][ph2]) + ' ||| ' + str(self.phrases_fe[ph][ph2]))             # <<<<<<<<<<<<<<
  * 
  *     # Lookup online stats for phrase pair (f, e).  Return None if no match.
  */
-      __pyx_t_8 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_8);
-      __pyx_t_5 = PyObject_GetAttr(__pyx_t_8, __pyx_n_s__info); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-      __pyx_t_8 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__fmt_rule); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_8 = PyObject_GetAttr(__pyx_t_4, __pyx_n_s__info); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
-      __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_4 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__fmt_rule); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
       __Pyx_INCREF(__pyx_v_ph);
-      PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_ph);
+      PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_v_ph);
       __Pyx_GIVEREF(__pyx_v_ph);
-      __pyx_t_7 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_7);
-      __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
-      __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_10 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
+      __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
       __Pyx_INCREF(__pyx_v_ph2);
-      PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_ph2);
+      PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_v_ph2);
       __Pyx_GIVEREF(__pyx_v_ph2);
-      __pyx_t_12 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_11 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_11);
+      __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
+      __pyx_t_9 = PyObject_GetItem(__pyx_v_self->phrases_al, __pyx_v_ph); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+      __pyx_t_12 = PyObject_GetItem(__pyx_t_9, __pyx_v_ph2); if (!__pyx_t_12) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_12);
-      __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
-      __pyx_t_2 = PyObject_GetItem(__pyx_v_self->phrases_al, __pyx_v_ph); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_13 = PyObject_GetItem(__pyx_t_2, __pyx_v_ph2); if (!__pyx_t_13) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_13);
-      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_2);
-      PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_7);
-      __Pyx_GIVEREF(__pyx_t_7);
-      PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_12);
+      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+      __pyx_t_9 = PyTuple_New(3); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+      PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_10);
+      __Pyx_GIVEREF(__pyx_t_10);
+      PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_t_11);
+      __Pyx_GIVEREF(__pyx_t_11);
+      PyTuple_SET_ITEM(__pyx_t_9, 2, __pyx_t_12);
       __Pyx_GIVEREF(__pyx_t_12);
-      PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_t_13);
-      __Pyx_GIVEREF(__pyx_t_13);
-      __pyx_t_7 = 0;
+      __pyx_t_10 = 0;
+      __pyx_t_11 = 0;
       __pyx_t_12 = 0;
-      __pyx_t_13 = 0;
-      __pyx_t_13 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_13);
-      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-      __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
-      __pyx_t_2 = PyNumber_Add(__pyx_t_13, ((PyObject *)__pyx_kp_s_18)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_2);
-      __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
-      __pyx_t_13 = PyObject_GetItem(__pyx_v_self->phrases_fe, __pyx_v_ph); if (!__pyx_t_13) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_13);
-      __pyx_t_8 = PyObject_GetItem(__pyx_t_13, __pyx_v_ph2); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_8);
-      __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
-      __pyx_t_13 = PyTuple_New(1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_13);
-      PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_8);
-      __Pyx_GIVEREF(__pyx_t_8);
-      __pyx_t_8 = 0;
-      __pyx_t_8 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_13), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_8);
-      __Pyx_DECREF(((PyObject *)__pyx_t_13)); __pyx_t_13 = 0;
-      __pyx_t_13 = PyNumber_Add(__pyx_t_2, __pyx_t_8); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_13);
-      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __pyx_t_12 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_12);
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
+      __pyx_t_9 = PyNumber_Add(__pyx_t_12, ((PyObject *)__pyx_kp_s_18)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+      __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+      __pyx_t_12 = PyObject_GetItem(__pyx_v_self->phrases_fe, __pyx_v_ph); if (!__pyx_t_12) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_12);
+      __pyx_t_4 = PyObject_GetItem(__pyx_t_12, __pyx_v_ph2); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+      __pyx_t_12 = PyTuple_New(1); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_12);
+      PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_t_4);
+      __Pyx_GIVEREF(__pyx_t_4);
+      __pyx_t_4 = 0;
+      __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_12), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __Pyx_DECREF(((PyObject *)__pyx_t_12)); __pyx_t_12 = 0;
+      __pyx_t_12 = PyNumber_Add(__pyx_t_9, __pyx_t_4); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_12);
+      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_12);
+      __Pyx_GIVEREF(__pyx_t_12);
+      __pyx_t_12 = 0;
+      __pyx_t_12 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_12);
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-      __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_8);
-      PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_13);
-      __Pyx_GIVEREF(__pyx_t_13);
-      __pyx_t_13 = 0;
-      __pyx_t_13 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_13);
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      __Pyx_DECREF(((PyObject *)__pyx_t_8)); __pyx_t_8 = 0;
-      __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+      __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+      __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
     }
-    __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
@@ -64072,18 +64464,16 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
   goto __pyx_L0;
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_7);
   __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_XDECREF(__pyx_t_9);
+  __Pyx_XDECREF(__pyx_t_10);
   __Pyx_XDECREF(__pyx_t_11);
   __Pyx_XDECREF(__pyx_t_12);
-  __Pyx_XDECREF(__pyx_t_13);
-  __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.dump_online_stats", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.dump_online_rules", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
-  __Pyx_XDECREF(__pyx_v_w);
-  __Pyx_XDECREF(__pyx_v_w2);
   __Pyx_XDECREF(__pyx_v_ph);
   __Pyx_XDECREF(__pyx_v_ph2);
   __Pyx_XGIVEREF(__pyx_r);
@@ -64092,8 +64482,8 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_34online_ctx_lookup(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_34online_ctx_lookup(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_36online_ctx_lookup(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_36online_ctx_lookup(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_f = 0;
   PyObject *__pyx_v_e = 0;
   PyObject *__pyx_r = 0;
@@ -64119,11 +64509,11 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_34online_ctx_lookup(PyO
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__e)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("online_ctx_lookup", 1, 2, 2, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2124; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("online_ctx_lookup", 1, 2, 2, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2147; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "online_ctx_lookup") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2124; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "online_ctx_lookup") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2147; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -64136,18 +64526,18 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_34online_ctx_lookup(PyO
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("online_ctx_lookup", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2124; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("online_ctx_lookup", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2147; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.online_ctx_lookup", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_3_sa_23HieroCachingRuleFactory_33online_ctx_lookup(((struct __pyx_obj_3_sa_HieroCachingRuleFactory *)__pyx_v_self), __pyx_v_f, __pyx_v_e);
+  __pyx_r = __pyx_pf_3_sa_23HieroCachingRuleFactory_35online_ctx_lookup(((struct __pyx_obj_3_sa_HieroCachingRuleFactory *)__pyx_v_self), __pyx_v_f, __pyx_v_e);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2124
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2147
  *     # Lookup online stats for phrase pair (f, e).  Return None if no match.
  *     # IMPORTANT: use get() to avoid adding items to defaultdict
  *     def online_ctx_lookup(self, f, e):             # <<<<<<<<<<<<<<
@@ -64155,8 +64545,9 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_34online_ctx_lookup(PyO
  *             fcount = self.phrases_f.get(f, 0)
  */
 
-static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_33online_ctx_lookup(struct __pyx_obj_3_sa_HieroCachingRuleFactory *__pyx_v_self, PyObject *__pyx_v_f, PyObject *__pyx_v_e) {
+static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_35online_ctx_lookup(struct __pyx_obj_3_sa_HieroCachingRuleFactory *__pyx_v_self, PyObject *__pyx_v_f, PyObject *__pyx_v_e) {
   PyObject *__pyx_v_fcount = NULL;
+  PyObject *__pyx_v_fsample_count = NULL;
   PyObject *__pyx_v_d = NULL;
   PyObject *__pyx_v_paircount = NULL;
   PyObject *__pyx_r = NULL;
@@ -64171,25 +64562,25 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_33online_ctx_lookup(str
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("online_ctx_lookup", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2125
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2148
  *     # IMPORTANT: use get() to avoid adding items to defaultdict
  *     def online_ctx_lookup(self, f, e):
  *         if self.online:             # <<<<<<<<<<<<<<
  *             fcount = self.phrases_f.get(f, 0)
- *             d = self.phrases_fe.get(f, None)
+ *             fsample_count = self.samples_f.get(f, 0)
  */
   if (__pyx_v_self->online) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2126
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2149
  *     def online_ctx_lookup(self, f, e):
  *         if self.online:
  *             fcount = self.phrases_f.get(f, 0)             # <<<<<<<<<<<<<<
+ *             fsample_count = self.samples_f.get(f, 0)
  *             d = self.phrases_fe.get(f, None)
- *             paircount = d.get(e, 0) if d else 0
  */
-    __pyx_t_1 = PyObject_GetAttr(__pyx_v_self->phrases_f, __pyx_n_s__get); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_GetAttr(__pyx_v_self->phrases_f, __pyx_n_s__get); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_INCREF(__pyx_v_f);
     PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_f);
@@ -64197,146 +64588,134 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_33online_ctx_lookup(str
     __Pyx_INCREF(__pyx_int_0);
     PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_int_0);
     __Pyx_GIVEREF(__pyx_int_0);
-    __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
     __pyx_v_fcount = __pyx_t_3;
     __pyx_t_3 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2127
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2150
  *         if self.online:
  *             fcount = self.phrases_f.get(f, 0)
- *             d = self.phrases_fe.get(f, None)             # <<<<<<<<<<<<<<
+ *             fsample_count = self.samples_f.get(f, 0)             # <<<<<<<<<<<<<<
+ *             d = self.phrases_fe.get(f, None)
  *             paircount = d.get(e, 0) if d else 0
- *             if paircount > 0:
  */
-    __pyx_t_3 = PyObject_GetAttr(__pyx_v_self->phrases_fe, __pyx_n_s__get); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_GetAttr(__pyx_v_self->samples_f, __pyx_n_s__get); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_INCREF(__pyx_v_f);
     PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_f);
     __Pyx_GIVEREF(__pyx_v_f);
-    __Pyx_INCREF(Py_None);
-    PyTuple_SET_ITEM(__pyx_t_2, 1, Py_None);
-    __Pyx_GIVEREF(Py_None);
-    __pyx_t_1 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_INCREF(__pyx_int_0);
+    PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_int_0);
+    __Pyx_GIVEREF(__pyx_int_0);
+    __pyx_t_1 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
-    __pyx_v_d = __pyx_t_1;
+    __pyx_v_fsample_count = __pyx_t_1;
     __pyx_t_1 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2128
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2151
  *             fcount = self.phrases_f.get(f, 0)
+ *             fsample_count = self.samples_f.get(f, 0)
+ *             d = self.phrases_fe.get(f, None)             # <<<<<<<<<<<<<<
+ *             paircount = d.get(e, 0) if d else 0
+ *             return OnlineFeatureContext(fcount, fsample_count, paircount, self.bilex_fe)
+ */
+    __pyx_t_1 = PyObject_GetAttr(__pyx_v_self->phrases_fe, __pyx_n_s__get); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_INCREF(__pyx_v_f);
+    PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_f);
+    __Pyx_GIVEREF(__pyx_v_f);
+    __Pyx_INCREF(Py_None);
+    PyTuple_SET_ITEM(__pyx_t_2, 1, Py_None);
+    __Pyx_GIVEREF(Py_None);
+    __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+    __pyx_v_d = __pyx_t_3;
+    __pyx_t_3 = 0;
+
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2152
+ *             fsample_count = self.samples_f.get(f, 0)
  *             d = self.phrases_fe.get(f, None)
  *             paircount = d.get(e, 0) if d else 0             # <<<<<<<<<<<<<<
- *             if paircount > 0:
- *                 print 'Online support:', f, '|||', e
+ *             return OnlineFeatureContext(fcount, fsample_count, paircount, self.bilex_fe)
+ *         return None
  */
-    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_d); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_d); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     if (__pyx_t_4) {
-      __pyx_t_2 = PyObject_GetAttr(__pyx_v_d, __pyx_n_s__get); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_GetAttr(__pyx_v_d, __pyx_n_s__get); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
       __Pyx_INCREF(__pyx_v_e);
-      PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_e);
+      PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_e);
       __Pyx_GIVEREF(__pyx_v_e);
       __Pyx_INCREF(__pyx_int_0);
-      PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_0);
+      PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_0);
       __Pyx_GIVEREF(__pyx_int_0);
-      __pyx_t_5 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
-      __pyx_t_1 = __pyx_t_5;
+      __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+      __pyx_t_3 = __pyx_t_5;
       __pyx_t_5 = 0;
     } else {
       __Pyx_INCREF(__pyx_int_0);
-      __pyx_t_1 = __pyx_int_0;
+      __pyx_t_3 = __pyx_int_0;
     }
-    __pyx_v_paircount = __pyx_t_1;
-    __pyx_t_1 = 0;
+    __pyx_v_paircount = __pyx_t_3;
+    __pyx_t_3 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2129
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2153
  *             d = self.phrases_fe.get(f, None)
  *             paircount = d.get(e, 0) if d else 0
- *             if paircount > 0:             # <<<<<<<<<<<<<<
- *                 print 'Online support:', f, '|||', e
- *             return OnlineFeatureContext(fcount, paircount, self.bilex_fe)
- */
-    __pyx_t_1 = PyObject_RichCompare(__pyx_v_paircount, __pyx_int_0, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    if (__pyx_t_4) {
-
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2130
- *             paircount = d.get(e, 0) if d else 0
- *             if paircount > 0:
- *                 print 'Online support:', f, '|||', e             # <<<<<<<<<<<<<<
- *             return OnlineFeatureContext(fcount, paircount, self.bilex_fe)
- *         return None
- */
-      __pyx_t_1 = PyTuple_New(4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_1);
-      __Pyx_INCREF(((PyObject *)__pyx_kp_s_151));
-      PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_kp_s_151));
-      __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_151));
-      __Pyx_INCREF(__pyx_v_f);
-      PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_f);
-      __Pyx_GIVEREF(__pyx_v_f);
-      __Pyx_INCREF(((PyObject *)__pyx_kp_s_152));
-      PyTuple_SET_ITEM(__pyx_t_1, 2, ((PyObject *)__pyx_kp_s_152));
-      __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_152));
-      __Pyx_INCREF(__pyx_v_e);
-      PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_v_e);
-      __Pyx_GIVEREF(__pyx_v_e);
-      if (__Pyx_Print(0, ((PyObject *)__pyx_t_1), 1) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-      goto __pyx_L4;
-    }
-    __pyx_L4:;
-
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2131
- *             if paircount > 0:
- *                 print 'Online support:', f, '|||', e
- *             return OnlineFeatureContext(fcount, paircount, self.bilex_fe)             # <<<<<<<<<<<<<<
+ *             return OnlineFeatureContext(fcount, fsample_count, paircount, self.bilex_fe)             # <<<<<<<<<<<<<<
  *         return None
  * 
  */
     __Pyx_XDECREF(__pyx_r);
-    __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s_153); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s_151); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_INCREF(__pyx_v_fcount);
     PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_fcount);
     __Pyx_GIVEREF(__pyx_v_fcount);
+    __Pyx_INCREF(__pyx_v_fsample_count);
+    PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_v_fsample_count);
+    __Pyx_GIVEREF(__pyx_v_fsample_count);
     __Pyx_INCREF(__pyx_v_paircount);
-    PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_v_paircount);
+    PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_v_paircount);
     __Pyx_GIVEREF(__pyx_v_paircount);
     __Pyx_INCREF(__pyx_v_self->bilex_fe);
-    PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_v_self->bilex_fe);
+    PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_v_self->bilex_fe);
     __Pyx_GIVEREF(__pyx_v_self->bilex_fe);
-    __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_t_1 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
-    __pyx_r = __pyx_t_3;
-    __pyx_t_3 = 0;
+    __pyx_r = __pyx_t_1;
+    __pyx_t_1 = 0;
     goto __pyx_L0;
     goto __pyx_L3;
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2132
- *                 print 'Online support:', f, '|||', e
- *             return OnlineFeatureContext(fcount, paircount, self.bilex_fe)
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2154
+ *             paircount = d.get(e, 0) if d else 0
+ *             return OnlineFeatureContext(fcount, fsample_count, paircount, self.bilex_fe)
  *         return None             # <<<<<<<<<<<<<<
  * 
- *     # Match source words against online data.
+ *     # Find all phrases that we might try to extract
  */
   __Pyx_XDECREF(__pyx_r);
   __Pyx_INCREF(Py_None);
@@ -64354,6 +64733,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_33online_ctx_lookup(str
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XDECREF(__pyx_v_fcount);
+  __Pyx_XDECREF(__pyx_v_fsample_count);
   __Pyx_XDECREF(__pyx_v_d);
   __Pyx_XDECREF(__pyx_v_paircount);
   __Pyx_XGIVEREF(__pyx_r);
@@ -64362,67 +64742,24 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_33online_ctx_lookup(str
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_36online_match(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_36online_match(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyObject *__pyx_v_f_words = 0;
-  PyObject *__pyx_v_seen_phrases = 0;
+static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_38get_f_phrases(PyObject *__pyx_v_self, PyObject *__pyx_v_f_words); /*proto*/
+static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_38get_f_phrases(PyObject *__pyx_v_self, PyObject *__pyx_v_f_words) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("online_match (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__f_words,&__pyx_n_s__seen_phrases,0};
-    PyObject* values[2] = {0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__f_words)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__seen_phrases)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("online_match", 1, 2, 2, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2136; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "online_match") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2136; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-    }
-    __pyx_v_f_words = values[0];
-    __pyx_v_seen_phrases = values[1];
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("online_match", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2136; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.online_match", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_3_sa_23HieroCachingRuleFactory_35online_match(((struct __pyx_obj_3_sa_HieroCachingRuleFactory *)__pyx_v_self), __pyx_v_f_words, __pyx_v_seen_phrases);
+  __Pyx_RefNannySetupContext("get_f_phrases (wrapper)", 0);
+  __pyx_r = __pyx_pf_3_sa_23HieroCachingRuleFactory_37get_f_phrases(((struct __pyx_obj_3_sa_HieroCachingRuleFactory *)__pyx_v_self), ((PyObject *)__pyx_v_f_words));
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_12online_match_1extract(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static PyMethodDef __pyx_mdef_3_sa_23HieroCachingRuleFactory_12online_match_1extract = {__Pyx_NAMESTR("extract"), (PyCFunction)__pyx_pw_3_sa_23HieroCachingRuleFactory_12online_match_1extract, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};
-static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_12online_match_1extract(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_13get_f_phrases_1extract(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_3_sa_23HieroCachingRuleFactory_13get_f_phrases_1extract = {__Pyx_NAMESTR("extract"), (PyCFunction)__pyx_pw_3_sa_23HieroCachingRuleFactory_13get_f_phrases_1extract, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_13get_f_phrases_1extract(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_f_i = 0;
   PyObject *__pyx_v_f_j = 0;
+  PyObject *__pyx_v_lex_i = 0;
+  PyObject *__pyx_v_lex_j = 0;
   PyObject *__pyx_v_wc = 0;
   PyObject *__pyx_v_ntc = 0;
   PyObject *__pyx_v_syms = 0;
@@ -64430,12 +64767,14 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_12online_match_1extract
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("extract (wrapper)", 0);
   {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__f_i,&__pyx_n_s__f_j,&__pyx_n_s__wc,&__pyx_n_s__ntc,&__pyx_n_s__syms,0};
-    PyObject* values[5] = {0,0,0,0,0};
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__f_i,&__pyx_n_s__f_j,&__pyx_n_s__lex_i,&__pyx_n_s__lex_j,&__pyx_n_s__wc,&__pyx_n_s__ntc,&__pyx_n_s__syms,0};
+    PyObject* values[7] = {0,0,0,0,0,0,0};
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
       const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
       switch (pos_args) {
+        case  7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
         case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
         case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
         case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
@@ -64452,28 +64791,38 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_12online_match_1extract
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__f_j)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("extract", 1, 5, 5, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2141; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("extract", 1, 7, 7, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2164; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
-        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__wc)) != 0)) kw_args--;
+        if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__lex_i)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("extract", 1, 5, 5, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2141; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("extract", 1, 7, 7, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2164; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  3:
-        if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__ntc)) != 0)) kw_args--;
+        if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__lex_j)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("extract", 1, 5, 5, 3); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2141; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("extract", 1, 7, 7, 3); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2164; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  4:
-        if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__syms)) != 0)) kw_args--;
+        if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__wc)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("extract", 1, 7, 7, 4); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2164; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  5:
+        if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__ntc)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("extract", 1, 7, 7, 5); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2164; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  6:
+        if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__syms)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("extract", 1, 5, 5, 4); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2141; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("extract", 1, 7, 7, 6); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2164; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "extract") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2141; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "extract") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2164; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 5) {
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 7) {
       goto __pyx_L5_argtuple_error;
     } else {
       values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
@@ -64481,39 +64830,44 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_12online_match_1extract
       values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
       values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
       values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+      values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+      values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
     }
     __pyx_v_f_i = values[0];
     __pyx_v_f_j = values[1];
-    __pyx_v_wc = values[2];
-    __pyx_v_ntc = values[3];
-    __pyx_v_syms = values[4];
+    __pyx_v_lex_i = values[2];
+    __pyx_v_lex_j = values[3];
+    __pyx_v_wc = values[4];
+    __pyx_v_ntc = values[5];
+    __pyx_v_syms = values[6];
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("extract", 1, 5, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2141; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("extract", 1, 7, 7, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2164; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
-  __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.online_match.extract", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.get_f_phrases.extract", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_3_sa_23HieroCachingRuleFactory_12online_match_extract(__pyx_self, __pyx_v_f_i, __pyx_v_f_j, __pyx_v_wc, __pyx_v_ntc, __pyx_v_syms);
+  __pyx_r = __pyx_pf_3_sa_23HieroCachingRuleFactory_13get_f_phrases_extract(__pyx_self, __pyx_v_f_i, __pyx_v_f_j, __pyx_v_lex_i, __pyx_v_lex_j, __pyx_v_wc, __pyx_v_ntc, __pyx_v_syms);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2141
- *         matches = {} # (f, e) = len
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2164
+ *         phrases = set() # (fphrase, lex_i, lex_j)
  * 
- *         def extract(f_i, f_j, wc, ntc, syms):             # <<<<<<<<<<<<<<
+ *         def extract(f_i, f_j, lex_i, lex_j, wc, ntc, syms):             # <<<<<<<<<<<<<<
  *             # Phrase extraction limits
  *             if f_j > (f_len - 1) or (f_j - f_i) + 1 > self.max_initial_size:
  */
 
-static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12online_match_extract(PyObject *__pyx_self, PyObject *__pyx_v_f_i, PyObject *__pyx_v_f_j, PyObject *__pyx_v_wc, PyObject *__pyx_v_ntc, PyObject *__pyx_v_syms) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_26_online_match *__pyx_cur_scope;
-  struct __pyx_obj_3_sa___pyx_scope_struct_26_online_match *__pyx_outer_scope;
+static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_13get_f_phrases_extract(PyObject *__pyx_self, PyObject *__pyx_v_f_i, PyObject *__pyx_v_f_j, PyObject *__pyx_v_lex_i, PyObject *__pyx_v_lex_j, PyObject *__pyx_v_wc, PyObject *__pyx_v_ntc, PyObject *__pyx_v_syms) {
+  struct __pyx_obj_3_sa___pyx_scope_struct_26_get_f_phrases *__pyx_cur_scope;
+  struct __pyx_obj_3_sa___pyx_scope_struct_26_get_f_phrases *__pyx_outer_scope;
   struct __pyx_obj_3_sa_Phrase *__pyx_v_f = NULL;
-  PyObject *__pyx_v_e = NULL;
+  PyObject *__pyx_v_new_lex_i = NULL;
+  PyObject *__pyx_v_new_lex_j = NULL;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -64522,44 +64876,43 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12online_match_extract(
   PyObject *__pyx_t_4 = NULL;
   int __pyx_t_5;
   int __pyx_t_6;
-  Py_ssize_t __pyx_t_7;
-  PyObject *(*__pyx_t_8)(PyObject *);
+  PyObject *__pyx_t_7 = NULL;
+  int __pyx_t_8;
   int __pyx_t_9;
-  int __pyx_t_10;
   int __pyx_lineno = 0;
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("extract", 0);
-  __pyx_outer_scope = (struct __pyx_obj_3_sa___pyx_scope_struct_26_online_match *) __Pyx_CyFunction_GetClosure(__pyx_self);
+  __pyx_outer_scope = (struct __pyx_obj_3_sa___pyx_scope_struct_26_get_f_phrases *) __Pyx_CyFunction_GetClosure(__pyx_self);
   __pyx_cur_scope = __pyx_outer_scope;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2143
- *         def extract(f_i, f_j, wc, ntc, syms):
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2166
+ *         def extract(f_i, f_j, lex_i, lex_j, wc, ntc, syms):
  *             # Phrase extraction limits
  *             if f_j > (f_len - 1) or (f_j - f_i) + 1 > self.max_initial_size:             # <<<<<<<<<<<<<<
  *                 return
  *             # Extend with word
  */
-  if (unlikely(!__pyx_cur_scope->__pyx_v_f_len)) { __Pyx_RaiseClosureNameError("f_len"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-  __pyx_t_1 = PyNumber_Subtract(__pyx_cur_scope->__pyx_v_f_len, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__pyx_cur_scope->__pyx_v_f_len)) { __Pyx_RaiseClosureNameError("f_len"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+  __pyx_t_1 = PyNumber_Subtract(__pyx_cur_scope->__pyx_v_f_len, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_RichCompare(__pyx_v_f_j, __pyx_t_1, Py_GT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_RichCompare(__pyx_v_f_j, __pyx_t_1, Py_GT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   if (!__pyx_t_3) {
-    __pyx_t_2 = PyNumber_Subtract(__pyx_v_f_j, __pyx_v_f_i); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyNumber_Subtract(__pyx_v_f_j, __pyx_v_f_i); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    if (unlikely(!__pyx_cur_scope->__pyx_v_self)) { __Pyx_RaiseClosureNameError("self"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-    __pyx_t_2 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_initial_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_cur_scope->__pyx_v_self)) { __Pyx_RaiseClosureNameError("self"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+    __pyx_t_2 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_initial_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_4 = PyObject_RichCompare(__pyx_t_1, __pyx_t_2, Py_GT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_RichCompare(__pyx_t_1, __pyx_t_2, Py_GT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __pyx_t_6 = __pyx_t_5;
   } else {
@@ -64567,7 +64920,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12online_match_extract(
   }
   if (__pyx_t_6) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2144
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2167
  *             # Phrase extraction limits
  *             if f_j > (f_len - 1) or (f_j - f_i) + 1 > self.max_initial_size:
  *                 return             # <<<<<<<<<<<<<<
@@ -64581,504 +64934,447 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12online_match_extract(
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2146
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2169
  *                 return
  *             # Extend with word
  *             if wc + ntc < self.max_length:             # <<<<<<<<<<<<<<
  *                 syms.append(f_words[f_j])
  *                 f = Phrase(syms)
  */
-  __pyx_t_4 = PyNumber_Add(__pyx_v_wc, __pyx_v_ntc); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyNumber_Add(__pyx_v_wc, __pyx_v_ntc); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_2 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_length); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_length); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_1 = PyObject_RichCompare(__pyx_t_4, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_RichCompare(__pyx_t_4, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   if (__pyx_t_6) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2147
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2170
  *             # Extend with word
  *             if wc + ntc < self.max_length:
  *                 syms.append(f_words[f_j])             # <<<<<<<<<<<<<<
  *                 f = Phrase(syms)
- *                 for e in self.phrases_fe[f]:
+ *                 new_lex_i = min(lex_i, f_j)
  */
-    if (unlikely(!__pyx_cur_scope->__pyx_v_f_words)) { __Pyx_RaiseClosureNameError("f_words"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2147; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-    __pyx_t_1 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_f_words, __pyx_v_f_j); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_cur_scope->__pyx_v_f_words)) { __Pyx_RaiseClosureNameError("f_words"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2170; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+    __pyx_t_1 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_f_words, __pyx_v_f_j); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_2 = __Pyx_PyObject_Append(__pyx_v_syms, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_PyObject_Append(__pyx_v_syms, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2148
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2171
  *             if wc + ntc < self.max_length:
  *                 syms.append(f_words[f_j])
  *                 f = Phrase(syms)             # <<<<<<<<<<<<<<
- *                 for e in self.phrases_fe[f]:
- *                     if (f, e) not in seen_phrases:
+ *                 new_lex_i = min(lex_i, f_j)
+ *                 new_lex_j = max(lex_j, f_j)
  */
-    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_INCREF(__pyx_v_syms);
     PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_syms);
     __Pyx_GIVEREF(__pyx_v_syms);
-    __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
     __pyx_v_f = ((struct __pyx_obj_3_sa_Phrase *)__pyx_t_1);
     __pyx_t_1 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2149
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2172
  *                 syms.append(f_words[f_j])
  *                 f = Phrase(syms)
- *                 for e in self.phrases_fe[f]:             # <<<<<<<<<<<<<<
- *                     if (f, e) not in seen_phrases:
- *                         matches[(f, e)] = (f_j - f_i) + 1
+ *                 new_lex_i = min(lex_i, f_j)             # <<<<<<<<<<<<<<
+ *                 new_lex_j = max(lex_j, f_j)
+ *                 phrases.add((f, new_lex_i, new_lex_j))
  */
-    __pyx_t_1 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_self->phrases_fe, ((PyObject *)__pyx_v_f)); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    if (PyList_CheckExact(__pyx_t_1) || PyTuple_CheckExact(__pyx_t_1)) {
-      __pyx_t_2 = __pyx_t_1; __Pyx_INCREF(__pyx_t_2); __pyx_t_7 = 0;
-      __pyx_t_8 = NULL;
+    __Pyx_INCREF(__pyx_v_f_j);
+    __pyx_t_1 = __pyx_v_f_j;
+    __Pyx_INCREF(__pyx_v_lex_i);
+    __pyx_t_2 = __pyx_v_lex_i;
+    __pyx_t_7 = PyObject_RichCompare(__pyx_t_1, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    if (__pyx_t_6) {
+      __Pyx_INCREF(__pyx_t_1);
+      __pyx_t_4 = __pyx_t_1;
     } else {
-      __pyx_t_7 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_8 = Py_TYPE(__pyx_t_2)->tp_iternext;
+      __Pyx_INCREF(__pyx_t_2);
+      __pyx_t_4 = __pyx_t_2;
     }
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    for (;;) {
-      if (!__pyx_t_8 && PyList_CheckExact(__pyx_t_2)) {
-        if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_2)) break;
-        #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_1 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_7); __Pyx_INCREF(__pyx_t_1); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        #else
-        __pyx_t_1 = PySequence_ITEM(__pyx_t_2, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        #endif
-      } else if (!__pyx_t_8 && PyTuple_CheckExact(__pyx_t_2)) {
-        if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
-        #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_7); __Pyx_INCREF(__pyx_t_1); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        #else
-        __pyx_t_1 = PySequence_ITEM(__pyx_t_2, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        #endif
-      } else {
-        __pyx_t_1 = __pyx_t_8(__pyx_t_2);
-        if (unlikely(!__pyx_t_1)) {
-          if (PyErr_Occurred()) {
-            if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-          }
-          break;
-        }
-        __Pyx_GOTREF(__pyx_t_1);
-      }
-      __Pyx_XDECREF(__pyx_v_e);
-      __pyx_v_e = __pyx_t_1;
-      __pyx_t_1 = 0;
+    __Pyx_INCREF(__pyx_t_4);
+    __pyx_v_new_lex_i = __pyx_t_4;
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2150
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2173
  *                 f = Phrase(syms)
- *                 for e in self.phrases_fe[f]:
- *                     if (f, e) not in seen_phrases:             # <<<<<<<<<<<<<<
- *                         matches[(f, e)] = (f_j - f_i) + 1
- *                 extract(f_i, f_j + 1, wc + 1, ntc, syms)
+ *                 new_lex_i = min(lex_i, f_j)
+ *                 new_lex_j = max(lex_j, f_j)             # <<<<<<<<<<<<<<
+ *                 phrases.add((f, new_lex_i, new_lex_j))
+ *                 extract(f_i, f_j + 1, new_lex_i, new_lex_j, wc + 1, ntc, syms)
  */
-      __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_1);
-      __Pyx_INCREF(((PyObject *)__pyx_v_f));
-      PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_v_f));
-      __Pyx_GIVEREF(((PyObject *)__pyx_v_f));
-      __Pyx_INCREF(__pyx_v_e);
-      PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_e);
-      __Pyx_GIVEREF(__pyx_v_e);
-      if (unlikely(!__pyx_cur_scope->__pyx_v_seen_phrases)) { __Pyx_RaiseClosureNameError("seen_phrases"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2150; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_6 = (__Pyx_PySequence_Contains(((PyObject *)__pyx_t_1), __pyx_cur_scope->__pyx_v_seen_phrases, Py_NE)); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-      if (__pyx_t_6) {
+    __Pyx_INCREF(__pyx_v_f_j);
+    __pyx_t_4 = __pyx_v_f_j;
+    __Pyx_INCREF(__pyx_v_lex_j);
+    __pyx_t_1 = __pyx_v_lex_j;
+    __pyx_t_7 = PyObject_RichCompare(__pyx_t_4, __pyx_t_1, Py_GT); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    if (__pyx_t_6) {
+      __Pyx_INCREF(__pyx_t_4);
+      __pyx_t_2 = __pyx_t_4;
+    } else {
+      __Pyx_INCREF(__pyx_t_1);
+      __pyx_t_2 = __pyx_t_1;
+    }
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __Pyx_INCREF(__pyx_t_2);
+    __pyx_v_new_lex_j = __pyx_t_2;
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2151
- *                 for e in self.phrases_fe[f]:
- *                     if (f, e) not in seen_phrases:
- *                         matches[(f, e)] = (f_j - f_i) + 1             # <<<<<<<<<<<<<<
- *                 extract(f_i, f_j + 1, wc + 1, ntc, syms)
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2174
+ *                 new_lex_i = min(lex_i, f_j)
+ *                 new_lex_j = max(lex_j, f_j)
+ *                 phrases.add((f, new_lex_i, new_lex_j))             # <<<<<<<<<<<<<<
+ *                 extract(f_i, f_j + 1, new_lex_i, new_lex_j, wc + 1, ntc, syms)
  *                 syms.pop()
  */
-        __pyx_t_1 = PyNumber_Subtract(__pyx_v_f_j, __pyx_v_f_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_1);
-        __pyx_t_4 = PyNumber_Add(__pyx_t_1, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_4);
-        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-        if (unlikely(!__pyx_cur_scope->__pyx_v_matches)) { __Pyx_RaiseClosureNameError("matches"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2151; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-        __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_1);
-        __Pyx_INCREF(((PyObject *)__pyx_v_f));
-        PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_v_f));
-        __Pyx_GIVEREF(((PyObject *)__pyx_v_f));
-        __Pyx_INCREF(__pyx_v_e);
-        PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_e);
-        __Pyx_GIVEREF(__pyx_v_e);
-        if (PyObject_SetItem(__pyx_cur_scope->__pyx_v_matches, ((PyObject *)__pyx_t_1), __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        goto __pyx_L7;
-      }
-      __pyx_L7:;
-    }
+    if (unlikely(!__pyx_cur_scope->__pyx_v_phrases)) { __Pyx_RaiseClosureNameError("phrases"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+    __pyx_t_2 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_phrases, __pyx_n_s__add); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_INCREF(((PyObject *)__pyx_v_f));
+    PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_v_f));
+    __Pyx_GIVEREF(((PyObject *)__pyx_v_f));
+    __Pyx_INCREF(__pyx_v_new_lex_i);
+    PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_v_new_lex_i);
+    __Pyx_GIVEREF(__pyx_v_new_lex_i);
+    __Pyx_INCREF(__pyx_v_new_lex_j);
+    PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_v_new_lex_j);
+    __Pyx_GIVEREF(__pyx_v_new_lex_j);
+    __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_t_4));
+    __Pyx_GIVEREF(((PyObject *)__pyx_t_4));
+    __pyx_t_4 = 0;
+    __pyx_t_4 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2152
- *                     if (f, e) not in seen_phrases:
- *                         matches[(f, e)] = (f_j - f_i) + 1
- *                 extract(f_i, f_j + 1, wc + 1, ntc, syms)             # <<<<<<<<<<<<<<
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2175
+ *                 new_lex_j = max(lex_j, f_j)
+ *                 phrases.add((f, new_lex_i, new_lex_j))
+ *                 extract(f_i, f_j + 1, new_lex_i, new_lex_j, wc + 1, ntc, syms)             # <<<<<<<<<<<<<<
  *                 syms.pop()
  *             # Extend with existing non-terminal
  */
-    if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2152; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-    __pyx_t_2 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_4 = PyNumber_Add(__pyx_v_wc, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2175; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+    __pyx_t_4 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyNumber_Add(__pyx_v_wc, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_2 = PyTuple_New(7); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
     __Pyx_INCREF(__pyx_v_f_i);
-    PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_f_i);
+    PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_f_i);
     __Pyx_GIVEREF(__pyx_v_f_i);
-    PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_2);
-    __Pyx_GIVEREF(__pyx_t_2);
-    PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_t_4);
+    PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_4);
     __Pyx_GIVEREF(__pyx_t_4);
+    __Pyx_INCREF(__pyx_v_new_lex_i);
+    PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_v_new_lex_i);
+    __Pyx_GIVEREF(__pyx_v_new_lex_i);
+    __Pyx_INCREF(__pyx_v_new_lex_j);
+    PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_v_new_lex_j);
+    __Pyx_GIVEREF(__pyx_v_new_lex_j);
+    PyTuple_SET_ITEM(__pyx_t_2, 4, __pyx_t_1);
+    __Pyx_GIVEREF(__pyx_t_1);
     __Pyx_INCREF(__pyx_v_ntc);
-    PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_v_ntc);
+    PyTuple_SET_ITEM(__pyx_t_2, 5, __pyx_v_ntc);
     __Pyx_GIVEREF(__pyx_v_ntc);
     __Pyx_INCREF(__pyx_v_syms);
-    PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_v_syms);
+    PyTuple_SET_ITEM(__pyx_t_2, 6, __pyx_v_syms);
     __Pyx_GIVEREF(__pyx_v_syms);
-    __pyx_t_2 = 0;
     __pyx_t_4 = 0;
-    __pyx_t_4 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_1 = 0;
+    __pyx_t_1 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2153
- *                         matches[(f, e)] = (f_j - f_i) + 1
- *                 extract(f_i, f_j + 1, wc + 1, ntc, syms)
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2176
+ *                 phrases.add((f, new_lex_i, new_lex_j))
+ *                 extract(f_i, f_j + 1, new_lex_i, new_lex_j, wc + 1, ntc, syms)
  *                 syms.pop()             # <<<<<<<<<<<<<<
  *             # Extend with existing non-terminal
  *             if syms and sym_isvar(syms[-1]):
  */
-    __pyx_t_4 = __Pyx_PyObject_Pop(__pyx_v_syms); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_1 = __Pyx_PyObject_Pop(__pyx_v_syms); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     goto __pyx_L4;
   }
   __pyx_L4:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2155
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2178
  *                 syms.pop()
  *             # Extend with existing non-terminal
  *             if syms and sym_isvar(syms[-1]):             # <<<<<<<<<<<<<<
  *                 # Don't re-extract the same phrase
- *                 extract(f_i, f_j + 1, wc, ntc, syms)
+ *                 extract(f_i, f_j + 1, lex_i, lex_j, wc, ntc, syms)
  */
-  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_syms); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_syms); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   if (__pyx_t_6) {
-    __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_syms, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_t_4); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_3 = __pyx_f_3_sa_sym_isvar(__pyx_t_9);
+    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_syms, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_8 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_8 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_t_3 = __pyx_f_3_sa_sym_isvar(__pyx_t_8);
   } else {
     __pyx_t_3 = __pyx_t_6;
   }
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2157
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2180
  *             if syms and sym_isvar(syms[-1]):
  *                 # Don't re-extract the same phrase
- *                 extract(f_i, f_j + 1, wc, ntc, syms)             # <<<<<<<<<<<<<<
+ *                 extract(f_i, f_j + 1, lex_i, lex_j, wc, ntc, syms)             # <<<<<<<<<<<<<<
  *             # Extend with new non-terminal
  *             if wc + ntc < self.max_length:
  */
-    if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2157; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-    __pyx_t_4 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2180; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+    __pyx_t_1 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_2 = PyTuple_New(7); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
     __Pyx_INCREF(__pyx_v_f_i);
-    PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_f_i);
+    PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_f_i);
     __Pyx_GIVEREF(__pyx_v_f_i);
-    PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_4);
-    __Pyx_GIVEREF(__pyx_t_4);
+    PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_1);
+    __Pyx_GIVEREF(__pyx_t_1);
+    __Pyx_INCREF(__pyx_v_lex_i);
+    PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_v_lex_i);
+    __Pyx_GIVEREF(__pyx_v_lex_i);
+    __Pyx_INCREF(__pyx_v_lex_j);
+    PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_v_lex_j);
+    __Pyx_GIVEREF(__pyx_v_lex_j);
     __Pyx_INCREF(__pyx_v_wc);
-    PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_v_wc);
+    PyTuple_SET_ITEM(__pyx_t_2, 4, __pyx_v_wc);
     __Pyx_GIVEREF(__pyx_v_wc);
     __Pyx_INCREF(__pyx_v_ntc);
-    PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_v_ntc);
+    PyTuple_SET_ITEM(__pyx_t_2, 5, __pyx_v_ntc);
     __Pyx_GIVEREF(__pyx_v_ntc);
     __Pyx_INCREF(__pyx_v_syms);
-    PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_v_syms);
+    PyTuple_SET_ITEM(__pyx_t_2, 6, __pyx_v_syms);
     __Pyx_GIVEREF(__pyx_v_syms);
-    __pyx_t_4 = 0;
-    __pyx_t_4 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    goto __pyx_L8;
+    __pyx_t_1 = 0;
+    __pyx_t_1 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    goto __pyx_L5;
   }
-  __pyx_L8:;
+  __pyx_L5:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2159
- *                 extract(f_i, f_j + 1, wc, ntc, syms)
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2182
+ *                 extract(f_i, f_j + 1, lex_i, lex_j, wc, ntc, syms)
  *             # Extend with new non-terminal
  *             if wc + ntc < self.max_length:             # <<<<<<<<<<<<<<
  *                 if not syms or (ntc < self.max_nonterminals and not sym_isvar(syms[-1])):
- *                     syms.append(sym_setindex(self.category, ntc))
+ *                     syms.append(sym_setindex(self.category, ntc + 1))
  */
-  __pyx_t_4 = PyNumber_Add(__pyx_v_wc, __pyx_v_ntc); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_1 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_length); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyNumber_Add(__pyx_v_wc, __pyx_v_ntc); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_RichCompare(__pyx_t_4, __pyx_t_1, Py_LT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_2 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_length); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_4 = PyObject_RichCompare(__pyx_t_1, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2160
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2183
  *             # Extend with new non-terminal
  *             if wc + ntc < self.max_length:
  *                 if not syms or (ntc < self.max_nonterminals and not sym_isvar(syms[-1])):             # <<<<<<<<<<<<<<
- *                     syms.append(sym_setindex(self.category, ntc))
+ *                     syms.append(sym_setindex(self.category, ntc + 1))
  *                     f = Phrase(syms)
  */
-    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_syms); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_syms); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __pyx_t_6 = (!__pyx_t_3);
     if (!__pyx_t_6) {
-      __pyx_t_2 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_nonterminals); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_1 = PyObject_RichCompare(__pyx_v_ntc, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_nonterminals); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_2 = PyObject_RichCompare(__pyx_v_ntc, __pyx_t_4, Py_LT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       if (__pyx_t_3) {
-        __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_syms, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_1);
-        __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-        __pyx_t_5 = (!__pyx_f_3_sa_sym_isvar(__pyx_t_9));
-        __pyx_t_10 = __pyx_t_5;
+        __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_syms, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+        __pyx_t_8 = __Pyx_PyInt_AsInt(__pyx_t_2); if (unlikely((__pyx_t_8 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+        __pyx_t_5 = (!__pyx_f_3_sa_sym_isvar(__pyx_t_8));
+        __pyx_t_9 = __pyx_t_5;
       } else {
-        __pyx_t_10 = __pyx_t_3;
+        __pyx_t_9 = __pyx_t_3;
       }
-      __pyx_t_3 = __pyx_t_10;
+      __pyx_t_3 = __pyx_t_9;
     } else {
       __pyx_t_3 = __pyx_t_6;
     }
     if (__pyx_t_3) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2161
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2184
  *             if wc + ntc < self.max_length:
  *                 if not syms or (ntc < self.max_nonterminals and not sym_isvar(syms[-1])):
- *                     syms.append(sym_setindex(self.category, ntc))             # <<<<<<<<<<<<<<
+ *                     syms.append(sym_setindex(self.category, ntc + 1))             # <<<<<<<<<<<<<<
  *                     f = Phrase(syms)
  *                     if wc > 0:
  */
-      __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_v_ntc); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_1 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_cur_scope->__pyx_v_self->category, __pyx_t_9)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_2 = __Pyx_PyObject_Append(__pyx_v_syms, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_Add(__pyx_v_ntc, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __pyx_t_8 = __Pyx_PyInt_AsInt(__pyx_t_2); if (unlikely((__pyx_t_8 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __pyx_t_2 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_cur_scope->__pyx_v_self->category, __pyx_t_8)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_4 = __Pyx_PyObject_Append(__pyx_v_syms, __pyx_t_2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2162
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2185
  *                 if not syms or (ntc < self.max_nonterminals and not sym_isvar(syms[-1])):
- *                     syms.append(sym_setindex(self.category, ntc))
+ *                     syms.append(sym_setindex(self.category, ntc + 1))
  *                     f = Phrase(syms)             # <<<<<<<<<<<<<<
  *                     if wc > 0:
- *                         for e in self.phrases_fe[f]:
+ *                         phrases.add((f, lex_i, lex_j))
  */
-      __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
       __Pyx_INCREF(__pyx_v_syms);
-      PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_syms);
+      PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_syms);
       __Pyx_GIVEREF(__pyx_v_syms);
-      __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_1);
-      __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+      __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
       __Pyx_XDECREF(((PyObject *)__pyx_v_f));
-      __pyx_v_f = ((struct __pyx_obj_3_sa_Phrase *)__pyx_t_1);
-      __pyx_t_1 = 0;
+      __pyx_v_f = ((struct __pyx_obj_3_sa_Phrase *)__pyx_t_2);
+      __pyx_t_2 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2163
- *                     syms.append(sym_setindex(self.category, ntc))
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2186
+ *                     syms.append(sym_setindex(self.category, ntc + 1))
  *                     f = Phrase(syms)
  *                     if wc > 0:             # <<<<<<<<<<<<<<
- *                         for e in self.phrases_fe[f]:
- *                             if (f, e) not in seen_phrases:
+ *                         phrases.add((f, lex_i, lex_j))
+ *                     extract(f_i, f_j + 1, lex_i, lex_j, wc, ntc + 1, syms)
  */
-      __pyx_t_1 = PyObject_RichCompare(__pyx_v_wc, __pyx_int_0, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __pyx_t_2 = PyObject_RichCompare(__pyx_v_wc, __pyx_int_0, Py_GT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       if (__pyx_t_3) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2164
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2187
  *                     f = Phrase(syms)
  *                     if wc > 0:
- *                         for e in self.phrases_fe[f]:             # <<<<<<<<<<<<<<
- *                             if (f, e) not in seen_phrases:
- *                                 matches[(f, e)] = (f_j - f_i) + 1
- */
-        __pyx_t_1 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_self->phrases_fe, ((PyObject *)__pyx_v_f)); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_1);
-        if (PyList_CheckExact(__pyx_t_1) || PyTuple_CheckExact(__pyx_t_1)) {
-          __pyx_t_2 = __pyx_t_1; __Pyx_INCREF(__pyx_t_2); __pyx_t_7 = 0;
-          __pyx_t_8 = NULL;
-        } else {
-          __pyx_t_7 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-          __Pyx_GOTREF(__pyx_t_2);
-          __pyx_t_8 = Py_TYPE(__pyx_t_2)->tp_iternext;
-        }
-        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-        for (;;) {
-          if (!__pyx_t_8 && PyList_CheckExact(__pyx_t_2)) {
-            if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_2)) break;
-            #if CYTHON_COMPILING_IN_CPYTHON
-            __pyx_t_1 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_7); __Pyx_INCREF(__pyx_t_1); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-            #else
-            __pyx_t_1 = PySequence_ITEM(__pyx_t_2, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-            #endif
-          } else if (!__pyx_t_8 && PyTuple_CheckExact(__pyx_t_2)) {
-            if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
-            #if CYTHON_COMPILING_IN_CPYTHON
-            __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_7); __Pyx_INCREF(__pyx_t_1); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-            #else
-            __pyx_t_1 = PySequence_ITEM(__pyx_t_2, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-            #endif
-          } else {
-            __pyx_t_1 = __pyx_t_8(__pyx_t_2);
-            if (unlikely(!__pyx_t_1)) {
-              if (PyErr_Occurred()) {
-                if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-                else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-              }
-              break;
-            }
-            __Pyx_GOTREF(__pyx_t_1);
-          }
-          __Pyx_XDECREF(__pyx_v_e);
-          __pyx_v_e = __pyx_t_1;
-          __pyx_t_1 = 0;
-
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2165
- *                     if wc > 0:
- *                         for e in self.phrases_fe[f]:
- *                             if (f, e) not in seen_phrases:             # <<<<<<<<<<<<<<
- *                                 matches[(f, e)] = (f_j - f_i) + 1
- *                     extract(f_i, f_j + 1, wc, ntc + 1, syms)
- */
-          __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-          __Pyx_GOTREF(__pyx_t_1);
-          __Pyx_INCREF(((PyObject *)__pyx_v_f));
-          PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_v_f));
-          __Pyx_GIVEREF(((PyObject *)__pyx_v_f));
-          __Pyx_INCREF(__pyx_v_e);
-          PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_e);
-          __Pyx_GIVEREF(__pyx_v_e);
-          if (unlikely(!__pyx_cur_scope->__pyx_v_seen_phrases)) { __Pyx_RaiseClosureNameError("seen_phrases"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2165; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-          __pyx_t_3 = (__Pyx_PySequence_Contains(((PyObject *)__pyx_t_1), __pyx_cur_scope->__pyx_v_seen_phrases, Py_NE)); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-          __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-          if (__pyx_t_3) {
-
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2166
- *                         for e in self.phrases_fe[f]:
- *                             if (f, e) not in seen_phrases:
- *                                 matches[(f, e)] = (f_j - f_i) + 1             # <<<<<<<<<<<<<<
- *                     extract(f_i, f_j + 1, wc, ntc + 1, syms)
+ *                         phrases.add((f, lex_i, lex_j))             # <<<<<<<<<<<<<<
+ *                     extract(f_i, f_j + 1, lex_i, lex_j, wc, ntc + 1, syms)
  *                     syms.pop()
  */
-            __pyx_t_1 = PyNumber_Subtract(__pyx_v_f_j, __pyx_v_f_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-            __Pyx_GOTREF(__pyx_t_1);
-            __pyx_t_4 = PyNumber_Add(__pyx_t_1, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-            __Pyx_GOTREF(__pyx_t_4);
-            __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-            if (unlikely(!__pyx_cur_scope->__pyx_v_matches)) { __Pyx_RaiseClosureNameError("matches"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-            __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-            __Pyx_GOTREF(__pyx_t_1);
-            __Pyx_INCREF(((PyObject *)__pyx_v_f));
-            PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_v_f));
-            __Pyx_GIVEREF(((PyObject *)__pyx_v_f));
-            __Pyx_INCREF(__pyx_v_e);
-            PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_e);
-            __Pyx_GIVEREF(__pyx_v_e);
-            if (PyObject_SetItem(__pyx_cur_scope->__pyx_v_matches, ((PyObject *)__pyx_t_1), __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-            __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-            __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-            goto __pyx_L14;
-          }
-          __pyx_L14:;
-        }
+        if (unlikely(!__pyx_cur_scope->__pyx_v_phrases)) { __Pyx_RaiseClosureNameError("phrases"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2187; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+        __pyx_t_2 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_phrases, __pyx_n_s__add); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_2);
+        __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_4);
+        __Pyx_INCREF(((PyObject *)__pyx_v_f));
+        PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_v_f));
+        __Pyx_GIVEREF(((PyObject *)__pyx_v_f));
+        __Pyx_INCREF(__pyx_v_lex_i);
+        PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_v_lex_i);
+        __Pyx_GIVEREF(__pyx_v_lex_i);
+        __Pyx_INCREF(__pyx_v_lex_j);
+        PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_v_lex_j);
+        __Pyx_GIVEREF(__pyx_v_lex_j);
+        __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_t_4));
+        __Pyx_GIVEREF(((PyObject *)__pyx_t_4));
+        __pyx_t_4 = 0;
+        __pyx_t_4 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_4);
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-        goto __pyx_L11;
+        __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+        goto __pyx_L8;
       }
-      __pyx_L11:;
+      __pyx_L8:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2167
- *                             if (f, e) not in seen_phrases:
- *                                 matches[(f, e)] = (f_j - f_i) + 1
- *                     extract(f_i, f_j + 1, wc, ntc + 1, syms)             # <<<<<<<<<<<<<<
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2188
+ *                     if wc > 0:
+ *                         phrases.add((f, lex_i, lex_j))
+ *                     extract(f_i, f_j + 1, lex_i, lex_j, wc, ntc + 1, syms)             # <<<<<<<<<<<<<<
  *                     syms.pop()
  * 
  */
-      if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2167; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_2 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_4 = PyNumber_Add(__pyx_v_ntc, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2188; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_4 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyNumber_Add(__pyx_v_ntc, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
+      __pyx_t_2 = PyTuple_New(7); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
       __Pyx_INCREF(__pyx_v_f_i);
-      PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_f_i);
+      PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_f_i);
       __Pyx_GIVEREF(__pyx_v_f_i);
-      PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_2);
-      __Pyx_GIVEREF(__pyx_t_2);
+      PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_4);
+      __Pyx_GIVEREF(__pyx_t_4);
+      __Pyx_INCREF(__pyx_v_lex_i);
+      PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_v_lex_i);
+      __Pyx_GIVEREF(__pyx_v_lex_i);
+      __Pyx_INCREF(__pyx_v_lex_j);
+      PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_v_lex_j);
+      __Pyx_GIVEREF(__pyx_v_lex_j);
       __Pyx_INCREF(__pyx_v_wc);
-      PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_v_wc);
+      PyTuple_SET_ITEM(__pyx_t_2, 4, __pyx_v_wc);
       __Pyx_GIVEREF(__pyx_v_wc);
-      PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_t_4);
-      __Pyx_GIVEREF(__pyx_t_4);
+      PyTuple_SET_ITEM(__pyx_t_2, 5, __pyx_t_1);
+      __Pyx_GIVEREF(__pyx_t_1);
       __Pyx_INCREF(__pyx_v_syms);
-      PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_v_syms);
+      PyTuple_SET_ITEM(__pyx_t_2, 6, __pyx_v_syms);
       __Pyx_GIVEREF(__pyx_v_syms);
-      __pyx_t_2 = 0;
       __pyx_t_4 = 0;
-      __pyx_t_4 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_4);
-      __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_1 = 0;
+      __pyx_t_1 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2168
- *                                 matches[(f, e)] = (f_j - f_i) + 1
- *                     extract(f_i, f_j + 1, wc, ntc + 1, syms)
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2189
+ *                         phrases.add((f, lex_i, lex_j))
+ *                     extract(f_i, f_j + 1, lex_i, lex_j, wc, ntc + 1, syms)
  *                     syms.pop()             # <<<<<<<<<<<<<<
  * 
  *         # Try to extract phrases from every f index
  */
-      __pyx_t_4 = __Pyx_PyObject_Pop(__pyx_v_syms); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_4);
-      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      goto __pyx_L10;
+      __pyx_t_1 = __Pyx_PyObject_Pop(__pyx_v_syms); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      goto __pyx_L7;
     }
-    __pyx_L10:;
-    goto __pyx_L9;
+    __pyx_L7:;
+    goto __pyx_L6;
   }
-  __pyx_L9:;
+  __pyx_L6:;
 
   __pyx_r = Py_None; __Pyx_INCREF(Py_None);
   goto __pyx_L0;
@@ -65086,483 +65382,29 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12online_match_extract(
   __Pyx_XDECREF(__pyx_t_1);
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.online_match.extract", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_f);
-  __Pyx_XDECREF(__pyx_v_e);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_12online_match_4generator17(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value); /* proto */
-
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2174
- *             extract(f_i, f_i, 0, 0, [])
- * 
- *         for line in sorted(' ||| '.join((str(f), str(e))) for (f, e) in matches):             # <<<<<<<<<<<<<<
- *             print 'Online new:', line
- *         return ((f, e, matches[(f, e)]) for (f, e) in matches)
- */
-
-static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12online_match_2genexpr(PyObject *__pyx_self) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_27_genexpr *__pyx_cur_scope;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("genexpr", 0);
-  __pyx_cur_scope = (struct __pyx_obj_3_sa___pyx_scope_struct_27_genexpr *)__pyx_ptype_3_sa___pyx_scope_struct_27_genexpr->tp_new(__pyx_ptype_3_sa___pyx_scope_struct_27_genexpr, __pyx_empty_tuple, NULL);
-  if (unlikely(!__pyx_cur_scope)) {
-    __Pyx_RefNannyFinishContext();
-    return NULL;
-  }
-  __Pyx_GOTREF(__pyx_cur_scope);
-  __pyx_cur_scope->__pyx_outer_scope = (struct __pyx_obj_3_sa___pyx_scope_struct_26_online_match *) __pyx_self;
-  __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_outer_scope));
-  __Pyx_GIVEREF(__pyx_cur_scope->__pyx_outer_scope);
-  {
-    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_23HieroCachingRuleFactory_12online_match_4generator17, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_cur_scope);
-    __Pyx_RefNannyFinishContext();
-    return (PyObject *) gen;
-  }
-
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.online_match.genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_DECREF(((PyObject *)__pyx_cur_scope));
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_12online_match_4generator17(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value) /* generator body */
-{
-  struct __pyx_obj_3_sa___pyx_scope_struct_27_genexpr *__pyx_cur_scope = ((struct __pyx_obj_3_sa___pyx_scope_struct_27_genexpr *)__pyx_generator->closure);
-  PyObject *__pyx_r = NULL;
-  PyObject *__pyx_t_1 = NULL;
-  Py_ssize_t __pyx_t_2;
-  PyObject *(*__pyx_t_3)(PyObject *);
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
-  PyObject *__pyx_t_7 = NULL;
-  PyObject *(*__pyx_t_8)(PyObject *);
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("None", 0);
-  switch (__pyx_generator->resume_label) {
-    case 0: goto __pyx_L3_first_run;
-    case 1: goto __pyx_L8_resume_from_yield;
-    default: /* CPython raises the right error here */
-    __Pyx_RefNannyFinishContext();
-    return NULL;
-  }
-  __pyx_L3_first_run:;
-  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_matches)) { __Pyx_RaiseClosureNameError("matches"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-  if (PyList_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_matches) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_matches)) {
-    __pyx_t_1 = __pyx_cur_scope->__pyx_outer_scope->__pyx_v_matches; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
-    __pyx_t_3 = NULL;
-  } else {
-    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_matches); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext;
-  }
-  for (;;) {
-    if (!__pyx_t_3 && PyList_CheckExact(__pyx_t_1)) {
-      if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
-      #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #endif
-    } else if (!__pyx_t_3 && PyTuple_CheckExact(__pyx_t_1)) {
-      if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
-      #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #endif
-    } else {
-      __pyx_t_4 = __pyx_t_3(__pyx_t_1);
-      if (unlikely(!__pyx_t_4)) {
-        if (PyErr_Occurred()) {
-          if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        }
-        break;
-      }
-      __Pyx_GOTREF(__pyx_t_4);
-    }
-    if ((likely(PyTuple_CheckExact(__pyx_t_4))) || (PyList_CheckExact(__pyx_t_4))) {
-      PyObject* sequence = __pyx_t_4;
-      #if CYTHON_COMPILING_IN_CPYTHON
-      Py_ssize_t size = Py_SIZE(sequence);
-      #else
-      Py_ssize_t size = PySequence_Size(sequence);
-      #endif
-      if (unlikely(size != 2)) {
-        if (size > 2) __Pyx_RaiseTooManyValuesError(2);
-        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      }
-      #if CYTHON_COMPILING_IN_CPYTHON
-      if (likely(PyTuple_CheckExact(sequence))) {
-        __pyx_t_5 = PyTuple_GET_ITEM(sequence, 0); 
-        __pyx_t_6 = PyTuple_GET_ITEM(sequence, 1); 
-      } else {
-        __pyx_t_5 = PyList_GET_ITEM(sequence, 0); 
-        __pyx_t_6 = PyList_GET_ITEM(sequence, 1); 
-      }
-      __Pyx_INCREF(__pyx_t_5);
-      __Pyx_INCREF(__pyx_t_6);
-      #else
-      __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #endif
-      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    } else
-    {
-      Py_ssize_t index = -1;
-      __pyx_t_7 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __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_L6_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_L6_unpacking_failed;
-      __Pyx_GOTREF(__pyx_t_6);
-      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_8 = NULL;
-      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-      goto __pyx_L7_unpacking_done;
-      __pyx_L6_unpacking_failed:;
-      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-      __pyx_t_8 = NULL;
-      if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_L7_unpacking_done:;
-    }
-    __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_f);
-    __Pyx_XDECREF(__pyx_cur_scope->__pyx_v_f);
-    __Pyx_GIVEREF(__pyx_t_5);
-    __pyx_cur_scope->__pyx_v_f = __pyx_t_5;
-    __pyx_t_5 = 0;
-    __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_e);
-    __Pyx_XDECREF(__pyx_cur_scope->__pyx_v_e);
-    __Pyx_GIVEREF(__pyx_t_6);
-    __pyx_cur_scope->__pyx_v_e = __pyx_t_6;
-    __pyx_t_6 = 0;
-    __pyx_t_4 = PyObject_GetAttr(((PyObject *)__pyx_kp_s_18), __pyx_n_s__join); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_6);
-    __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f);
-    PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_cur_scope->__pyx_v_f);
-    __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_f);
-    __pyx_t_5 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
-    __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_6);
-    __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e);
-    PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_cur_scope->__pyx_v_e);
-    __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_e);
-    __pyx_t_7 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_7);
-    __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
-    __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_6);
-    PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5);
-    __Pyx_GIVEREF(__pyx_t_5);
-    PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_7);
-    __Pyx_GIVEREF(__pyx_t_7);
-    __pyx_t_5 = 0;
-    __pyx_t_7 = 0;
-    __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_7);
-    PyTuple_SET_ITEM(__pyx_t_7, 0, ((PyObject *)__pyx_t_6));
-    __Pyx_GIVEREF(((PyObject *)__pyx_t_6));
-    __pyx_t_6 = 0;
-    __pyx_t_6 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_7), NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_6);
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __Pyx_DECREF(((PyObject *)__pyx_t_7)); __pyx_t_7 = 0;
-    __pyx_r = __pyx_t_6;
-    __pyx_t_6 = 0;
-    __Pyx_XGIVEREF(__pyx_t_1);
-    __pyx_cur_scope->__pyx_t_0 = __pyx_t_1;
-    __pyx_cur_scope->__pyx_t_1 = __pyx_t_2;
-    __pyx_cur_scope->__pyx_t_2 = __pyx_t_3;
-    __Pyx_XGIVEREF(__pyx_r);
-    __Pyx_RefNannyFinishContext();
-    /* return from generator, yielding value */
-    __pyx_generator->resume_label = 1;
-    return __pyx_r;
-    __pyx_L8_resume_from_yield:;
-    __pyx_t_1 = __pyx_cur_scope->__pyx_t_0;
-    __pyx_cur_scope->__pyx_t_0 = 0;
-    __Pyx_XGOTREF(__pyx_t_1);
-    __pyx_t_2 = __pyx_cur_scope->__pyx_t_1;
-    __pyx_t_3 = __pyx_cur_scope->__pyx_t_2;
-    if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  PyErr_SetNone(PyExc_StopIteration);
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
   __Pyx_XDECREF(__pyx_t_7);
-  __Pyx_AddTraceback("genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_L0:;
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_generator->resume_label = -1;
-  __Pyx_Generator_clear((PyObject*)__pyx_generator);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-}
-static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_12online_match_7generator18(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value); /* proto */
-
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2176
- *         for line in sorted(' ||| '.join((str(f), str(e))) for (f, e) in matches):
- *             print 'Online new:', line
- *         return ((f, e, matches[(f, e)]) for (f, e) in matches)             # <<<<<<<<<<<<<<
- * 
- * # Spans are _inclusive_ on both ends [i, j]
- */
-
-static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12online_match_5genexpr(PyObject *__pyx_self) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_28_genexpr *__pyx_cur_scope;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("genexpr", 0);
-  __pyx_cur_scope = (struct __pyx_obj_3_sa___pyx_scope_struct_28_genexpr *)__pyx_ptype_3_sa___pyx_scope_struct_28_genexpr->tp_new(__pyx_ptype_3_sa___pyx_scope_struct_28_genexpr, __pyx_empty_tuple, NULL);
-  if (unlikely(!__pyx_cur_scope)) {
-    __Pyx_RefNannyFinishContext();
-    return NULL;
-  }
-  __Pyx_GOTREF(__pyx_cur_scope);
-  __pyx_cur_scope->__pyx_outer_scope = (struct __pyx_obj_3_sa___pyx_scope_struct_26_online_match *) __pyx_self;
-  __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_outer_scope));
-  __Pyx_GIVEREF(__pyx_cur_scope->__pyx_outer_scope);
-  {
-    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_23HieroCachingRuleFactory_12online_match_7generator18, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_cur_scope);
-    __Pyx_RefNannyFinishContext();
-    return (PyObject *) gen;
-  }
-
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.online_match.genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.get_f_phrases.extract", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
-  __Pyx_DECREF(((PyObject *)__pyx_cur_scope));
+  __Pyx_XDECREF((PyObject *)__pyx_v_f);
+  __Pyx_XDECREF(__pyx_v_new_lex_i);
+  __Pyx_XDECREF(__pyx_v_new_lex_j);
   __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_12online_match_7generator18(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value) /* generator body */
-{
-  struct __pyx_obj_3_sa___pyx_scope_struct_28_genexpr *__pyx_cur_scope = ((struct __pyx_obj_3_sa___pyx_scope_struct_28_genexpr *)__pyx_generator->closure);
-  PyObject *__pyx_r = NULL;
-  PyObject *__pyx_t_1 = NULL;
-  Py_ssize_t __pyx_t_2;
-  PyObject *(*__pyx_t_3)(PyObject *);
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
-  PyObject *__pyx_t_7 = NULL;
-  PyObject *(*__pyx_t_8)(PyObject *);
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("None", 0);
-  switch (__pyx_generator->resume_label) {
-    case 0: goto __pyx_L3_first_run;
-    case 1: goto __pyx_L8_resume_from_yield;
-    default: /* CPython raises the right error here */
-    __Pyx_RefNannyFinishContext();
-    return NULL;
-  }
-  __pyx_L3_first_run:;
-  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_matches)) { __Pyx_RaiseClosureNameError("matches"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2176; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-  if (PyList_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_matches) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_matches)) {
-    __pyx_t_1 = __pyx_cur_scope->__pyx_outer_scope->__pyx_v_matches; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
-    __pyx_t_3 = NULL;
-  } else {
-    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_matches); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext;
-  }
-  for (;;) {
-    if (!__pyx_t_3 && PyList_CheckExact(__pyx_t_1)) {
-      if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
-      #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 2176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #endif
-    } else if (!__pyx_t_3 && PyTuple_CheckExact(__pyx_t_1)) {
-      if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
-      #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 2176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #endif
-    } else {
-      __pyx_t_4 = __pyx_t_3(__pyx_t_1);
-      if (unlikely(!__pyx_t_4)) {
-        if (PyErr_Occurred()) {
-          if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        }
-        break;
-      }
-      __Pyx_GOTREF(__pyx_t_4);
-    }
-    if ((likely(PyTuple_CheckExact(__pyx_t_4))) || (PyList_CheckExact(__pyx_t_4))) {
-      PyObject* sequence = __pyx_t_4;
-      #if CYTHON_COMPILING_IN_CPYTHON
-      Py_ssize_t size = Py_SIZE(sequence);
-      #else
-      Py_ssize_t size = PySequence_Size(sequence);
-      #endif
-      if (unlikely(size != 2)) {
-        if (size > 2) __Pyx_RaiseTooManyValuesError(2);
-        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      }
-      #if CYTHON_COMPILING_IN_CPYTHON
-      if (likely(PyTuple_CheckExact(sequence))) {
-        __pyx_t_5 = PyTuple_GET_ITEM(sequence, 0); 
-        __pyx_t_6 = PyTuple_GET_ITEM(sequence, 1); 
-      } else {
-        __pyx_t_5 = PyList_GET_ITEM(sequence, 0); 
-        __pyx_t_6 = PyList_GET_ITEM(sequence, 1); 
-      }
-      __Pyx_INCREF(__pyx_t_5);
-      __Pyx_INCREF(__pyx_t_6);
-      #else
-      __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #endif
-      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    } else
-    {
-      Py_ssize_t index = -1;
-      __pyx_t_7 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2176; __pyx_clineno = __LINE__; goto __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_L6_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_L6_unpacking_failed;
-      __Pyx_GOTREF(__pyx_t_6);
-      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_8 = NULL;
-      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-      goto __pyx_L7_unpacking_done;
-      __pyx_L6_unpacking_failed:;
-      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-      __pyx_t_8 = NULL;
-      if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_L7_unpacking_done:;
-    }
-    __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_f);
-    __Pyx_XDECREF(__pyx_cur_scope->__pyx_v_f);
-    __Pyx_GIVEREF(__pyx_t_5);
-    __pyx_cur_scope->__pyx_v_f = __pyx_t_5;
-    __pyx_t_5 = 0;
-    __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_e);
-    __Pyx_XDECREF(__pyx_cur_scope->__pyx_v_e);
-    __Pyx_GIVEREF(__pyx_t_6);
-    __pyx_cur_scope->__pyx_v_e = __pyx_t_6;
-    __pyx_t_6 = 0;
-    __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f);
-    PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_cur_scope->__pyx_v_f);
-    __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_f);
-    __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e);
-    PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_cur_scope->__pyx_v_e);
-    __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_e);
-    __pyx_t_6 = PyObject_GetItem(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_matches, ((PyObject *)__pyx_t_4)); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_6);
-    __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
-    __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f);
-    PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_cur_scope->__pyx_v_f);
-    __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_f);
-    __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e);
-    PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_cur_scope->__pyx_v_e);
-    __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_e);
-    PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_t_6);
-    __Pyx_GIVEREF(__pyx_t_6);
-    __pyx_t_6 = 0;
-    __pyx_r = ((PyObject *)__pyx_t_4);
-    __pyx_t_4 = 0;
-    __Pyx_XGIVEREF(__pyx_t_1);
-    __pyx_cur_scope->__pyx_t_0 = __pyx_t_1;
-    __pyx_cur_scope->__pyx_t_1 = __pyx_t_2;
-    __pyx_cur_scope->__pyx_t_2 = __pyx_t_3;
-    __Pyx_XGIVEREF(__pyx_r);
-    __Pyx_RefNannyFinishContext();
-    /* return from generator, yielding value */
-    __pyx_generator->resume_label = 1;
-    return __pyx_r;
-    __pyx_L8_resume_from_yield:;
-    __pyx_t_1 = __pyx_cur_scope->__pyx_t_0;
-    __pyx_cur_scope->__pyx_t_0 = 0;
-    __Pyx_XGOTREF(__pyx_t_1);
-    __pyx_t_2 = __pyx_cur_scope->__pyx_t_1;
-    __pyx_t_3 = __pyx_cur_scope->__pyx_t_2;
-    if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  PyErr_SetNone(PyExc_StopIteration);
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_7);
-  __Pyx_AddTraceback("genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_L0:;
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_generator->resume_label = -1;
-  __Pyx_Generator_clear((PyObject*)__pyx_generator);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-}
-
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2136
- *     # Match source words against online data.
- *     # Return (fphrase, ephrase, length)
- *     def online_match(self, f_words, seen_phrases):             # <<<<<<<<<<<<<<
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2159
+ *     # (Used for EGivenFCoherent)
+ *     # Return set of (fphrase, lex_i, lex_j)
+ *     def get_f_phrases(self, f_words):             # <<<<<<<<<<<<<<
  * 
  *         f_len = len(f_words)
  */
 
-static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_35online_match(struct __pyx_obj_3_sa_HieroCachingRuleFactory *__pyx_v_self, PyObject *__pyx_v_f_words, PyObject *__pyx_v_seen_phrases) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_26_online_match *__pyx_cur_scope;
+static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_37get_f_phrases(struct __pyx_obj_3_sa_HieroCachingRuleFactory *__pyx_v_self, PyObject *__pyx_v_f_words) {
+  struct __pyx_obj_3_sa___pyx_scope_struct_26_get_f_phrases *__pyx_cur_scope;
   long __pyx_v_f_i;
-  PyObject *__pyx_v_line = NULL;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -65571,12 +65413,11 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_35online_match(struct _
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
   PyObject *__pyx_t_6 = NULL;
-  PyObject *(*__pyx_t_7)(PyObject *);
   int __pyx_lineno = 0;
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("online_match", 0);
-  __pyx_cur_scope = (struct __pyx_obj_3_sa___pyx_scope_struct_26_online_match *)__pyx_ptype_3_sa___pyx_scope_struct_26_online_match->tp_new(__pyx_ptype_3_sa___pyx_scope_struct_26_online_match, __pyx_empty_tuple, NULL);
+  __Pyx_RefNannySetupContext("get_f_phrases", 0);
+  __pyx_cur_scope = (struct __pyx_obj_3_sa___pyx_scope_struct_26_get_f_phrases *)__pyx_ptype_3_sa___pyx_scope_struct_26_get_f_phrases->tp_new(__pyx_ptype_3_sa___pyx_scope_struct_26_get_f_phrases, __pyx_empty_tuple, NULL);
   if (unlikely(!__pyx_cur_scope)) {
     __Pyx_RefNannyFinishContext();
     return NULL;
@@ -65588,187 +65429,112 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_35online_match(struct _
   __pyx_cur_scope->__pyx_v_f_words = __pyx_v_f_words;
   __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f_words);
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_f_words);
-  __pyx_cur_scope->__pyx_v_seen_phrases = __pyx_v_seen_phrases;
-  __Pyx_INCREF(__pyx_cur_scope->__pyx_v_seen_phrases);
-  __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_seen_phrases);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2138
- *     def online_match(self, f_words, seen_phrases):
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2161
+ *     def get_f_phrases(self, f_words):
  * 
  *         f_len = len(f_words)             # <<<<<<<<<<<<<<
- *         matches = {} # (f, e) = len
+ *         phrases = set() # (fphrase, lex_i, lex_j)
  * 
  */
   __pyx_t_1 = __pyx_cur_scope->__pyx_v_f_words;
   __Pyx_INCREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_1);
   __pyx_cur_scope->__pyx_v_f_len = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2139
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2162
  * 
  *         f_len = len(f_words)
- *         matches = {} # (f, e) = len             # <<<<<<<<<<<<<<
+ *         phrases = set() # (fphrase, lex_i, lex_j)             # <<<<<<<<<<<<<<
  * 
- *         def extract(f_i, f_j, wc, ntc, syms):
+ *         def extract(f_i, f_j, lex_i, lex_j, wc, ntc, syms):
  */
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PySet_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
-  __pyx_cur_scope->__pyx_v_matches = ((PyObject *)__pyx_t_1);
+  __pyx_cur_scope->__pyx_v_phrases = ((PyObject *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2141
- *         matches = {} # (f, e) = len
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2164
+ *         phrases = set() # (fphrase, lex_i, lex_j)
  * 
- *         def extract(f_i, f_j, wc, ntc, syms):             # <<<<<<<<<<<<<<
+ *         def extract(f_i, f_j, lex_i, lex_j, wc, ntc, syms):             # <<<<<<<<<<<<<<
  *             # Phrase extraction limits
  *             if f_j > (f_len - 1) or (f_j - f_i) + 1 > self.max_initial_size:
  */
-  __pyx_t_1 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_12online_match_1extract, 0, ((PyObject*)__pyx_cur_scope), __pyx_n_s___sa, ((PyObject *)__pyx_k_codeobj_155)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_13get_f_phrases_1extract, 0, ((PyObject*)__pyx_cur_scope), __pyx_n_s___sa, ((PyObject *)__pyx_k_codeobj_153)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_1);
   __pyx_cur_scope->__pyx_v_extract = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2171
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2192
  * 
  *         # Try to extract phrases from every f index
  *         for f_i from 0 <= f_i < f_len:             # <<<<<<<<<<<<<<
- *             extract(f_i, f_i, 0, 0, [])
+ *             extract(f_i, f_i, f_len, -1, 0, 0, [])
  * 
  */
-  __pyx_t_3 = __Pyx_PyInt_AsLong(__pyx_cur_scope->__pyx_v_f_len); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = __Pyx_PyInt_AsLong(__pyx_cur_scope->__pyx_v_f_len); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   for (__pyx_v_f_i = 0; __pyx_v_f_i < __pyx_t_3; __pyx_v_f_i++) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2172
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2193
  *         # Try to extract phrases from every f index
  *         for f_i from 0 <= f_i < f_len:
- *             extract(f_i, f_i, 0, 0, [])             # <<<<<<<<<<<<<<
+ *             extract(f_i, f_i, f_len, -1, 0, 0, [])             # <<<<<<<<<<<<<<
  * 
- *         for line in sorted(' ||| '.join((str(f), str(e))) for (f, e) in matches):
+ *         return phrases
  */
-    __pyx_t_1 = PyInt_FromLong(__pyx_v_f_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyInt_FromLong(__pyx_v_f_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_4 = PyInt_FromLong(__pyx_v_f_i); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyInt_FromLong(__pyx_v_f_i); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = PyList_New(0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyList_New(0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_6 = PyTuple_New(5); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyTuple_New(7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_1);
     __Pyx_GIVEREF(__pyx_t_1);
     PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_4);
     __Pyx_GIVEREF(__pyx_t_4);
+    __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f_len);
+    PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_cur_scope->__pyx_v_f_len);
+    __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_f_len);
+    __Pyx_INCREF(__pyx_int_neg_1);
+    PyTuple_SET_ITEM(__pyx_t_6, 3, __pyx_int_neg_1);
+    __Pyx_GIVEREF(__pyx_int_neg_1);
     __Pyx_INCREF(__pyx_int_0);
-    PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_int_0);
+    PyTuple_SET_ITEM(__pyx_t_6, 4, __pyx_int_0);
     __Pyx_GIVEREF(__pyx_int_0);
     __Pyx_INCREF(__pyx_int_0);
-    PyTuple_SET_ITEM(__pyx_t_6, 3, __pyx_int_0);
+    PyTuple_SET_ITEM(__pyx_t_6, 5, __pyx_int_0);
     __Pyx_GIVEREF(__pyx_int_0);
-    PyTuple_SET_ITEM(__pyx_t_6, 4, ((PyObject *)__pyx_t_5));
+    PyTuple_SET_ITEM(__pyx_t_6, 6, ((PyObject *)__pyx_t_5));
     __Pyx_GIVEREF(((PyObject *)__pyx_t_5));
     __pyx_t_1 = 0;
     __pyx_t_4 = 0;
     __pyx_t_5 = 0;
-    __pyx_t_5 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2174
- *             extract(f_i, f_i, 0, 0, [])
- * 
- *         for line in sorted(' ||| '.join((str(f), str(e))) for (f, e) in matches):             # <<<<<<<<<<<<<<
- *             print 'Online new:', line
- *         return ((f, e, matches[(f, e)]) for (f, e) in matches)
- */
-  __pyx_t_5 = __pyx_pf_3_sa_23HieroCachingRuleFactory_12online_match_2genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5);
-  __Pyx_GIVEREF(__pyx_t_5);
-  __pyx_t_5 = 0;
-  __pyx_t_5 = PyObject_Call(__pyx_builtin_sorted, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
-  if (PyList_CheckExact(__pyx_t_5) || PyTuple_CheckExact(__pyx_t_5)) {
-    __pyx_t_6 = __pyx_t_5; __Pyx_INCREF(__pyx_t_6); __pyx_t_2 = 0;
-    __pyx_t_7 = NULL;
-  } else {
-    __pyx_t_2 = -1; __pyx_t_6 = PyObject_GetIter(__pyx_t_5); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_7 = Py_TYPE(__pyx_t_6)->tp_iternext;
-  }
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  for (;;) {
-    if (!__pyx_t_7 && PyList_CheckExact(__pyx_t_6)) {
-      if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_6)) break;
-      #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_5 = PyList_GET_ITEM(__pyx_t_6, __pyx_t_2); __Pyx_INCREF(__pyx_t_5); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #else
-      __pyx_t_5 = PySequence_ITEM(__pyx_t_6, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #endif
-    } else if (!__pyx_t_7 && PyTuple_CheckExact(__pyx_t_6)) {
-      if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_6)) break;
-      #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_6, __pyx_t_2); __Pyx_INCREF(__pyx_t_5); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #else
-      __pyx_t_5 = PySequence_ITEM(__pyx_t_6, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #endif
-    } else {
-      __pyx_t_5 = __pyx_t_7(__pyx_t_6);
-      if (unlikely(!__pyx_t_5)) {
-        if (PyErr_Occurred()) {
-          if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        }
-        break;
-      }
-      __Pyx_GOTREF(__pyx_t_5);
-    }
-    __Pyx_XDECREF(__pyx_v_line);
-    __pyx_v_line = __pyx_t_5;
-    __pyx_t_5 = 0;
-
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2175
- * 
- *         for line in sorted(' ||| '.join((str(f), str(e))) for (f, e) in matches):
- *             print 'Online new:', line             # <<<<<<<<<<<<<<
- *         return ((f, e, matches[(f, e)]) for (f, e) in matches)
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2195
+ *             extract(f_i, f_i, f_len, -1, 0, 0, [])
  * 
- */
-    __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    __Pyx_INCREF(((PyObject *)__pyx_kp_s_156));
-    PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)__pyx_kp_s_156));
-    __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_156));
-    __Pyx_INCREF(__pyx_v_line);
-    PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_v_line);
-    __Pyx_GIVEREF(__pyx_v_line);
-    if (__Pyx_Print(0, ((PyObject *)__pyx_t_5), 1) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
-  }
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2176
- *         for line in sorted(' ||| '.join((str(f), str(e))) for (f, e) in matches):
- *             print 'Online new:', line
- *         return ((f, e, matches[(f, e)]) for (f, e) in matches)             # <<<<<<<<<<<<<<
+ *         return phrases             # <<<<<<<<<<<<<<
  * 
  * # Spans are _inclusive_ on both ends [i, j]
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_6 = __pyx_pf_3_sa_23HieroCachingRuleFactory_12online_match_5genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __pyx_r = __pyx_t_6;
-  __pyx_t_6 = 0;
+  __Pyx_INCREF(__pyx_cur_scope->__pyx_v_phrases);
+  __pyx_r = __pyx_cur_scope->__pyx_v_phrases;
   goto __pyx_L0;
 
   __pyx_r = Py_None; __Pyx_INCREF(Py_None);
@@ -65778,10 +65544,9 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_35online_match(struct _
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.online_match", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.get_f_phrases", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
-  __Pyx_XDECREF(__pyx_v_line);
   __Pyx_DECREF(((PyObject *)__pyx_cur_scope));
   __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
@@ -65819,16 +65584,16 @@ static PyObject *__pyx_pw_3_sa_13span_check(PyObject *__pyx_self, PyObject *__py
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__i)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("span_check", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2179; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("span_check", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2198; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__j)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("span_check", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2179; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("span_check", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2198; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "span_check") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2179; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "span_check") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2198; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
       goto __pyx_L5_argtuple_error;
@@ -65843,7 +65608,7 @@ static PyObject *__pyx_pw_3_sa_13span_check(PyObject *__pyx_self, PyObject *__py
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("span_check", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2179; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("span_check", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2198; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.span_check", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -65854,7 +65619,7 @@ static PyObject *__pyx_pw_3_sa_13span_check(PyObject *__pyx_self, PyObject *__py
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2179
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2198
  * 
  * # Spans are _inclusive_ on both ends [i, j]
  * def span_check(vec, i, j):             # <<<<<<<<<<<<<<
@@ -65873,7 +65638,7 @@ static PyObject *__pyx_pf_3_sa_12span_check(CYTHON_UNUSED PyObject *__pyx_self,
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("span_check", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2180
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2199
  * # Spans are _inclusive_ on both ends [i, j]
  * def span_check(vec, i, j):
  *     k = i             # <<<<<<<<<<<<<<
@@ -65883,7 +65648,7 @@ static PyObject *__pyx_pf_3_sa_12span_check(CYTHON_UNUSED PyObject *__pyx_self,
   __Pyx_INCREF(__pyx_v_i);
   __pyx_v_k = __pyx_v_i;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2181
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2200
  * def span_check(vec, i, j):
  *     k = i
  *     while k <= j:             # <<<<<<<<<<<<<<
@@ -65891,25 +65656,25 @@ static PyObject *__pyx_pf_3_sa_12span_check(CYTHON_UNUSED PyObject *__pyx_self,
  *             return False
  */
   while (1) {
-    __pyx_t_1 = PyObject_RichCompare(__pyx_v_k, __pyx_v_j, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_RichCompare(__pyx_v_k, __pyx_v_j, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     if (!__pyx_t_2) break;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2182
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2201
  *     k = i
  *     while k <= j:
  *         if vec[k]:             # <<<<<<<<<<<<<<
  *             return False
  *         k += 1
  */
-    __pyx_t_1 = PyObject_GetItem(__pyx_v_vec, __pyx_v_k); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_GetItem(__pyx_v_vec, __pyx_v_k); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     if (__pyx_t_2) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2183
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2202
  *     while k <= j:
  *         if vec[k]:
  *             return False             # <<<<<<<<<<<<<<
@@ -65917,7 +65682,7 @@ static PyObject *__pyx_pf_3_sa_12span_check(CYTHON_UNUSED PyObject *__pyx_self,
  *     return True
  */
       __Pyx_XDECREF(__pyx_r);
-      __pyx_t_1 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2202; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __pyx_r = __pyx_t_1;
       __pyx_t_1 = 0;
@@ -65926,21 +65691,21 @@ static PyObject *__pyx_pf_3_sa_12span_check(CYTHON_UNUSED PyObject *__pyx_self,
     }
     __pyx_L5:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2184
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2203
  *         if vec[k]:
  *             return False
  *         k += 1             # <<<<<<<<<<<<<<
  *     return True
  * 
  */
-    __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_k, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_k, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_v_k);
     __pyx_v_k = __pyx_t_1;
     __pyx_t_1 = 0;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2185
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2204
  *             return False
  *         k += 1
  *     return True             # <<<<<<<<<<<<<<
@@ -65948,7 +65713,7 @@ static PyObject *__pyx_pf_3_sa_12span_check(CYTHON_UNUSED PyObject *__pyx_self,
  * def span_inc(vec, i, j):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -65998,16 +65763,16 @@ static PyObject *__pyx_pw_3_sa_15span_inc(PyObject *__pyx_self, PyObject *__pyx_
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__i)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("span_inc", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2187; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("span_inc", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2206; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__j)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("span_inc", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2187; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("span_inc", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2206; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "span_inc") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2187; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "span_inc") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2206; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
       goto __pyx_L5_argtuple_error;
@@ -66022,7 +65787,7 @@ static PyObject *__pyx_pw_3_sa_15span_inc(PyObject *__pyx_self, PyObject *__pyx_
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("span_inc", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2187; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("span_inc", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2206; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.span_inc", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -66033,7 +65798,7 @@ static PyObject *__pyx_pw_3_sa_15span_inc(PyObject *__pyx_self, PyObject *__pyx_
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2187
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2206
  *     return True
  * 
  * def span_inc(vec, i, j):             # <<<<<<<<<<<<<<
@@ -66054,7 +65819,7 @@ static PyObject *__pyx_pf_3_sa_14span_inc(CYTHON_UNUSED PyObject *__pyx_self, Py
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("span_inc", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2188
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2207
  * 
  * def span_inc(vec, i, j):
  *     k = i             # <<<<<<<<<<<<<<
@@ -66064,7 +65829,7 @@ static PyObject *__pyx_pf_3_sa_14span_inc(CYTHON_UNUSED PyObject *__pyx_self, Py
   __Pyx_INCREF(__pyx_v_i);
   __pyx_v_k = __pyx_v_i;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2189
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2208
  * def span_inc(vec, i, j):
  *     k = i
  *     while k <= j:             # <<<<<<<<<<<<<<
@@ -66072,12 +65837,12 @@ static PyObject *__pyx_pf_3_sa_14span_inc(CYTHON_UNUSED PyObject *__pyx_self, Py
  *         k += 1
  */
   while (1) {
-    __pyx_t_1 = PyObject_RichCompare(__pyx_v_k, __pyx_v_j, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_RichCompare(__pyx_v_k, __pyx_v_j, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     if (!__pyx_t_2) break;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2190
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2209
  *     k = i
  *     while k <= j:
  *         vec[k] += 1             # <<<<<<<<<<<<<<
@@ -66086,23 +65851,23 @@ static PyObject *__pyx_pf_3_sa_14span_inc(CYTHON_UNUSED PyObject *__pyx_self, Py
  */
     __Pyx_INCREF(__pyx_v_k);
     __pyx_t_1 = __pyx_v_k;
-    __pyx_t_3 = PyObject_GetItem(__pyx_v_vec, __pyx_t_1); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_GetItem(__pyx_v_vec, __pyx_t_1); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_t_3, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_t_3, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (PyObject_SetItem(__pyx_v_vec, __pyx_t_1, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyObject_SetItem(__pyx_v_vec, __pyx_t_1, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2191
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2210
  *     while k <= j:
  *         vec[k] += 1
  *         k += 1             # <<<<<<<<<<<<<<
  * 
  * def span_dec(vec, i, j):
  */
-    __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_k, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_k, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_v_k);
     __pyx_v_k = __pyx_t_1;
@@ -66155,16 +65920,16 @@ static PyObject *__pyx_pw_3_sa_17span_dec(PyObject *__pyx_self, PyObject *__pyx_
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__i)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("span_dec", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2193; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("span_dec", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2212; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__j)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("span_dec", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2193; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("span_dec", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2212; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "span_dec") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2193; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "span_dec") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2212; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
       goto __pyx_L5_argtuple_error;
@@ -66179,7 +65944,7 @@ static PyObject *__pyx_pw_3_sa_17span_dec(PyObject *__pyx_self, PyObject *__pyx_
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("span_dec", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2193; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("span_dec", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2212; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.span_dec", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -66190,7 +65955,7 @@ static PyObject *__pyx_pw_3_sa_17span_dec(PyObject *__pyx_self, PyObject *__pyx_
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2193
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2212
  *         k += 1
  * 
  * def span_dec(vec, i, j):             # <<<<<<<<<<<<<<
@@ -66211,7 +65976,7 @@ static PyObject *__pyx_pf_3_sa_16span_dec(CYTHON_UNUSED PyObject *__pyx_self, Py
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("span_dec", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2194
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2213
  * 
  * def span_dec(vec, i, j):
  *     k = i             # <<<<<<<<<<<<<<
@@ -66221,7 +65986,7 @@ static PyObject *__pyx_pf_3_sa_16span_dec(CYTHON_UNUSED PyObject *__pyx_self, Py
   __Pyx_INCREF(__pyx_v_i);
   __pyx_v_k = __pyx_v_i;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2195
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2214
  * def span_dec(vec, i, j):
  *     k = i
  *     while k <= j:             # <<<<<<<<<<<<<<
@@ -66229,12 +65994,12 @@ static PyObject *__pyx_pf_3_sa_16span_dec(CYTHON_UNUSED PyObject *__pyx_self, Py
  *         k += 1
  */
   while (1) {
-    __pyx_t_1 = PyObject_RichCompare(__pyx_v_k, __pyx_v_j, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2195; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2195; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_RichCompare(__pyx_v_k, __pyx_v_j, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     if (!__pyx_t_2) break;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2196
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2215
  *     k = i
  *     while k <= j:
  *         vec[k] -= 1             # <<<<<<<<<<<<<<
@@ -66242,21 +66007,21 @@ static PyObject *__pyx_pf_3_sa_16span_dec(CYTHON_UNUSED PyObject *__pyx_self, Py
  */
     __Pyx_INCREF(__pyx_v_k);
     __pyx_t_1 = __pyx_v_k;
-    __pyx_t_3 = PyObject_GetItem(__pyx_v_vec, __pyx_t_1); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_GetItem(__pyx_v_vec, __pyx_t_1); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_4 = PyNumber_InPlaceSubtract(__pyx_t_3, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyNumber_InPlaceSubtract(__pyx_t_3, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (PyObject_SetItem(__pyx_v_vec, __pyx_t_1, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyObject_SetItem(__pyx_v_vec, __pyx_t_1, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2197
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2216
  *     while k <= j:
  *         vec[k] -= 1
  *         k += 1             # <<<<<<<<<<<<<<
  */
-    __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_k, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_k, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2216; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_v_k);
     __pyx_v_k = __pyx_t_1;
@@ -66516,14 +66281,14 @@ static PyObject *__pyx_pw_3_sa_13FeatureVector_5__iter__(PyObject *__pyx_v_self)
  */
 
 static PyObject *__pyx_pf_3_sa_13FeatureVector_4__iter__(struct __pyx_obj_3_sa_FeatureVector *__pyx_v_self) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_29___iter__ *__pyx_cur_scope;
+  struct __pyx_obj_3_sa___pyx_scope_struct_27___iter__ *__pyx_cur_scope;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   int __pyx_lineno = 0;
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__iter__", 0);
-  __pyx_cur_scope = (struct __pyx_obj_3_sa___pyx_scope_struct_29___iter__ *)__pyx_ptype_3_sa___pyx_scope_struct_29___iter__->tp_new(__pyx_ptype_3_sa___pyx_scope_struct_29___iter__, __pyx_empty_tuple, NULL);
+  __pyx_cur_scope = (struct __pyx_obj_3_sa___pyx_scope_struct_27___iter__ *)__pyx_ptype_3_sa___pyx_scope_struct_27___iter__->tp_new(__pyx_ptype_3_sa___pyx_scope_struct_27___iter__, __pyx_empty_tuple, NULL);
   if (unlikely(!__pyx_cur_scope)) {
     __Pyx_RefNannyFinishContext();
     return NULL;
@@ -66553,7 +66318,7 @@ static PyObject *__pyx_pf_3_sa_13FeatureVector_4__iter__(struct __pyx_obj_3_sa_F
 
 static PyObject *__pyx_gb_3_sa_13FeatureVector_6generator5(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value) /* generator body */
 {
-  struct __pyx_obj_3_sa___pyx_scope_struct_29___iter__ *__pyx_cur_scope = ((struct __pyx_obj_3_sa___pyx_scope_struct_29___iter__ *)__pyx_generator->closure);
+  struct __pyx_obj_3_sa___pyx_scope_struct_27___iter__ *__pyx_cur_scope = ((struct __pyx_obj_3_sa___pyx_scope_struct_27___iter__ *)__pyx_generator->closure);
   PyObject *__pyx_r = NULL;
   int __pyx_t_1;
   unsigned int __pyx_t_2;
@@ -66646,7 +66411,7 @@ static PyObject *__pyx_pw_3_sa_13FeatureVector_8__str__(PyObject *__pyx_v_self)
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
-static PyObject *__pyx_gb_3_sa_13FeatureVector_7__str___2generator19(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value); /* proto */
+static PyObject *__pyx_gb_3_sa_13FeatureVector_7__str___2generator17(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value); /* proto */
 
 /* "/home/m/workspace/cdec/python/src/sa/features.pxi":21
  * 
@@ -66657,24 +66422,24 @@ static PyObject *__pyx_gb_3_sa_13FeatureVector_7__str___2generator19(__pyx_Gener
  */
 
 static PyObject *__pyx_pf_3_sa_13FeatureVector_7__str___genexpr(PyObject *__pyx_self) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_31_genexpr *__pyx_cur_scope;
+  struct __pyx_obj_3_sa___pyx_scope_struct_29_genexpr *__pyx_cur_scope;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   int __pyx_lineno = 0;
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("genexpr", 0);
-  __pyx_cur_scope = (struct __pyx_obj_3_sa___pyx_scope_struct_31_genexpr *)__pyx_ptype_3_sa___pyx_scope_struct_31_genexpr->tp_new(__pyx_ptype_3_sa___pyx_scope_struct_31_genexpr, __pyx_empty_tuple, NULL);
+  __pyx_cur_scope = (struct __pyx_obj_3_sa___pyx_scope_struct_29_genexpr *)__pyx_ptype_3_sa___pyx_scope_struct_29_genexpr->tp_new(__pyx_ptype_3_sa___pyx_scope_struct_29_genexpr, __pyx_empty_tuple, NULL);
   if (unlikely(!__pyx_cur_scope)) {
     __Pyx_RefNannyFinishContext();
     return NULL;
   }
   __Pyx_GOTREF(__pyx_cur_scope);
-  __pyx_cur_scope->__pyx_outer_scope = (struct __pyx_obj_3_sa___pyx_scope_struct_30___str__ *) __pyx_self;
+  __pyx_cur_scope->__pyx_outer_scope = (struct __pyx_obj_3_sa___pyx_scope_struct_28___str__ *) __pyx_self;
   __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_outer_scope));
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_outer_scope);
   {
-    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_13FeatureVector_7__str___2generator19, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[13]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_13FeatureVector_7__str___2generator17, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[13]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_cur_scope);
     __Pyx_RefNannyFinishContext();
     return (PyObject *) gen;
@@ -66692,9 +66457,9 @@ static PyObject *__pyx_pf_3_sa_13FeatureVector_7__str___genexpr(PyObject *__pyx_
   return __pyx_r;
 }
 
-static PyObject *__pyx_gb_3_sa_13FeatureVector_7__str___2generator19(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value) /* generator body */
+static PyObject *__pyx_gb_3_sa_13FeatureVector_7__str___2generator17(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value) /* generator body */
 {
-  struct __pyx_obj_3_sa___pyx_scope_struct_31_genexpr *__pyx_cur_scope = ((struct __pyx_obj_3_sa___pyx_scope_struct_31_genexpr *)__pyx_generator->closure);
+  struct __pyx_obj_3_sa___pyx_scope_struct_29_genexpr *__pyx_cur_scope = ((struct __pyx_obj_3_sa___pyx_scope_struct_29_genexpr *)__pyx_generator->closure);
   PyObject *__pyx_r = NULL;
   PyObject *__pyx_t_1 = NULL;
   Py_ssize_t __pyx_t_2;
@@ -66751,7 +66516,7 @@ static PyObject *__pyx_gb_3_sa_13FeatureVector_7__str___2generator19(__pyx_Gener
     __Pyx_GIVEREF(__pyx_t_4);
     __pyx_cur_scope->__pyx_v_feat = __pyx_t_4;
     __pyx_t_4 = 0;
-    __pyx_t_4 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_157), __pyx_cur_scope->__pyx_v_feat); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[13]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_154), __pyx_cur_scope->__pyx_v_feat); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[13]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(((PyObject *)__pyx_t_4));
     __pyx_r = ((PyObject *)__pyx_t_4);
     __pyx_t_4 = 0;
@@ -66796,7 +66561,7 @@ static PyObject *__pyx_gb_3_sa_13FeatureVector_7__str___2generator19(__pyx_Gener
  */
 
 static PyObject *__pyx_pf_3_sa_13FeatureVector_7__str__(struct __pyx_obj_3_sa_FeatureVector *__pyx_v_self) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_30___str__ *__pyx_cur_scope;
+  struct __pyx_obj_3_sa___pyx_scope_struct_28___str__ *__pyx_cur_scope;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -66806,7 +66571,7 @@ static PyObject *__pyx_pf_3_sa_13FeatureVector_7__str__(struct __pyx_obj_3_sa_Fe
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__str__", 0);
-  __pyx_cur_scope = (struct __pyx_obj_3_sa___pyx_scope_struct_30___str__ *)__pyx_ptype_3_sa___pyx_scope_struct_30___str__->tp_new(__pyx_ptype_3_sa___pyx_scope_struct_30___str__, __pyx_empty_tuple, NULL);
+  __pyx_cur_scope = (struct __pyx_obj_3_sa___pyx_scope_struct_28___str__ *)__pyx_ptype_3_sa___pyx_scope_struct_28___str__->tp_new(__pyx_ptype_3_sa___pyx_scope_struct_28___str__, __pyx_empty_tuple, NULL);
   if (unlikely(!__pyx_cur_scope)) {
     __Pyx_RefNannyFinishContext();
     return NULL;
@@ -72097,6 +71862,7 @@ static PyObject *__pyx_tp_new_3_sa_HieroCachingRuleFactory(PyTypeObject *t, PyOb
   p->fid2symid = ((struct __pyx_obj_3_sa_IntList *)Py_None); Py_INCREF(Py_None);
   p->findexes = ((struct __pyx_obj_3_sa_IntList *)Py_None); Py_INCREF(Py_None);
   p->findexes1 = ((struct __pyx_obj_3_sa_IntList *)Py_None); Py_INCREF(Py_None);
+  p->samples_f = Py_None; Py_INCREF(Py_None);
   p->phrases_f = Py_None; Py_INCREF(Py_None);
   p->phrases_e = Py_None; Py_INCREF(Py_None);
   p->phrases_fe = Py_None; Py_INCREF(Py_None);
@@ -72128,6 +71894,7 @@ static void __pyx_tp_dealloc_3_sa_HieroCachingRuleFactory(PyObject *o) {
   Py_CLEAR(p->fid2symid);
   Py_CLEAR(p->findexes);
   Py_CLEAR(p->findexes1);
+  Py_CLEAR(p->samples_f);
   Py_CLEAR(p->phrases_f);
   Py_CLEAR(p->phrases_e);
   Py_CLEAR(p->phrases_fe);
@@ -72189,6 +71956,9 @@ static int __pyx_tp_traverse_3_sa_HieroCachingRuleFactory(PyObject *o, visitproc
   if (p->findexes1) {
     e = (*v)(((PyObject*)p->findexes1), a); if (e) return e;
   }
+  if (p->samples_f) {
+    e = (*v)(p->samples_f, a); if (e) return e;
+  }
   if (p->phrases_f) {
     e = (*v)(p->phrases_f, a); if (e) return e;
   }
@@ -72264,6 +72034,9 @@ static int __pyx_tp_clear_3_sa_HieroCachingRuleFactory(PyObject *o) {
   tmp = ((PyObject*)p->findexes1);
   p->findexes1 = ((struct __pyx_obj_3_sa_IntList *)Py_None); Py_INCREF(Py_None);
   Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->samples_f);
+  p->samples_f = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
   tmp = ((PyObject*)p->phrases_f);
   p->phrases_f = Py_None; Py_INCREF(Py_None);
   Py_XDECREF(tmp);
@@ -72304,8 +72077,9 @@ static PyMethodDef __pyx_methods_3_sa_HieroCachingRuleFactory[] = {
   {__Pyx_NAMESTR("form_rule"), (PyCFunction)__pyx_pw_3_sa_23HieroCachingRuleFactory_28form_rule, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)},
   {__Pyx_NAMESTR("fmt_rule"), (PyCFunction)__pyx_pw_3_sa_23HieroCachingRuleFactory_30fmt_rule, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)},
   {__Pyx_NAMESTR("dump_online_stats"), (PyCFunction)__pyx_pw_3_sa_23HieroCachingRuleFactory_32dump_online_stats, METH_NOARGS, __Pyx_DOCSTR(0)},
-  {__Pyx_NAMESTR("online_ctx_lookup"), (PyCFunction)__pyx_pw_3_sa_23HieroCachingRuleFactory_34online_ctx_lookup, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)},
-  {__Pyx_NAMESTR("online_match"), (PyCFunction)__pyx_pw_3_sa_23HieroCachingRuleFactory_36online_match, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("dump_online_rules"), (PyCFunction)__pyx_pw_3_sa_23HieroCachingRuleFactory_34dump_online_rules, METH_NOARGS, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("online_ctx_lookup"), (PyCFunction)__pyx_pw_3_sa_23HieroCachingRuleFactory_36online_ctx_lookup, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)},
+  {__Pyx_NAMESTR("get_f_phrases"), (PyCFunction)__pyx_pw_3_sa_23HieroCachingRuleFactory_38get_f_phrases, METH_O, __Pyx_DOCSTR(0)},
   {0, 0, 0, 0}
 };
 
@@ -76561,6 +76335,8 @@ static PyObject *__pyx_tp_new_3_sa___pyx_scope_struct_19_input(PyTypeObject *t,
   p->__pyx_v_input_match = 0;
   p->__pyx_v_is_shadow_path = 0;
   p->__pyx_v_key = 0;
+  p->__pyx_v_lex_i = 0;
+  p->__pyx_v_lex_j = 0;
   p->__pyx_v_loc = 0;
   p->__pyx_v_locs = 0;
   p->__pyx_v_max_locs = 0;
@@ -76619,6 +76395,8 @@ static void __pyx_tp_dealloc_3_sa___pyx_scope_struct_19_input(PyObject *o) {
   Py_CLEAR(p->__pyx_v_input_match);
   Py_CLEAR(p->__pyx_v_is_shadow_path);
   Py_CLEAR(p->__pyx_v_key);
+  Py_CLEAR(p->__pyx_v_lex_i);
+  Py_CLEAR(p->__pyx_v_lex_j);
   Py_CLEAR(p->__pyx_v_loc);
   Py_CLEAR(p->__pyx_v_locs);
   Py_CLEAR(p->__pyx_v_max_locs);
@@ -76724,6 +76502,12 @@ static int __pyx_tp_traverse_3_sa___pyx_scope_struct_19_input(PyObject *o, visit
   if (p->__pyx_v_key) {
     e = (*v)(p->__pyx_v_key, a); if (e) return e;
   }
+  if (p->__pyx_v_lex_i) {
+    e = (*v)(p->__pyx_v_lex_i, a); if (e) return e;
+  }
+  if (p->__pyx_v_lex_j) {
+    e = (*v)(p->__pyx_v_lex_j, a); if (e) return e;
+  }
   if (p->__pyx_v_loc) {
     e = (*v)(p->__pyx_v_loc, a); if (e) return e;
   }
@@ -76889,6 +76673,12 @@ static int __pyx_tp_clear_3_sa___pyx_scope_struct_19_input(PyObject *o) {
   tmp = ((PyObject*)p->__pyx_v_key);
   p->__pyx_v_key = ((PyObject*)Py_None); Py_INCREF(Py_None);
   Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->__pyx_v_lex_i);
+  p->__pyx_v_lex_i = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->__pyx_v_lex_j);
+  p->__pyx_v_lex_j = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
   tmp = ((PyObject*)p->__pyx_v_loc);
   p->__pyx_v_loc = Py_None; Py_INCREF(Py_None);
   Py_XDECREF(tmp);
@@ -77721,222 +77511,7 @@ static PyNumberMethods __pyx_tp_as_number___pyx_scope_struct_22_form_rule = {
   #endif
 };
 
-static PySequenceMethods __pyx_tp_as_sequence___pyx_scope_struct_22_form_rule = {
-  0, /*sq_length*/
-  0, /*sq_concat*/
-  0, /*sq_repeat*/
-  0, /*sq_item*/
-  0, /*sq_slice*/
-  0, /*sq_ass_item*/
-  0, /*sq_ass_slice*/
-  0, /*sq_contains*/
-  0, /*sq_inplace_concat*/
-  0, /*sq_inplace_repeat*/
-};
-
-static PyMappingMethods __pyx_tp_as_mapping___pyx_scope_struct_22_form_rule = {
-  0, /*mp_length*/
-  0, /*mp_subscript*/
-  0, /*mp_ass_subscript*/
-};
-
-static PyBufferProcs __pyx_tp_as_buffer___pyx_scope_struct_22_form_rule = {
-  #if PY_MAJOR_VERSION < 3
-  0, /*bf_getreadbuffer*/
-  #endif
-  #if PY_MAJOR_VERSION < 3
-  0, /*bf_getwritebuffer*/
-  #endif
-  #if PY_MAJOR_VERSION < 3
-  0, /*bf_getsegcount*/
-  #endif
-  #if PY_MAJOR_VERSION < 3
-  0, /*bf_getcharbuffer*/
-  #endif
-  #if PY_VERSION_HEX >= 0x02060000
-  0, /*bf_getbuffer*/
-  #endif
-  #if PY_VERSION_HEX >= 0x02060000
-  0, /*bf_releasebuffer*/
-  #endif
-};
-
-static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_22_form_rule = {
-  PyVarObject_HEAD_INIT(0, 0)
-  __Pyx_NAMESTR("_sa.__pyx_scope_struct_22_form_rule"), /*tp_name*/
-  sizeof(struct __pyx_obj_3_sa___pyx_scope_struct_22_form_rule), /*tp_basicsize*/
-  0, /*tp_itemsize*/
-  __pyx_tp_dealloc_3_sa___pyx_scope_struct_22_form_rule, /*tp_dealloc*/
-  0, /*tp_print*/
-  0, /*tp_getattr*/
-  0, /*tp_setattr*/
-  #if PY_MAJOR_VERSION < 3
-  0, /*tp_compare*/
-  #else
-  0, /*reserved*/
-  #endif
-  0, /*tp_repr*/
-  &__pyx_tp_as_number___pyx_scope_struct_22_form_rule, /*tp_as_number*/
-  &__pyx_tp_as_sequence___pyx_scope_struct_22_form_rule, /*tp_as_sequence*/
-  &__pyx_tp_as_mapping___pyx_scope_struct_22_form_rule, /*tp_as_mapping*/
-  0, /*tp_hash*/
-  0, /*tp_call*/
-  0, /*tp_str*/
-  0, /*tp_getattro*/
-  0, /*tp_setattro*/
-  &__pyx_tp_as_buffer___pyx_scope_struct_22_form_rule, /*tp_as_buffer*/
-  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
-  0, /*tp_doc*/
-  __pyx_tp_traverse_3_sa___pyx_scope_struct_22_form_rule, /*tp_traverse*/
-  __pyx_tp_clear_3_sa___pyx_scope_struct_22_form_rule, /*tp_clear*/
-  0, /*tp_richcompare*/
-  0, /*tp_weaklistoffset*/
-  0, /*tp_iter*/
-  0, /*tp_iternext*/
-  __pyx_methods_3_sa___pyx_scope_struct_22_form_rule, /*tp_methods*/
-  0, /*tp_members*/
-  0, /*tp_getset*/
-  0, /*tp_base*/
-  0, /*tp_dict*/
-  0, /*tp_descr_get*/
-  0, /*tp_descr_set*/
-  0, /*tp_dictoffset*/
-  0, /*tp_init*/
-  0, /*tp_alloc*/
-  __pyx_tp_new_3_sa___pyx_scope_struct_22_form_rule, /*tp_new*/
-  0, /*tp_free*/
-  0, /*tp_is_gc*/
-  0, /*tp_bases*/
-  0, /*tp_mro*/
-  0, /*tp_cache*/
-  0, /*tp_subclasses*/
-  0, /*tp_weaklist*/
-  0, /*tp_del*/
-  #if PY_VERSION_HEX >= 0x02060000
-  0, /*tp_version_tag*/
-  #endif
-};
-
-static PyObject *__pyx_tp_new_3_sa___pyx_scope_struct_23_genexpr(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_23_genexpr *p;
-  PyObject *o = (*t->tp_alloc)(t, 0);
-  if (!o) return 0;
-  p = ((struct __pyx_obj_3_sa___pyx_scope_struct_23_genexpr *)o);
-  p->__pyx_outer_scope = 0;
-  p->__pyx_v_i = 0;
-  p->__pyx_v_j = 0;
-  p->__pyx_t_0 = 0;
-  return o;
-}
-
-static void __pyx_tp_dealloc_3_sa___pyx_scope_struct_23_genexpr(PyObject *o) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_23_genexpr *p = (struct __pyx_obj_3_sa___pyx_scope_struct_23_genexpr *)o;
-  Py_CLEAR(p->__pyx_outer_scope);
-  Py_CLEAR(p->__pyx_v_i);
-  Py_CLEAR(p->__pyx_v_j);
-  Py_CLEAR(p->__pyx_t_0);
-  (*Py_TYPE(o)->tp_free)(o);
-}
-
-static int __pyx_tp_traverse_3_sa___pyx_scope_struct_23_genexpr(PyObject *o, visitproc v, void *a) {
-  int e;
-  struct __pyx_obj_3_sa___pyx_scope_struct_23_genexpr *p = (struct __pyx_obj_3_sa___pyx_scope_struct_23_genexpr *)o;
-  if (p->__pyx_outer_scope) {
-    e = (*v)(((PyObject*)p->__pyx_outer_scope), a); if (e) return e;
-  }
-  if (p->__pyx_v_i) {
-    e = (*v)(p->__pyx_v_i, a); if (e) return e;
-  }
-  if (p->__pyx_v_j) {
-    e = (*v)(p->__pyx_v_j, a); if (e) return e;
-  }
-  if (p->__pyx_t_0) {
-    e = (*v)(p->__pyx_t_0, a); if (e) return e;
-  }
-  return 0;
-}
-
-static int __pyx_tp_clear_3_sa___pyx_scope_struct_23_genexpr(PyObject *o) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_23_genexpr *p = (struct __pyx_obj_3_sa___pyx_scope_struct_23_genexpr *)o;
-  PyObject* tmp;
-  tmp = ((PyObject*)p->__pyx_outer_scope);
-  p->__pyx_outer_scope = ((struct __pyx_obj_3_sa___pyx_scope_struct_22_form_rule *)Py_None); Py_INCREF(Py_None);
-  Py_XDECREF(tmp);
-  tmp = ((PyObject*)p->__pyx_v_i);
-  p->__pyx_v_i = Py_None; Py_INCREF(Py_None);
-  Py_XDECREF(tmp);
-  tmp = ((PyObject*)p->__pyx_v_j);
-  p->__pyx_v_j = Py_None; Py_INCREF(Py_None);
-  Py_XDECREF(tmp);
-  tmp = ((PyObject*)p->__pyx_t_0);
-  p->__pyx_t_0 = Py_None; Py_INCREF(Py_None);
-  Py_XDECREF(tmp);
-  return 0;
-}
-
-static PyMethodDef __pyx_methods_3_sa___pyx_scope_struct_23_genexpr[] = {
-  {0, 0, 0, 0}
-};
-
-static PyNumberMethods __pyx_tp_as_number___pyx_scope_struct_23_genexpr = {
-  0, /*nb_add*/
-  0, /*nb_subtract*/
-  0, /*nb_multiply*/
-  #if PY_MAJOR_VERSION < 3
-  0, /*nb_divide*/
-  #endif
-  0, /*nb_remainder*/
-  0, /*nb_divmod*/
-  0, /*nb_power*/
-  0, /*nb_negative*/
-  0, /*nb_positive*/
-  0, /*nb_absolute*/
-  0, /*nb_nonzero*/
-  0, /*nb_invert*/
-  0, /*nb_lshift*/
-  0, /*nb_rshift*/
-  0, /*nb_and*/
-  0, /*nb_xor*/
-  0, /*nb_or*/
-  #if PY_MAJOR_VERSION < 3
-  0, /*nb_coerce*/
-  #endif
-  0, /*nb_int*/
-  #if PY_MAJOR_VERSION < 3
-  0, /*nb_long*/
-  #else
-  0, /*reserved*/
-  #endif
-  0, /*nb_float*/
-  #if PY_MAJOR_VERSION < 3
-  0, /*nb_oct*/
-  #endif
-  #if PY_MAJOR_VERSION < 3
-  0, /*nb_hex*/
-  #endif
-  0, /*nb_inplace_add*/
-  0, /*nb_inplace_subtract*/
-  0, /*nb_inplace_multiply*/
-  #if PY_MAJOR_VERSION < 3
-  0, /*nb_inplace_divide*/
-  #endif
-  0, /*nb_inplace_remainder*/
-  0, /*nb_inplace_power*/
-  0, /*nb_inplace_lshift*/
-  0, /*nb_inplace_rshift*/
-  0, /*nb_inplace_and*/
-  0, /*nb_inplace_xor*/
-  0, /*nb_inplace_or*/
-  0, /*nb_floor_divide*/
-  0, /*nb_true_divide*/
-  0, /*nb_inplace_floor_divide*/
-  0, /*nb_inplace_true_divide*/
-  #if PY_VERSION_HEX >= 0x02050000
-  0, /*nb_index*/
-  #endif
-};
-
-static PySequenceMethods __pyx_tp_as_sequence___pyx_scope_struct_23_genexpr = {
+static PySequenceMethods __pyx_tp_as_sequence___pyx_scope_struct_22_form_rule = {
   0, /*sq_length*/
   0, /*sq_concat*/
   0, /*sq_repeat*/
@@ -77949,13 +77524,13 @@ static PySequenceMethods __pyx_tp_as_sequence___pyx_scope_struct_23_genexpr = {
   0, /*sq_inplace_repeat*/
 };
 
-static PyMappingMethods __pyx_tp_as_mapping___pyx_scope_struct_23_genexpr = {
+static PyMappingMethods __pyx_tp_as_mapping___pyx_scope_struct_22_form_rule = {
   0, /*mp_length*/
   0, /*mp_subscript*/
   0, /*mp_ass_subscript*/
 };
 
-static PyBufferProcs __pyx_tp_as_buffer___pyx_scope_struct_23_genexpr = {
+static PyBufferProcs __pyx_tp_as_buffer___pyx_scope_struct_22_form_rule = {
   #if PY_MAJOR_VERSION < 3
   0, /*bf_getreadbuffer*/
   #endif
@@ -77976,12 +77551,12 @@ static PyBufferProcs __pyx_tp_as_buffer___pyx_scope_struct_23_genexpr = {
   #endif
 };
 
-static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_23_genexpr = {
+static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_22_form_rule = {
   PyVarObject_HEAD_INIT(0, 0)
-  __Pyx_NAMESTR("_sa.__pyx_scope_struct_23_genexpr"), /*tp_name*/
-  sizeof(struct __pyx_obj_3_sa___pyx_scope_struct_23_genexpr), /*tp_basicsize*/
+  __Pyx_NAMESTR("_sa.__pyx_scope_struct_22_form_rule"), /*tp_name*/
+  sizeof(struct __pyx_obj_3_sa___pyx_scope_struct_22_form_rule), /*tp_basicsize*/
   0, /*tp_itemsize*/
-  __pyx_tp_dealloc_3_sa___pyx_scope_struct_23_genexpr, /*tp_dealloc*/
+  __pyx_tp_dealloc_3_sa___pyx_scope_struct_22_form_rule, /*tp_dealloc*/
   0, /*tp_print*/
   0, /*tp_getattr*/
   0, /*tp_setattr*/
@@ -77991,24 +77566,24 @@ static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_23_genexpr = {
   0, /*reserved*/
   #endif
   0, /*tp_repr*/
-  &__pyx_tp_as_number___pyx_scope_struct_23_genexpr, /*tp_as_number*/
-  &__pyx_tp_as_sequence___pyx_scope_struct_23_genexpr, /*tp_as_sequence*/
-  &__pyx_tp_as_mapping___pyx_scope_struct_23_genexpr, /*tp_as_mapping*/
+  &__pyx_tp_as_number___pyx_scope_struct_22_form_rule, /*tp_as_number*/
+  &__pyx_tp_as_sequence___pyx_scope_struct_22_form_rule, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping___pyx_scope_struct_22_form_rule, /*tp_as_mapping*/
   0, /*tp_hash*/
   0, /*tp_call*/
   0, /*tp_str*/
   0, /*tp_getattro*/
   0, /*tp_setattro*/
-  &__pyx_tp_as_buffer___pyx_scope_struct_23_genexpr, /*tp_as_buffer*/
+  &__pyx_tp_as_buffer___pyx_scope_struct_22_form_rule, /*tp_as_buffer*/
   Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
   0, /*tp_doc*/
-  __pyx_tp_traverse_3_sa___pyx_scope_struct_23_genexpr, /*tp_traverse*/
-  __pyx_tp_clear_3_sa___pyx_scope_struct_23_genexpr, /*tp_clear*/
+  __pyx_tp_traverse_3_sa___pyx_scope_struct_22_form_rule, /*tp_traverse*/
+  __pyx_tp_clear_3_sa___pyx_scope_struct_22_form_rule, /*tp_clear*/
   0, /*tp_richcompare*/
   0, /*tp_weaklistoffset*/
   0, /*tp_iter*/
   0, /*tp_iternext*/
-  __pyx_methods_3_sa___pyx_scope_struct_23_genexpr, /*tp_methods*/
+  __pyx_methods_3_sa___pyx_scope_struct_22_form_rule, /*tp_methods*/
   0, /*tp_members*/
   0, /*tp_getset*/
   0, /*tp_base*/
@@ -78018,7 +77593,7 @@ static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_23_genexpr = {
   0, /*tp_dictoffset*/
   0, /*tp_init*/
   0, /*tp_alloc*/
-  __pyx_tp_new_3_sa___pyx_scope_struct_23_genexpr, /*tp_new*/
+  __pyx_tp_new_3_sa___pyx_scope_struct_22_form_rule, /*tp_new*/
   0, /*tp_free*/
   0, /*tp_is_gc*/
   0, /*tp_bases*/
@@ -78032,52 +77607,68 @@ static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_23_genexpr = {
   #endif
 };
 
-static PyObject *__pyx_tp_new_3_sa___pyx_scope_struct_24_fmt_rule(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_24_fmt_rule *p;
+static PyObject *__pyx_tp_new_3_sa___pyx_scope_struct_23_genexpr(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_3_sa___pyx_scope_struct_23_genexpr *p;
   PyObject *o = (*t->tp_alloc)(t, 0);
   if (!o) return 0;
-  p = ((struct __pyx_obj_3_sa___pyx_scope_struct_24_fmt_rule *)o);
-  p->__pyx_v_a = 0;
-  p->__pyx_v_self = 0;
+  p = ((struct __pyx_obj_3_sa___pyx_scope_struct_23_genexpr *)o);
+  p->__pyx_outer_scope = 0;
+  p->__pyx_v_i = 0;
+  p->__pyx_v_j = 0;
+  p->__pyx_t_0 = 0;
   return o;
 }
 
-static void __pyx_tp_dealloc_3_sa___pyx_scope_struct_24_fmt_rule(PyObject *o) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_24_fmt_rule *p = (struct __pyx_obj_3_sa___pyx_scope_struct_24_fmt_rule *)o;
-  Py_CLEAR(p->__pyx_v_a);
-  Py_CLEAR(p->__pyx_v_self);
+static void __pyx_tp_dealloc_3_sa___pyx_scope_struct_23_genexpr(PyObject *o) {
+  struct __pyx_obj_3_sa___pyx_scope_struct_23_genexpr *p = (struct __pyx_obj_3_sa___pyx_scope_struct_23_genexpr *)o;
+  Py_CLEAR(p->__pyx_outer_scope);
+  Py_CLEAR(p->__pyx_v_i);
+  Py_CLEAR(p->__pyx_v_j);
+  Py_CLEAR(p->__pyx_t_0);
   (*Py_TYPE(o)->tp_free)(o);
 }
 
-static int __pyx_tp_traverse_3_sa___pyx_scope_struct_24_fmt_rule(PyObject *o, visitproc v, void *a) {
+static int __pyx_tp_traverse_3_sa___pyx_scope_struct_23_genexpr(PyObject *o, visitproc v, void *a) {
   int e;
-  struct __pyx_obj_3_sa___pyx_scope_struct_24_fmt_rule *p = (struct __pyx_obj_3_sa___pyx_scope_struct_24_fmt_rule *)o;
-  if (p->__pyx_v_a) {
-    e = (*v)(p->__pyx_v_a, a); if (e) return e;
+  struct __pyx_obj_3_sa___pyx_scope_struct_23_genexpr *p = (struct __pyx_obj_3_sa___pyx_scope_struct_23_genexpr *)o;
+  if (p->__pyx_outer_scope) {
+    e = (*v)(((PyObject*)p->__pyx_outer_scope), a); if (e) return e;
   }
-  if (p->__pyx_v_self) {
-    e = (*v)(((PyObject*)p->__pyx_v_self), a); if (e) return e;
+  if (p->__pyx_v_i) {
+    e = (*v)(p->__pyx_v_i, a); if (e) return e;
+  }
+  if (p->__pyx_v_j) {
+    e = (*v)(p->__pyx_v_j, a); if (e) return e;
+  }
+  if (p->__pyx_t_0) {
+    e = (*v)(p->__pyx_t_0, a); if (e) return e;
   }
   return 0;
 }
 
-static int __pyx_tp_clear_3_sa___pyx_scope_struct_24_fmt_rule(PyObject *o) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_24_fmt_rule *p = (struct __pyx_obj_3_sa___pyx_scope_struct_24_fmt_rule *)o;
+static int __pyx_tp_clear_3_sa___pyx_scope_struct_23_genexpr(PyObject *o) {
+  struct __pyx_obj_3_sa___pyx_scope_struct_23_genexpr *p = (struct __pyx_obj_3_sa___pyx_scope_struct_23_genexpr *)o;
   PyObject* tmp;
-  tmp = ((PyObject*)p->__pyx_v_a);
-  p->__pyx_v_a = Py_None; Py_INCREF(Py_None);
+  tmp = ((PyObject*)p->__pyx_outer_scope);
+  p->__pyx_outer_scope = ((struct __pyx_obj_3_sa___pyx_scope_struct_22_form_rule *)Py_None); Py_INCREF(Py_None);
   Py_XDECREF(tmp);
-  tmp = ((PyObject*)p->__pyx_v_self);
-  p->__pyx_v_self = ((struct __pyx_obj_3_sa_HieroCachingRuleFactory *)Py_None); Py_INCREF(Py_None);
+  tmp = ((PyObject*)p->__pyx_v_i);
+  p->__pyx_v_i = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->__pyx_v_j);
+  p->__pyx_v_j = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->__pyx_t_0);
+  p->__pyx_t_0 = Py_None; Py_INCREF(Py_None);
   Py_XDECREF(tmp);
   return 0;
 }
 
-static PyMethodDef __pyx_methods_3_sa___pyx_scope_struct_24_fmt_rule[] = {
+static PyMethodDef __pyx_methods_3_sa___pyx_scope_struct_23_genexpr[] = {
   {0, 0, 0, 0}
 };
 
-static PyNumberMethods __pyx_tp_as_number___pyx_scope_struct_24_fmt_rule = {
+static PyNumberMethods __pyx_tp_as_number___pyx_scope_struct_23_genexpr = {
   0, /*nb_add*/
   0, /*nb_subtract*/
   0, /*nb_multiply*/
@@ -78135,7 +77726,7 @@ static PyNumberMethods __pyx_tp_as_number___pyx_scope_struct_24_fmt_rule = {
   #endif
 };
 
-static PySequenceMethods __pyx_tp_as_sequence___pyx_scope_struct_24_fmt_rule = {
+static PySequenceMethods __pyx_tp_as_sequence___pyx_scope_struct_23_genexpr = {
   0, /*sq_length*/
   0, /*sq_concat*/
   0, /*sq_repeat*/
@@ -78148,13 +77739,13 @@ static PySequenceMethods __pyx_tp_as_sequence___pyx_scope_struct_24_fmt_rule = {
   0, /*sq_inplace_repeat*/
 };
 
-static PyMappingMethods __pyx_tp_as_mapping___pyx_scope_struct_24_fmt_rule = {
+static PyMappingMethods __pyx_tp_as_mapping___pyx_scope_struct_23_genexpr = {
   0, /*mp_length*/
   0, /*mp_subscript*/
   0, /*mp_ass_subscript*/
 };
 
-static PyBufferProcs __pyx_tp_as_buffer___pyx_scope_struct_24_fmt_rule = {
+static PyBufferProcs __pyx_tp_as_buffer___pyx_scope_struct_23_genexpr = {
   #if PY_MAJOR_VERSION < 3
   0, /*bf_getreadbuffer*/
   #endif
@@ -78175,12 +77766,12 @@ static PyBufferProcs __pyx_tp_as_buffer___pyx_scope_struct_24_fmt_rule = {
   #endif
 };
 
-static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_24_fmt_rule = {
+static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_23_genexpr = {
   PyVarObject_HEAD_INIT(0, 0)
-  __Pyx_NAMESTR("_sa.__pyx_scope_struct_24_fmt_rule"), /*tp_name*/
-  sizeof(struct __pyx_obj_3_sa___pyx_scope_struct_24_fmt_rule), /*tp_basicsize*/
+  __Pyx_NAMESTR("_sa.__pyx_scope_struct_23_genexpr"), /*tp_name*/
+  sizeof(struct __pyx_obj_3_sa___pyx_scope_struct_23_genexpr), /*tp_basicsize*/
   0, /*tp_itemsize*/
-  __pyx_tp_dealloc_3_sa___pyx_scope_struct_24_fmt_rule, /*tp_dealloc*/
+  __pyx_tp_dealloc_3_sa___pyx_scope_struct_23_genexpr, /*tp_dealloc*/
   0, /*tp_print*/
   0, /*tp_getattr*/
   0, /*tp_setattr*/
@@ -78190,24 +77781,24 @@ static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_24_fmt_rule = {
   0, /*reserved*/
   #endif
   0, /*tp_repr*/
-  &__pyx_tp_as_number___pyx_scope_struct_24_fmt_rule, /*tp_as_number*/
-  &__pyx_tp_as_sequence___pyx_scope_struct_24_fmt_rule, /*tp_as_sequence*/
-  &__pyx_tp_as_mapping___pyx_scope_struct_24_fmt_rule, /*tp_as_mapping*/
+  &__pyx_tp_as_number___pyx_scope_struct_23_genexpr, /*tp_as_number*/
+  &__pyx_tp_as_sequence___pyx_scope_struct_23_genexpr, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping___pyx_scope_struct_23_genexpr, /*tp_as_mapping*/
   0, /*tp_hash*/
   0, /*tp_call*/
   0, /*tp_str*/
   0, /*tp_getattro*/
   0, /*tp_setattro*/
-  &__pyx_tp_as_buffer___pyx_scope_struct_24_fmt_rule, /*tp_as_buffer*/
+  &__pyx_tp_as_buffer___pyx_scope_struct_23_genexpr, /*tp_as_buffer*/
   Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
   0, /*tp_doc*/
-  __pyx_tp_traverse_3_sa___pyx_scope_struct_24_fmt_rule, /*tp_traverse*/
-  __pyx_tp_clear_3_sa___pyx_scope_struct_24_fmt_rule, /*tp_clear*/
+  __pyx_tp_traverse_3_sa___pyx_scope_struct_23_genexpr, /*tp_traverse*/
+  __pyx_tp_clear_3_sa___pyx_scope_struct_23_genexpr, /*tp_clear*/
   0, /*tp_richcompare*/
   0, /*tp_weaklistoffset*/
   0, /*tp_iter*/
   0, /*tp_iternext*/
-  __pyx_methods_3_sa___pyx_scope_struct_24_fmt_rule, /*tp_methods*/
+  __pyx_methods_3_sa___pyx_scope_struct_23_genexpr, /*tp_methods*/
   0, /*tp_members*/
   0, /*tp_getset*/
   0, /*tp_base*/
@@ -78217,7 +77808,7 @@ static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_24_fmt_rule = {
   0, /*tp_dictoffset*/
   0, /*tp_init*/
   0, /*tp_alloc*/
-  __pyx_tp_new_3_sa___pyx_scope_struct_24_fmt_rule, /*tp_new*/
+  __pyx_tp_new_3_sa___pyx_scope_struct_23_genexpr, /*tp_new*/
   0, /*tp_free*/
   0, /*tp_is_gc*/
   0, /*tp_bases*/
@@ -78231,60 +77822,52 @@ static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_24_fmt_rule = {
   #endif
 };
 
-static PyObject *__pyx_tp_new_3_sa___pyx_scope_struct_25_genexpr(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_25_genexpr *p;
+static PyObject *__pyx_tp_new_3_sa___pyx_scope_struct_24_fmt_rule(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_3_sa___pyx_scope_struct_24_fmt_rule *p;
   PyObject *o = (*t->tp_alloc)(t, 0);
   if (!o) return 0;
-  p = ((struct __pyx_obj_3_sa___pyx_scope_struct_25_genexpr *)o);
-  p->__pyx_outer_scope = 0;
-  p->__pyx_v_packed = 0;
-  p->__pyx_t_0 = 0;
+  p = ((struct __pyx_obj_3_sa___pyx_scope_struct_24_fmt_rule *)o);
+  p->__pyx_v_a = 0;
+  p->__pyx_v_self = 0;
   return o;
 }
 
-static void __pyx_tp_dealloc_3_sa___pyx_scope_struct_25_genexpr(PyObject *o) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_25_genexpr *p = (struct __pyx_obj_3_sa___pyx_scope_struct_25_genexpr *)o;
-  Py_CLEAR(p->__pyx_outer_scope);
-  Py_CLEAR(p->__pyx_v_packed);
-  Py_CLEAR(p->__pyx_t_0);
+static void __pyx_tp_dealloc_3_sa___pyx_scope_struct_24_fmt_rule(PyObject *o) {
+  struct __pyx_obj_3_sa___pyx_scope_struct_24_fmt_rule *p = (struct __pyx_obj_3_sa___pyx_scope_struct_24_fmt_rule *)o;
+  Py_CLEAR(p->__pyx_v_a);
+  Py_CLEAR(p->__pyx_v_self);
   (*Py_TYPE(o)->tp_free)(o);
 }
 
-static int __pyx_tp_traverse_3_sa___pyx_scope_struct_25_genexpr(PyObject *o, visitproc v, void *a) {
+static int __pyx_tp_traverse_3_sa___pyx_scope_struct_24_fmt_rule(PyObject *o, visitproc v, void *a) {
   int e;
-  struct __pyx_obj_3_sa___pyx_scope_struct_25_genexpr *p = (struct __pyx_obj_3_sa___pyx_scope_struct_25_genexpr *)o;
-  if (p->__pyx_outer_scope) {
-    e = (*v)(((PyObject*)p->__pyx_outer_scope), a); if (e) return e;
-  }
-  if (p->__pyx_v_packed) {
-    e = (*v)(p->__pyx_v_packed, a); if (e) return e;
+  struct __pyx_obj_3_sa___pyx_scope_struct_24_fmt_rule *p = (struct __pyx_obj_3_sa___pyx_scope_struct_24_fmt_rule *)o;
+  if (p->__pyx_v_a) {
+    e = (*v)(p->__pyx_v_a, a); if (e) return e;
   }
-  if (p->__pyx_t_0) {
-    e = (*v)(p->__pyx_t_0, a); if (e) return e;
+  if (p->__pyx_v_self) {
+    e = (*v)(((PyObject*)p->__pyx_v_self), a); if (e) return e;
   }
   return 0;
 }
 
-static int __pyx_tp_clear_3_sa___pyx_scope_struct_25_genexpr(PyObject *o) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_25_genexpr *p = (struct __pyx_obj_3_sa___pyx_scope_struct_25_genexpr *)o;
+static int __pyx_tp_clear_3_sa___pyx_scope_struct_24_fmt_rule(PyObject *o) {
+  struct __pyx_obj_3_sa___pyx_scope_struct_24_fmt_rule *p = (struct __pyx_obj_3_sa___pyx_scope_struct_24_fmt_rule *)o;
   PyObject* tmp;
-  tmp = ((PyObject*)p->__pyx_outer_scope);
-  p->__pyx_outer_scope = ((struct __pyx_obj_3_sa___pyx_scope_struct_24_fmt_rule *)Py_None); Py_INCREF(Py_None);
-  Py_XDECREF(tmp);
-  tmp = ((PyObject*)p->__pyx_v_packed);
-  p->__pyx_v_packed = Py_None; Py_INCREF(Py_None);
+  tmp = ((PyObject*)p->__pyx_v_a);
+  p->__pyx_v_a = Py_None; Py_INCREF(Py_None);
   Py_XDECREF(tmp);
-  tmp = ((PyObject*)p->__pyx_t_0);
-  p->__pyx_t_0 = Py_None; Py_INCREF(Py_None);
+  tmp = ((PyObject*)p->__pyx_v_self);
+  p->__pyx_v_self = ((struct __pyx_obj_3_sa_HieroCachingRuleFactory *)Py_None); Py_INCREF(Py_None);
   Py_XDECREF(tmp);
   return 0;
 }
 
-static PyMethodDef __pyx_methods_3_sa___pyx_scope_struct_25_genexpr[] = {
+static PyMethodDef __pyx_methods_3_sa___pyx_scope_struct_24_fmt_rule[] = {
   {0, 0, 0, 0}
 };
 
-static PyNumberMethods __pyx_tp_as_number___pyx_scope_struct_25_genexpr = {
+static PyNumberMethods __pyx_tp_as_number___pyx_scope_struct_24_fmt_rule = {
   0, /*nb_add*/
   0, /*nb_subtract*/
   0, /*nb_multiply*/
@@ -78342,7 +77925,7 @@ static PyNumberMethods __pyx_tp_as_number___pyx_scope_struct_25_genexpr = {
   #endif
 };
 
-static PySequenceMethods __pyx_tp_as_sequence___pyx_scope_struct_25_genexpr = {
+static PySequenceMethods __pyx_tp_as_sequence___pyx_scope_struct_24_fmt_rule = {
   0, /*sq_length*/
   0, /*sq_concat*/
   0, /*sq_repeat*/
@@ -78355,13 +77938,13 @@ static PySequenceMethods __pyx_tp_as_sequence___pyx_scope_struct_25_genexpr = {
   0, /*sq_inplace_repeat*/
 };
 
-static PyMappingMethods __pyx_tp_as_mapping___pyx_scope_struct_25_genexpr = {
+static PyMappingMethods __pyx_tp_as_mapping___pyx_scope_struct_24_fmt_rule = {
   0, /*mp_length*/
   0, /*mp_subscript*/
   0, /*mp_ass_subscript*/
 };
 
-static PyBufferProcs __pyx_tp_as_buffer___pyx_scope_struct_25_genexpr = {
+static PyBufferProcs __pyx_tp_as_buffer___pyx_scope_struct_24_fmt_rule = {
   #if PY_MAJOR_VERSION < 3
   0, /*bf_getreadbuffer*/
   #endif
@@ -78382,12 +77965,12 @@ static PyBufferProcs __pyx_tp_as_buffer___pyx_scope_struct_25_genexpr = {
   #endif
 };
 
-static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_25_genexpr = {
+static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_24_fmt_rule = {
   PyVarObject_HEAD_INIT(0, 0)
-  __Pyx_NAMESTR("_sa.__pyx_scope_struct_25_genexpr"), /*tp_name*/
-  sizeof(struct __pyx_obj_3_sa___pyx_scope_struct_25_genexpr), /*tp_basicsize*/
+  __Pyx_NAMESTR("_sa.__pyx_scope_struct_24_fmt_rule"), /*tp_name*/
+  sizeof(struct __pyx_obj_3_sa___pyx_scope_struct_24_fmt_rule), /*tp_basicsize*/
   0, /*tp_itemsize*/
-  __pyx_tp_dealloc_3_sa___pyx_scope_struct_25_genexpr, /*tp_dealloc*/
+  __pyx_tp_dealloc_3_sa___pyx_scope_struct_24_fmt_rule, /*tp_dealloc*/
   0, /*tp_print*/
   0, /*tp_getattr*/
   0, /*tp_setattr*/
@@ -78397,24 +77980,24 @@ static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_25_genexpr = {
   0, /*reserved*/
   #endif
   0, /*tp_repr*/
-  &__pyx_tp_as_number___pyx_scope_struct_25_genexpr, /*tp_as_number*/
-  &__pyx_tp_as_sequence___pyx_scope_struct_25_genexpr, /*tp_as_sequence*/
-  &__pyx_tp_as_mapping___pyx_scope_struct_25_genexpr, /*tp_as_mapping*/
+  &__pyx_tp_as_number___pyx_scope_struct_24_fmt_rule, /*tp_as_number*/
+  &__pyx_tp_as_sequence___pyx_scope_struct_24_fmt_rule, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping___pyx_scope_struct_24_fmt_rule, /*tp_as_mapping*/
   0, /*tp_hash*/
   0, /*tp_call*/
   0, /*tp_str*/
   0, /*tp_getattro*/
   0, /*tp_setattro*/
-  &__pyx_tp_as_buffer___pyx_scope_struct_25_genexpr, /*tp_as_buffer*/
+  &__pyx_tp_as_buffer___pyx_scope_struct_24_fmt_rule, /*tp_as_buffer*/
   Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
   0, /*tp_doc*/
-  __pyx_tp_traverse_3_sa___pyx_scope_struct_25_genexpr, /*tp_traverse*/
-  __pyx_tp_clear_3_sa___pyx_scope_struct_25_genexpr, /*tp_clear*/
+  __pyx_tp_traverse_3_sa___pyx_scope_struct_24_fmt_rule, /*tp_traverse*/
+  __pyx_tp_clear_3_sa___pyx_scope_struct_24_fmt_rule, /*tp_clear*/
   0, /*tp_richcompare*/
   0, /*tp_weaklistoffset*/
   0, /*tp_iter*/
   0, /*tp_iternext*/
-  __pyx_methods_3_sa___pyx_scope_struct_25_genexpr, /*tp_methods*/
+  __pyx_methods_3_sa___pyx_scope_struct_24_fmt_rule, /*tp_methods*/
   0, /*tp_members*/
   0, /*tp_getset*/
   0, /*tp_base*/
@@ -78424,7 +78007,7 @@ static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_25_genexpr = {
   0, /*tp_dictoffset*/
   0, /*tp_init*/
   0, /*tp_alloc*/
-  __pyx_tp_new_3_sa___pyx_scope_struct_25_genexpr, /*tp_new*/
+  __pyx_tp_new_3_sa___pyx_scope_struct_24_fmt_rule, /*tp_new*/
   0, /*tp_free*/
   0, /*tp_is_gc*/
   0, /*tp_bases*/
@@ -78438,84 +78021,60 @@ static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_25_genexpr = {
   #endif
 };
 
-static PyObject *__pyx_tp_new_3_sa___pyx_scope_struct_26_online_match(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_26_online_match *p;
+static PyObject *__pyx_tp_new_3_sa___pyx_scope_struct_25_genexpr(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_3_sa___pyx_scope_struct_25_genexpr *p;
   PyObject *o = (*t->tp_alloc)(t, 0);
   if (!o) return 0;
-  p = ((struct __pyx_obj_3_sa___pyx_scope_struct_26_online_match *)o);
-  p->__pyx_v_extract = 0;
-  p->__pyx_v_f_len = 0;
-  p->__pyx_v_f_words = 0;
-  p->__pyx_v_matches = 0;
-  p->__pyx_v_seen_phrases = 0;
-  p->__pyx_v_self = 0;
+  p = ((struct __pyx_obj_3_sa___pyx_scope_struct_25_genexpr *)o);
+  p->__pyx_outer_scope = 0;
+  p->__pyx_v_packed = 0;
+  p->__pyx_t_0 = 0;
   return o;
 }
 
-static void __pyx_tp_dealloc_3_sa___pyx_scope_struct_26_online_match(PyObject *o) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_26_online_match *p = (struct __pyx_obj_3_sa___pyx_scope_struct_26_online_match *)o;
-  Py_CLEAR(p->__pyx_v_extract);
-  Py_CLEAR(p->__pyx_v_f_len);
-  Py_CLEAR(p->__pyx_v_f_words);
-  Py_CLEAR(p->__pyx_v_matches);
-  Py_CLEAR(p->__pyx_v_seen_phrases);
-  Py_CLEAR(p->__pyx_v_self);
+static void __pyx_tp_dealloc_3_sa___pyx_scope_struct_25_genexpr(PyObject *o) {
+  struct __pyx_obj_3_sa___pyx_scope_struct_25_genexpr *p = (struct __pyx_obj_3_sa___pyx_scope_struct_25_genexpr *)o;
+  Py_CLEAR(p->__pyx_outer_scope);
+  Py_CLEAR(p->__pyx_v_packed);
+  Py_CLEAR(p->__pyx_t_0);
   (*Py_TYPE(o)->tp_free)(o);
 }
 
-static int __pyx_tp_traverse_3_sa___pyx_scope_struct_26_online_match(PyObject *o, visitproc v, void *a) {
+static int __pyx_tp_traverse_3_sa___pyx_scope_struct_25_genexpr(PyObject *o, visitproc v, void *a) {
   int e;
-  struct __pyx_obj_3_sa___pyx_scope_struct_26_online_match *p = (struct __pyx_obj_3_sa___pyx_scope_struct_26_online_match *)o;
-  if (p->__pyx_v_extract) {
-    e = (*v)(p->__pyx_v_extract, a); if (e) return e;
-  }
-  if (p->__pyx_v_f_len) {
-    e = (*v)(p->__pyx_v_f_len, a); if (e) return e;
-  }
-  if (p->__pyx_v_f_words) {
-    e = (*v)(p->__pyx_v_f_words, a); if (e) return e;
-  }
-  if (p->__pyx_v_matches) {
-    e = (*v)(p->__pyx_v_matches, a); if (e) return e;
+  struct __pyx_obj_3_sa___pyx_scope_struct_25_genexpr *p = (struct __pyx_obj_3_sa___pyx_scope_struct_25_genexpr *)o;
+  if (p->__pyx_outer_scope) {
+    e = (*v)(((PyObject*)p->__pyx_outer_scope), a); if (e) return e;
   }
-  if (p->__pyx_v_seen_phrases) {
-    e = (*v)(p->__pyx_v_seen_phrases, a); if (e) return e;
+  if (p->__pyx_v_packed) {
+    e = (*v)(p->__pyx_v_packed, a); if (e) return e;
   }
-  if (p->__pyx_v_self) {
-    e = (*v)(((PyObject*)p->__pyx_v_self), a); if (e) return e;
+  if (p->__pyx_t_0) {
+    e = (*v)(p->__pyx_t_0, a); if (e) return e;
   }
   return 0;
 }
 
-static int __pyx_tp_clear_3_sa___pyx_scope_struct_26_online_match(PyObject *o) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_26_online_match *p = (struct __pyx_obj_3_sa___pyx_scope_struct_26_online_match *)o;
+static int __pyx_tp_clear_3_sa___pyx_scope_struct_25_genexpr(PyObject *o) {
+  struct __pyx_obj_3_sa___pyx_scope_struct_25_genexpr *p = (struct __pyx_obj_3_sa___pyx_scope_struct_25_genexpr *)o;
   PyObject* tmp;
-  tmp = ((PyObject*)p->__pyx_v_extract);
-  p->__pyx_v_extract = Py_None; Py_INCREF(Py_None);
-  Py_XDECREF(tmp);
-  tmp = ((PyObject*)p->__pyx_v_f_len);
-  p->__pyx_v_f_len = Py_None; Py_INCREF(Py_None);
-  Py_XDECREF(tmp);
-  tmp = ((PyObject*)p->__pyx_v_f_words);
-  p->__pyx_v_f_words = Py_None; Py_INCREF(Py_None);
-  Py_XDECREF(tmp);
-  tmp = ((PyObject*)p->__pyx_v_matches);
-  p->__pyx_v_matches = Py_None; Py_INCREF(Py_None);
+  tmp = ((PyObject*)p->__pyx_outer_scope);
+  p->__pyx_outer_scope = ((struct __pyx_obj_3_sa___pyx_scope_struct_24_fmt_rule *)Py_None); Py_INCREF(Py_None);
   Py_XDECREF(tmp);
-  tmp = ((PyObject*)p->__pyx_v_seen_phrases);
-  p->__pyx_v_seen_phrases = Py_None; Py_INCREF(Py_None);
+  tmp = ((PyObject*)p->__pyx_v_packed);
+  p->__pyx_v_packed = Py_None; Py_INCREF(Py_None);
   Py_XDECREF(tmp);
-  tmp = ((PyObject*)p->__pyx_v_self);
-  p->__pyx_v_self = ((struct __pyx_obj_3_sa_HieroCachingRuleFactory *)Py_None); Py_INCREF(Py_None);
+  tmp = ((PyObject*)p->__pyx_t_0);
+  p->__pyx_t_0 = Py_None; Py_INCREF(Py_None);
   Py_XDECREF(tmp);
   return 0;
 }
 
-static PyMethodDef __pyx_methods_3_sa___pyx_scope_struct_26_online_match[] = {
+static PyMethodDef __pyx_methods_3_sa___pyx_scope_struct_25_genexpr[] = {
   {0, 0, 0, 0}
 };
 
-static PyNumberMethods __pyx_tp_as_number___pyx_scope_struct_26_online_match = {
+static PyNumberMethods __pyx_tp_as_number___pyx_scope_struct_25_genexpr = {
   0, /*nb_add*/
   0, /*nb_subtract*/
   0, /*nb_multiply*/
@@ -78573,7 +78132,7 @@ static PyNumberMethods __pyx_tp_as_number___pyx_scope_struct_26_online_match = {
   #endif
 };
 
-static PySequenceMethods __pyx_tp_as_sequence___pyx_scope_struct_26_online_match = {
+static PySequenceMethods __pyx_tp_as_sequence___pyx_scope_struct_25_genexpr = {
   0, /*sq_length*/
   0, /*sq_concat*/
   0, /*sq_repeat*/
@@ -78586,13 +78145,13 @@ static PySequenceMethods __pyx_tp_as_sequence___pyx_scope_struct_26_online_match
   0, /*sq_inplace_repeat*/
 };
 
-static PyMappingMethods __pyx_tp_as_mapping___pyx_scope_struct_26_online_match = {
+static PyMappingMethods __pyx_tp_as_mapping___pyx_scope_struct_25_genexpr = {
   0, /*mp_length*/
   0, /*mp_subscript*/
   0, /*mp_ass_subscript*/
 };
 
-static PyBufferProcs __pyx_tp_as_buffer___pyx_scope_struct_26_online_match = {
+static PyBufferProcs __pyx_tp_as_buffer___pyx_scope_struct_25_genexpr = {
   #if PY_MAJOR_VERSION < 3
   0, /*bf_getreadbuffer*/
   #endif
@@ -78613,12 +78172,12 @@ static PyBufferProcs __pyx_tp_as_buffer___pyx_scope_struct_26_online_match = {
   #endif
 };
 
-static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_26_online_match = {
+static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_25_genexpr = {
   PyVarObject_HEAD_INIT(0, 0)
-  __Pyx_NAMESTR("_sa.__pyx_scope_struct_26_online_match"), /*tp_name*/
-  sizeof(struct __pyx_obj_3_sa___pyx_scope_struct_26_online_match), /*tp_basicsize*/
+  __Pyx_NAMESTR("_sa.__pyx_scope_struct_25_genexpr"), /*tp_name*/
+  sizeof(struct __pyx_obj_3_sa___pyx_scope_struct_25_genexpr), /*tp_basicsize*/
   0, /*tp_itemsize*/
-  __pyx_tp_dealloc_3_sa___pyx_scope_struct_26_online_match, /*tp_dealloc*/
+  __pyx_tp_dealloc_3_sa___pyx_scope_struct_25_genexpr, /*tp_dealloc*/
   0, /*tp_print*/
   0, /*tp_getattr*/
   0, /*tp_setattr*/
@@ -78628,24 +78187,24 @@ static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_26_online_match = {
   0, /*reserved*/
   #endif
   0, /*tp_repr*/
-  &__pyx_tp_as_number___pyx_scope_struct_26_online_match, /*tp_as_number*/
-  &__pyx_tp_as_sequence___pyx_scope_struct_26_online_match, /*tp_as_sequence*/
-  &__pyx_tp_as_mapping___pyx_scope_struct_26_online_match, /*tp_as_mapping*/
+  &__pyx_tp_as_number___pyx_scope_struct_25_genexpr, /*tp_as_number*/
+  &__pyx_tp_as_sequence___pyx_scope_struct_25_genexpr, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping___pyx_scope_struct_25_genexpr, /*tp_as_mapping*/
   0, /*tp_hash*/
   0, /*tp_call*/
   0, /*tp_str*/
   0, /*tp_getattro*/
   0, /*tp_setattro*/
-  &__pyx_tp_as_buffer___pyx_scope_struct_26_online_match, /*tp_as_buffer*/
+  &__pyx_tp_as_buffer___pyx_scope_struct_25_genexpr, /*tp_as_buffer*/
   Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
   0, /*tp_doc*/
-  __pyx_tp_traverse_3_sa___pyx_scope_struct_26_online_match, /*tp_traverse*/
-  __pyx_tp_clear_3_sa___pyx_scope_struct_26_online_match, /*tp_clear*/
+  __pyx_tp_traverse_3_sa___pyx_scope_struct_25_genexpr, /*tp_traverse*/
+  __pyx_tp_clear_3_sa___pyx_scope_struct_25_genexpr, /*tp_clear*/
   0, /*tp_richcompare*/
   0, /*tp_weaklistoffset*/
   0, /*tp_iter*/
   0, /*tp_iternext*/
-  __pyx_methods_3_sa___pyx_scope_struct_26_online_match, /*tp_methods*/
+  __pyx_methods_3_sa___pyx_scope_struct_25_genexpr, /*tp_methods*/
   0, /*tp_members*/
   0, /*tp_getset*/
   0, /*tp_base*/
@@ -78655,7 +78214,7 @@ static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_26_online_match = {
   0, /*tp_dictoffset*/
   0, /*tp_init*/
   0, /*tp_alloc*/
-  __pyx_tp_new_3_sa___pyx_scope_struct_26_online_match, /*tp_new*/
+  __pyx_tp_new_3_sa___pyx_scope_struct_25_genexpr, /*tp_new*/
   0, /*tp_free*/
   0, /*tp_is_gc*/
   0, /*tp_bases*/
@@ -78669,283 +78228,76 @@ static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_26_online_match = {
   #endif
 };
 
-static PyObject *__pyx_tp_new_3_sa___pyx_scope_struct_27_genexpr(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_27_genexpr *p;
+static PyObject *__pyx_tp_new_3_sa___pyx_scope_struct_26_get_f_phrases(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_3_sa___pyx_scope_struct_26_get_f_phrases *p;
   PyObject *o = (*t->tp_alloc)(t, 0);
   if (!o) return 0;
-  p = ((struct __pyx_obj_3_sa___pyx_scope_struct_27_genexpr *)o);
-  p->__pyx_outer_scope = 0;
-  p->__pyx_v_e = 0;
-  p->__pyx_v_f = 0;
-  p->__pyx_t_0 = 0;
+  p = ((struct __pyx_obj_3_sa___pyx_scope_struct_26_get_f_phrases *)o);
+  p->__pyx_v_extract = 0;
+  p->__pyx_v_f_len = 0;
+  p->__pyx_v_f_words = 0;
+  p->__pyx_v_phrases = 0;
+  p->__pyx_v_self = 0;
   return o;
 }
 
-static void __pyx_tp_dealloc_3_sa___pyx_scope_struct_27_genexpr(PyObject *o) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_27_genexpr *p = (struct __pyx_obj_3_sa___pyx_scope_struct_27_genexpr *)o;
-  Py_CLEAR(p->__pyx_outer_scope);
-  Py_CLEAR(p->__pyx_v_e);
-  Py_CLEAR(p->__pyx_v_f);
-  Py_CLEAR(p->__pyx_t_0);
+static void __pyx_tp_dealloc_3_sa___pyx_scope_struct_26_get_f_phrases(PyObject *o) {
+  struct __pyx_obj_3_sa___pyx_scope_struct_26_get_f_phrases *p = (struct __pyx_obj_3_sa___pyx_scope_struct_26_get_f_phrases *)o;
+  Py_CLEAR(p->__pyx_v_extract);
+  Py_CLEAR(p->__pyx_v_f_len);
+  Py_CLEAR(p->__pyx_v_f_words);
+  Py_CLEAR(p->__pyx_v_phrases);
+  Py_CLEAR(p->__pyx_v_self);
   (*Py_TYPE(o)->tp_free)(o);
 }
 
-static int __pyx_tp_traverse_3_sa___pyx_scope_struct_27_genexpr(PyObject *o, visitproc v, void *a) {
+static int __pyx_tp_traverse_3_sa___pyx_scope_struct_26_get_f_phrases(PyObject *o, visitproc v, void *a) {
   int e;
-  struct __pyx_obj_3_sa___pyx_scope_struct_27_genexpr *p = (struct __pyx_obj_3_sa___pyx_scope_struct_27_genexpr *)o;
-  if (p->__pyx_outer_scope) {
-    e = (*v)(((PyObject*)p->__pyx_outer_scope), a); if (e) return e;
-  }
-  if (p->__pyx_v_e) {
-    e = (*v)(p->__pyx_v_e, a); if (e) return e;
-  }
-  if (p->__pyx_v_f) {
-    e = (*v)(p->__pyx_v_f, a); if (e) return e;
-  }
-  if (p->__pyx_t_0) {
-    e = (*v)(p->__pyx_t_0, a); if (e) return e;
+  struct __pyx_obj_3_sa___pyx_scope_struct_26_get_f_phrases *p = (struct __pyx_obj_3_sa___pyx_scope_struct_26_get_f_phrases *)o;
+  if (p->__pyx_v_extract) {
+    e = (*v)(p->__pyx_v_extract, a); if (e) return e;
   }
-  return 0;
-}
-
-static int __pyx_tp_clear_3_sa___pyx_scope_struct_27_genexpr(PyObject *o) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_27_genexpr *p = (struct __pyx_obj_3_sa___pyx_scope_struct_27_genexpr *)o;
-  PyObject* tmp;
-  tmp = ((PyObject*)p->__pyx_outer_scope);
-  p->__pyx_outer_scope = ((struct __pyx_obj_3_sa___pyx_scope_struct_26_online_match *)Py_None); Py_INCREF(Py_None);
-  Py_XDECREF(tmp);
-  tmp = ((PyObject*)p->__pyx_v_e);
-  p->__pyx_v_e = Py_None; Py_INCREF(Py_None);
-  Py_XDECREF(tmp);
-  tmp = ((PyObject*)p->__pyx_v_f);
-  p->__pyx_v_f = Py_None; Py_INCREF(Py_None);
-  Py_XDECREF(tmp);
-  tmp = ((PyObject*)p->__pyx_t_0);
-  p->__pyx_t_0 = Py_None; Py_INCREF(Py_None);
-  Py_XDECREF(tmp);
-  return 0;
-}
-
-static PyMethodDef __pyx_methods_3_sa___pyx_scope_struct_27_genexpr[] = {
-  {0, 0, 0, 0}
-};
-
-static PyNumberMethods __pyx_tp_as_number___pyx_scope_struct_27_genexpr = {
-  0, /*nb_add*/
-  0, /*nb_subtract*/
-  0, /*nb_multiply*/
-  #if PY_MAJOR_VERSION < 3
-  0, /*nb_divide*/
-  #endif
-  0, /*nb_remainder*/
-  0, /*nb_divmod*/
-  0, /*nb_power*/
-  0, /*nb_negative*/
-  0, /*nb_positive*/
-  0, /*nb_absolute*/
-  0, /*nb_nonzero*/
-  0, /*nb_invert*/
-  0, /*nb_lshift*/
-  0, /*nb_rshift*/
-  0, /*nb_and*/
-  0, /*nb_xor*/
-  0, /*nb_or*/
-  #if PY_MAJOR_VERSION < 3
-  0, /*nb_coerce*/
-  #endif
-  0, /*nb_int*/
-  #if PY_MAJOR_VERSION < 3
-  0, /*nb_long*/
-  #else
-  0, /*reserved*/
-  #endif
-  0, /*nb_float*/
-  #if PY_MAJOR_VERSION < 3
-  0, /*nb_oct*/
-  #endif
-  #if PY_MAJOR_VERSION < 3
-  0, /*nb_hex*/
-  #endif
-  0, /*nb_inplace_add*/
-  0, /*nb_inplace_subtract*/
-  0, /*nb_inplace_multiply*/
-  #if PY_MAJOR_VERSION < 3
-  0, /*nb_inplace_divide*/
-  #endif
-  0, /*nb_inplace_remainder*/
-  0, /*nb_inplace_power*/
-  0, /*nb_inplace_lshift*/
-  0, /*nb_inplace_rshift*/
-  0, /*nb_inplace_and*/
-  0, /*nb_inplace_xor*/
-  0, /*nb_inplace_or*/
-  0, /*nb_floor_divide*/
-  0, /*nb_true_divide*/
-  0, /*nb_inplace_floor_divide*/
-  0, /*nb_inplace_true_divide*/
-  #if PY_VERSION_HEX >= 0x02050000
-  0, /*nb_index*/
-  #endif
-};
-
-static PySequenceMethods __pyx_tp_as_sequence___pyx_scope_struct_27_genexpr = {
-  0, /*sq_length*/
-  0, /*sq_concat*/
-  0, /*sq_repeat*/
-  0, /*sq_item*/
-  0, /*sq_slice*/
-  0, /*sq_ass_item*/
-  0, /*sq_ass_slice*/
-  0, /*sq_contains*/
-  0, /*sq_inplace_concat*/
-  0, /*sq_inplace_repeat*/
-};
-
-static PyMappingMethods __pyx_tp_as_mapping___pyx_scope_struct_27_genexpr = {
-  0, /*mp_length*/
-  0, /*mp_subscript*/
-  0, /*mp_ass_subscript*/
-};
-
-static PyBufferProcs __pyx_tp_as_buffer___pyx_scope_struct_27_genexpr = {
-  #if PY_MAJOR_VERSION < 3
-  0, /*bf_getreadbuffer*/
-  #endif
-  #if PY_MAJOR_VERSION < 3
-  0, /*bf_getwritebuffer*/
-  #endif
-  #if PY_MAJOR_VERSION < 3
-  0, /*bf_getsegcount*/
-  #endif
-  #if PY_MAJOR_VERSION < 3
-  0, /*bf_getcharbuffer*/
-  #endif
-  #if PY_VERSION_HEX >= 0x02060000
-  0, /*bf_getbuffer*/
-  #endif
-  #if PY_VERSION_HEX >= 0x02060000
-  0, /*bf_releasebuffer*/
-  #endif
-};
-
-static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_27_genexpr = {
-  PyVarObject_HEAD_INIT(0, 0)
-  __Pyx_NAMESTR("_sa.__pyx_scope_struct_27_genexpr"), /*tp_name*/
-  sizeof(struct __pyx_obj_3_sa___pyx_scope_struct_27_genexpr), /*tp_basicsize*/
-  0, /*tp_itemsize*/
-  __pyx_tp_dealloc_3_sa___pyx_scope_struct_27_genexpr, /*tp_dealloc*/
-  0, /*tp_print*/
-  0, /*tp_getattr*/
-  0, /*tp_setattr*/
-  #if PY_MAJOR_VERSION < 3
-  0, /*tp_compare*/
-  #else
-  0, /*reserved*/
-  #endif
-  0, /*tp_repr*/
-  &__pyx_tp_as_number___pyx_scope_struct_27_genexpr, /*tp_as_number*/
-  &__pyx_tp_as_sequence___pyx_scope_struct_27_genexpr, /*tp_as_sequence*/
-  &__pyx_tp_as_mapping___pyx_scope_struct_27_genexpr, /*tp_as_mapping*/
-  0, /*tp_hash*/
-  0, /*tp_call*/
-  0, /*tp_str*/
-  0, /*tp_getattro*/
-  0, /*tp_setattro*/
-  &__pyx_tp_as_buffer___pyx_scope_struct_27_genexpr, /*tp_as_buffer*/
-  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
-  0, /*tp_doc*/
-  __pyx_tp_traverse_3_sa___pyx_scope_struct_27_genexpr, /*tp_traverse*/
-  __pyx_tp_clear_3_sa___pyx_scope_struct_27_genexpr, /*tp_clear*/
-  0, /*tp_richcompare*/
-  0, /*tp_weaklistoffset*/
-  0, /*tp_iter*/
-  0, /*tp_iternext*/
-  __pyx_methods_3_sa___pyx_scope_struct_27_genexpr, /*tp_methods*/
-  0, /*tp_members*/
-  0, /*tp_getset*/
-  0, /*tp_base*/
-  0, /*tp_dict*/
-  0, /*tp_descr_get*/
-  0, /*tp_descr_set*/
-  0, /*tp_dictoffset*/
-  0, /*tp_init*/
-  0, /*tp_alloc*/
-  __pyx_tp_new_3_sa___pyx_scope_struct_27_genexpr, /*tp_new*/
-  0, /*tp_free*/
-  0, /*tp_is_gc*/
-  0, /*tp_bases*/
-  0, /*tp_mro*/
-  0, /*tp_cache*/
-  0, /*tp_subclasses*/
-  0, /*tp_weaklist*/
-  0, /*tp_del*/
-  #if PY_VERSION_HEX >= 0x02060000
-  0, /*tp_version_tag*/
-  #endif
-};
-
-static PyObject *__pyx_tp_new_3_sa___pyx_scope_struct_28_genexpr(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_28_genexpr *p;
-  PyObject *o = (*t->tp_alloc)(t, 0);
-  if (!o) return 0;
-  p = ((struct __pyx_obj_3_sa___pyx_scope_struct_28_genexpr *)o);
-  p->__pyx_outer_scope = 0;
-  p->__pyx_v_e = 0;
-  p->__pyx_v_f = 0;
-  p->__pyx_t_0 = 0;
-  return o;
-}
-
-static void __pyx_tp_dealloc_3_sa___pyx_scope_struct_28_genexpr(PyObject *o) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_28_genexpr *p = (struct __pyx_obj_3_sa___pyx_scope_struct_28_genexpr *)o;
-  Py_CLEAR(p->__pyx_outer_scope);
-  Py_CLEAR(p->__pyx_v_e);
-  Py_CLEAR(p->__pyx_v_f);
-  Py_CLEAR(p->__pyx_t_0);
-  (*Py_TYPE(o)->tp_free)(o);
-}
-
-static int __pyx_tp_traverse_3_sa___pyx_scope_struct_28_genexpr(PyObject *o, visitproc v, void *a) {
-  int e;
-  struct __pyx_obj_3_sa___pyx_scope_struct_28_genexpr *p = (struct __pyx_obj_3_sa___pyx_scope_struct_28_genexpr *)o;
-  if (p->__pyx_outer_scope) {
-    e = (*v)(((PyObject*)p->__pyx_outer_scope), a); if (e) return e;
+  if (p->__pyx_v_f_len) {
+    e = (*v)(p->__pyx_v_f_len, a); if (e) return e;
   }
-  if (p->__pyx_v_e) {
-    e = (*v)(p->__pyx_v_e, a); if (e) return e;
+  if (p->__pyx_v_f_words) {
+    e = (*v)(p->__pyx_v_f_words, a); if (e) return e;
   }
-  if (p->__pyx_v_f) {
-    e = (*v)(p->__pyx_v_f, a); if (e) return e;
+  if (p->__pyx_v_phrases) {
+    e = (*v)(p->__pyx_v_phrases, a); if (e) return e;
   }
-  if (p->__pyx_t_0) {
-    e = (*v)(p->__pyx_t_0, a); if (e) return e;
+  if (p->__pyx_v_self) {
+    e = (*v)(((PyObject*)p->__pyx_v_self), a); if (e) return e;
   }
   return 0;
 }
 
-static int __pyx_tp_clear_3_sa___pyx_scope_struct_28_genexpr(PyObject *o) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_28_genexpr *p = (struct __pyx_obj_3_sa___pyx_scope_struct_28_genexpr *)o;
+static int __pyx_tp_clear_3_sa___pyx_scope_struct_26_get_f_phrases(PyObject *o) {
+  struct __pyx_obj_3_sa___pyx_scope_struct_26_get_f_phrases *p = (struct __pyx_obj_3_sa___pyx_scope_struct_26_get_f_phrases *)o;
   PyObject* tmp;
-  tmp = ((PyObject*)p->__pyx_outer_scope);
-  p->__pyx_outer_scope = ((struct __pyx_obj_3_sa___pyx_scope_struct_26_online_match *)Py_None); Py_INCREF(Py_None);
+  tmp = ((PyObject*)p->__pyx_v_extract);
+  p->__pyx_v_extract = Py_None; Py_INCREF(Py_None);
   Py_XDECREF(tmp);
-  tmp = ((PyObject*)p->__pyx_v_e);
-  p->__pyx_v_e = Py_None; Py_INCREF(Py_None);
+  tmp = ((PyObject*)p->__pyx_v_f_len);
+  p->__pyx_v_f_len = Py_None; Py_INCREF(Py_None);
   Py_XDECREF(tmp);
-  tmp = ((PyObject*)p->__pyx_v_f);
-  p->__pyx_v_f = Py_None; Py_INCREF(Py_None);
+  tmp = ((PyObject*)p->__pyx_v_f_words);
+  p->__pyx_v_f_words = Py_None; Py_INCREF(Py_None);
   Py_XDECREF(tmp);
-  tmp = ((PyObject*)p->__pyx_t_0);
-  p->__pyx_t_0 = Py_None; Py_INCREF(Py_None);
+  tmp = ((PyObject*)p->__pyx_v_phrases);
+  p->__pyx_v_phrases = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->__pyx_v_self);
+  p->__pyx_v_self = ((struct __pyx_obj_3_sa_HieroCachingRuleFactory *)Py_None); Py_INCREF(Py_None);
   Py_XDECREF(tmp);
   return 0;
 }
 
-static PyMethodDef __pyx_methods_3_sa___pyx_scope_struct_28_genexpr[] = {
+static PyMethodDef __pyx_methods_3_sa___pyx_scope_struct_26_get_f_phrases[] = {
   {0, 0, 0, 0}
 };
 
-static PyNumberMethods __pyx_tp_as_number___pyx_scope_struct_28_genexpr = {
+static PyNumberMethods __pyx_tp_as_number___pyx_scope_struct_26_get_f_phrases = {
   0, /*nb_add*/
   0, /*nb_subtract*/
   0, /*nb_multiply*/
@@ -79003,7 +78355,7 @@ static PyNumberMethods __pyx_tp_as_number___pyx_scope_struct_28_genexpr = {
   #endif
 };
 
-static PySequenceMethods __pyx_tp_as_sequence___pyx_scope_struct_28_genexpr = {
+static PySequenceMethods __pyx_tp_as_sequence___pyx_scope_struct_26_get_f_phrases = {
   0, /*sq_length*/
   0, /*sq_concat*/
   0, /*sq_repeat*/
@@ -79016,13 +78368,13 @@ static PySequenceMethods __pyx_tp_as_sequence___pyx_scope_struct_28_genexpr = {
   0, /*sq_inplace_repeat*/
 };
 
-static PyMappingMethods __pyx_tp_as_mapping___pyx_scope_struct_28_genexpr = {
+static PyMappingMethods __pyx_tp_as_mapping___pyx_scope_struct_26_get_f_phrases = {
   0, /*mp_length*/
   0, /*mp_subscript*/
   0, /*mp_ass_subscript*/
 };
 
-static PyBufferProcs __pyx_tp_as_buffer___pyx_scope_struct_28_genexpr = {
+static PyBufferProcs __pyx_tp_as_buffer___pyx_scope_struct_26_get_f_phrases = {
   #if PY_MAJOR_VERSION < 3
   0, /*bf_getreadbuffer*/
   #endif
@@ -79043,12 +78395,12 @@ static PyBufferProcs __pyx_tp_as_buffer___pyx_scope_struct_28_genexpr = {
   #endif
 };
 
-static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_28_genexpr = {
+static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_26_get_f_phrases = {
   PyVarObject_HEAD_INIT(0, 0)
-  __Pyx_NAMESTR("_sa.__pyx_scope_struct_28_genexpr"), /*tp_name*/
-  sizeof(struct __pyx_obj_3_sa___pyx_scope_struct_28_genexpr), /*tp_basicsize*/
+  __Pyx_NAMESTR("_sa.__pyx_scope_struct_26_get_f_phrases"), /*tp_name*/
+  sizeof(struct __pyx_obj_3_sa___pyx_scope_struct_26_get_f_phrases), /*tp_basicsize*/
   0, /*tp_itemsize*/
-  __pyx_tp_dealloc_3_sa___pyx_scope_struct_28_genexpr, /*tp_dealloc*/
+  __pyx_tp_dealloc_3_sa___pyx_scope_struct_26_get_f_phrases, /*tp_dealloc*/
   0, /*tp_print*/
   0, /*tp_getattr*/
   0, /*tp_setattr*/
@@ -79058,24 +78410,24 @@ static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_28_genexpr = {
   0, /*reserved*/
   #endif
   0, /*tp_repr*/
-  &__pyx_tp_as_number___pyx_scope_struct_28_genexpr, /*tp_as_number*/
-  &__pyx_tp_as_sequence___pyx_scope_struct_28_genexpr, /*tp_as_sequence*/
-  &__pyx_tp_as_mapping___pyx_scope_struct_28_genexpr, /*tp_as_mapping*/
+  &__pyx_tp_as_number___pyx_scope_struct_26_get_f_phrases, /*tp_as_number*/
+  &__pyx_tp_as_sequence___pyx_scope_struct_26_get_f_phrases, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping___pyx_scope_struct_26_get_f_phrases, /*tp_as_mapping*/
   0, /*tp_hash*/
   0, /*tp_call*/
   0, /*tp_str*/
   0, /*tp_getattro*/
   0, /*tp_setattro*/
-  &__pyx_tp_as_buffer___pyx_scope_struct_28_genexpr, /*tp_as_buffer*/
+  &__pyx_tp_as_buffer___pyx_scope_struct_26_get_f_phrases, /*tp_as_buffer*/
   Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
   0, /*tp_doc*/
-  __pyx_tp_traverse_3_sa___pyx_scope_struct_28_genexpr, /*tp_traverse*/
-  __pyx_tp_clear_3_sa___pyx_scope_struct_28_genexpr, /*tp_clear*/
+  __pyx_tp_traverse_3_sa___pyx_scope_struct_26_get_f_phrases, /*tp_traverse*/
+  __pyx_tp_clear_3_sa___pyx_scope_struct_26_get_f_phrases, /*tp_clear*/
   0, /*tp_richcompare*/
   0, /*tp_weaklistoffset*/
   0, /*tp_iter*/
   0, /*tp_iternext*/
-  __pyx_methods_3_sa___pyx_scope_struct_28_genexpr, /*tp_methods*/
+  __pyx_methods_3_sa___pyx_scope_struct_26_get_f_phrases, /*tp_methods*/
   0, /*tp_members*/
   0, /*tp_getset*/
   0, /*tp_base*/
@@ -79085,7 +78437,7 @@ static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_28_genexpr = {
   0, /*tp_dictoffset*/
   0, /*tp_init*/
   0, /*tp_alloc*/
-  __pyx_tp_new_3_sa___pyx_scope_struct_28_genexpr, /*tp_new*/
+  __pyx_tp_new_3_sa___pyx_scope_struct_26_get_f_phrases, /*tp_new*/
   0, /*tp_free*/
   0, /*tp_is_gc*/
   0, /*tp_bases*/
@@ -79099,32 +78451,32 @@ static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_28_genexpr = {
   #endif
 };
 
-static PyObject *__pyx_tp_new_3_sa___pyx_scope_struct_29___iter__(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_29___iter__ *p;
+static PyObject *__pyx_tp_new_3_sa___pyx_scope_struct_27___iter__(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_3_sa___pyx_scope_struct_27___iter__ *p;
   PyObject *o = (*t->tp_alloc)(t, 0);
   if (!o) return 0;
-  p = ((struct __pyx_obj_3_sa___pyx_scope_struct_29___iter__ *)o);
+  p = ((struct __pyx_obj_3_sa___pyx_scope_struct_27___iter__ *)o);
   p->__pyx_v_self = 0;
   return o;
 }
 
-static void __pyx_tp_dealloc_3_sa___pyx_scope_struct_29___iter__(PyObject *o) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_29___iter__ *p = (struct __pyx_obj_3_sa___pyx_scope_struct_29___iter__ *)o;
+static void __pyx_tp_dealloc_3_sa___pyx_scope_struct_27___iter__(PyObject *o) {
+  struct __pyx_obj_3_sa___pyx_scope_struct_27___iter__ *p = (struct __pyx_obj_3_sa___pyx_scope_struct_27___iter__ *)o;
   Py_CLEAR(p->__pyx_v_self);
   (*Py_TYPE(o)->tp_free)(o);
 }
 
-static int __pyx_tp_traverse_3_sa___pyx_scope_struct_29___iter__(PyObject *o, visitproc v, void *a) {
+static int __pyx_tp_traverse_3_sa___pyx_scope_struct_27___iter__(PyObject *o, visitproc v, void *a) {
   int e;
-  struct __pyx_obj_3_sa___pyx_scope_struct_29___iter__ *p = (struct __pyx_obj_3_sa___pyx_scope_struct_29___iter__ *)o;
+  struct __pyx_obj_3_sa___pyx_scope_struct_27___iter__ *p = (struct __pyx_obj_3_sa___pyx_scope_struct_27___iter__ *)o;
   if (p->__pyx_v_self) {
     e = (*v)(((PyObject*)p->__pyx_v_self), a); if (e) return e;
   }
   return 0;
 }
 
-static int __pyx_tp_clear_3_sa___pyx_scope_struct_29___iter__(PyObject *o) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_29___iter__ *p = (struct __pyx_obj_3_sa___pyx_scope_struct_29___iter__ *)o;
+static int __pyx_tp_clear_3_sa___pyx_scope_struct_27___iter__(PyObject *o) {
+  struct __pyx_obj_3_sa___pyx_scope_struct_27___iter__ *p = (struct __pyx_obj_3_sa___pyx_scope_struct_27___iter__ *)o;
   PyObject* tmp;
   tmp = ((PyObject*)p->__pyx_v_self);
   p->__pyx_v_self = ((struct __pyx_obj_3_sa_FeatureVector *)Py_None); Py_INCREF(Py_None);
@@ -79132,11 +78484,11 @@ static int __pyx_tp_clear_3_sa___pyx_scope_struct_29___iter__(PyObject *o) {
   return 0;
 }
 
-static PyMethodDef __pyx_methods_3_sa___pyx_scope_struct_29___iter__[] = {
+static PyMethodDef __pyx_methods_3_sa___pyx_scope_struct_27___iter__[] = {
   {0, 0, 0, 0}
 };
 
-static PyNumberMethods __pyx_tp_as_number___pyx_scope_struct_29___iter__ = {
+static PyNumberMethods __pyx_tp_as_number___pyx_scope_struct_27___iter__ = {
   0, /*nb_add*/
   0, /*nb_subtract*/
   0, /*nb_multiply*/
@@ -79194,7 +78546,7 @@ static PyNumberMethods __pyx_tp_as_number___pyx_scope_struct_29___iter__ = {
   #endif
 };
 
-static PySequenceMethods __pyx_tp_as_sequence___pyx_scope_struct_29___iter__ = {
+static PySequenceMethods __pyx_tp_as_sequence___pyx_scope_struct_27___iter__ = {
   0, /*sq_length*/
   0, /*sq_concat*/
   0, /*sq_repeat*/
@@ -79207,13 +78559,13 @@ static PySequenceMethods __pyx_tp_as_sequence___pyx_scope_struct_29___iter__ = {
   0, /*sq_inplace_repeat*/
 };
 
-static PyMappingMethods __pyx_tp_as_mapping___pyx_scope_struct_29___iter__ = {
+static PyMappingMethods __pyx_tp_as_mapping___pyx_scope_struct_27___iter__ = {
   0, /*mp_length*/
   0, /*mp_subscript*/
   0, /*mp_ass_subscript*/
 };
 
-static PyBufferProcs __pyx_tp_as_buffer___pyx_scope_struct_29___iter__ = {
+static PyBufferProcs __pyx_tp_as_buffer___pyx_scope_struct_27___iter__ = {
   #if PY_MAJOR_VERSION < 3
   0, /*bf_getreadbuffer*/
   #endif
@@ -79234,12 +78586,12 @@ static PyBufferProcs __pyx_tp_as_buffer___pyx_scope_struct_29___iter__ = {
   #endif
 };
 
-static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_29___iter__ = {
+static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_27___iter__ = {
   PyVarObject_HEAD_INIT(0, 0)
-  __Pyx_NAMESTR("_sa.__pyx_scope_struct_29___iter__"), /*tp_name*/
-  sizeof(struct __pyx_obj_3_sa___pyx_scope_struct_29___iter__), /*tp_basicsize*/
+  __Pyx_NAMESTR("_sa.__pyx_scope_struct_27___iter__"), /*tp_name*/
+  sizeof(struct __pyx_obj_3_sa___pyx_scope_struct_27___iter__), /*tp_basicsize*/
   0, /*tp_itemsize*/
-  __pyx_tp_dealloc_3_sa___pyx_scope_struct_29___iter__, /*tp_dealloc*/
+  __pyx_tp_dealloc_3_sa___pyx_scope_struct_27___iter__, /*tp_dealloc*/
   0, /*tp_print*/
   0, /*tp_getattr*/
   0, /*tp_setattr*/
@@ -79249,24 +78601,24 @@ static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_29___iter__ = {
   0, /*reserved*/
   #endif
   0, /*tp_repr*/
-  &__pyx_tp_as_number___pyx_scope_struct_29___iter__, /*tp_as_number*/
-  &__pyx_tp_as_sequence___pyx_scope_struct_29___iter__, /*tp_as_sequence*/
-  &__pyx_tp_as_mapping___pyx_scope_struct_29___iter__, /*tp_as_mapping*/
+  &__pyx_tp_as_number___pyx_scope_struct_27___iter__, /*tp_as_number*/
+  &__pyx_tp_as_sequence___pyx_scope_struct_27___iter__, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping___pyx_scope_struct_27___iter__, /*tp_as_mapping*/
   0, /*tp_hash*/
   0, /*tp_call*/
   0, /*tp_str*/
   0, /*tp_getattro*/
   0, /*tp_setattro*/
-  &__pyx_tp_as_buffer___pyx_scope_struct_29___iter__, /*tp_as_buffer*/
+  &__pyx_tp_as_buffer___pyx_scope_struct_27___iter__, /*tp_as_buffer*/
   Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
   0, /*tp_doc*/
-  __pyx_tp_traverse_3_sa___pyx_scope_struct_29___iter__, /*tp_traverse*/
-  __pyx_tp_clear_3_sa___pyx_scope_struct_29___iter__, /*tp_clear*/
+  __pyx_tp_traverse_3_sa___pyx_scope_struct_27___iter__, /*tp_traverse*/
+  __pyx_tp_clear_3_sa___pyx_scope_struct_27___iter__, /*tp_clear*/
   0, /*tp_richcompare*/
   0, /*tp_weaklistoffset*/
   0, /*tp_iter*/
   0, /*tp_iternext*/
-  __pyx_methods_3_sa___pyx_scope_struct_29___iter__, /*tp_methods*/
+  __pyx_methods_3_sa___pyx_scope_struct_27___iter__, /*tp_methods*/
   0, /*tp_members*/
   0, /*tp_getset*/
   0, /*tp_base*/
@@ -79276,7 +78628,7 @@ static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_29___iter__ = {
   0, /*tp_dictoffset*/
   0, /*tp_init*/
   0, /*tp_alloc*/
-  __pyx_tp_new_3_sa___pyx_scope_struct_29___iter__, /*tp_new*/
+  __pyx_tp_new_3_sa___pyx_scope_struct_27___iter__, /*tp_new*/
   0, /*tp_free*/
   0, /*tp_is_gc*/
   0, /*tp_bases*/
@@ -79290,32 +78642,32 @@ static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_29___iter__ = {
   #endif
 };
 
-static PyObject *__pyx_tp_new_3_sa___pyx_scope_struct_30___str__(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_30___str__ *p;
+static PyObject *__pyx_tp_new_3_sa___pyx_scope_struct_28___str__(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_3_sa___pyx_scope_struct_28___str__ *p;
   PyObject *o = (*t->tp_alloc)(t, 0);
   if (!o) return 0;
-  p = ((struct __pyx_obj_3_sa___pyx_scope_struct_30___str__ *)o);
+  p = ((struct __pyx_obj_3_sa___pyx_scope_struct_28___str__ *)o);
   p->__pyx_v_self = 0;
   return o;
 }
 
-static void __pyx_tp_dealloc_3_sa___pyx_scope_struct_30___str__(PyObject *o) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_30___str__ *p = (struct __pyx_obj_3_sa___pyx_scope_struct_30___str__ *)o;
+static void __pyx_tp_dealloc_3_sa___pyx_scope_struct_28___str__(PyObject *o) {
+  struct __pyx_obj_3_sa___pyx_scope_struct_28___str__ *p = (struct __pyx_obj_3_sa___pyx_scope_struct_28___str__ *)o;
   Py_CLEAR(p->__pyx_v_self);
   (*Py_TYPE(o)->tp_free)(o);
 }
 
-static int __pyx_tp_traverse_3_sa___pyx_scope_struct_30___str__(PyObject *o, visitproc v, void *a) {
+static int __pyx_tp_traverse_3_sa___pyx_scope_struct_28___str__(PyObject *o, visitproc v, void *a) {
   int e;
-  struct __pyx_obj_3_sa___pyx_scope_struct_30___str__ *p = (struct __pyx_obj_3_sa___pyx_scope_struct_30___str__ *)o;
+  struct __pyx_obj_3_sa___pyx_scope_struct_28___str__ *p = (struct __pyx_obj_3_sa___pyx_scope_struct_28___str__ *)o;
   if (p->__pyx_v_self) {
     e = (*v)(((PyObject*)p->__pyx_v_self), a); if (e) return e;
   }
   return 0;
 }
 
-static int __pyx_tp_clear_3_sa___pyx_scope_struct_30___str__(PyObject *o) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_30___str__ *p = (struct __pyx_obj_3_sa___pyx_scope_struct_30___str__ *)o;
+static int __pyx_tp_clear_3_sa___pyx_scope_struct_28___str__(PyObject *o) {
+  struct __pyx_obj_3_sa___pyx_scope_struct_28___str__ *p = (struct __pyx_obj_3_sa___pyx_scope_struct_28___str__ *)o;
   PyObject* tmp;
   tmp = ((PyObject*)p->__pyx_v_self);
   p->__pyx_v_self = ((struct __pyx_obj_3_sa_FeatureVector *)Py_None); Py_INCREF(Py_None);
@@ -79323,11 +78675,11 @@ static int __pyx_tp_clear_3_sa___pyx_scope_struct_30___str__(PyObject *o) {
   return 0;
 }
 
-static PyMethodDef __pyx_methods_3_sa___pyx_scope_struct_30___str__[] = {
+static PyMethodDef __pyx_methods_3_sa___pyx_scope_struct_28___str__[] = {
   {0, 0, 0, 0}
 };
 
-static PyNumberMethods __pyx_tp_as_number___pyx_scope_struct_30___str__ = {
+static PyNumberMethods __pyx_tp_as_number___pyx_scope_struct_28___str__ = {
   0, /*nb_add*/
   0, /*nb_subtract*/
   0, /*nb_multiply*/
@@ -79385,7 +78737,7 @@ static PyNumberMethods __pyx_tp_as_number___pyx_scope_struct_30___str__ = {
   #endif
 };
 
-static PySequenceMethods __pyx_tp_as_sequence___pyx_scope_struct_30___str__ = {
+static PySequenceMethods __pyx_tp_as_sequence___pyx_scope_struct_28___str__ = {
   0, /*sq_length*/
   0, /*sq_concat*/
   0, /*sq_repeat*/
@@ -79398,13 +78750,13 @@ static PySequenceMethods __pyx_tp_as_sequence___pyx_scope_struct_30___str__ = {
   0, /*sq_inplace_repeat*/
 };
 
-static PyMappingMethods __pyx_tp_as_mapping___pyx_scope_struct_30___str__ = {
+static PyMappingMethods __pyx_tp_as_mapping___pyx_scope_struct_28___str__ = {
   0, /*mp_length*/
   0, /*mp_subscript*/
   0, /*mp_ass_subscript*/
 };
 
-static PyBufferProcs __pyx_tp_as_buffer___pyx_scope_struct_30___str__ = {
+static PyBufferProcs __pyx_tp_as_buffer___pyx_scope_struct_28___str__ = {
   #if PY_MAJOR_VERSION < 3
   0, /*bf_getreadbuffer*/
   #endif
@@ -79425,12 +78777,12 @@ static PyBufferProcs __pyx_tp_as_buffer___pyx_scope_struct_30___str__ = {
   #endif
 };
 
-static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_30___str__ = {
+static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_28___str__ = {
   PyVarObject_HEAD_INIT(0, 0)
-  __Pyx_NAMESTR("_sa.__pyx_scope_struct_30___str__"), /*tp_name*/
-  sizeof(struct __pyx_obj_3_sa___pyx_scope_struct_30___str__), /*tp_basicsize*/
+  __Pyx_NAMESTR("_sa.__pyx_scope_struct_28___str__"), /*tp_name*/
+  sizeof(struct __pyx_obj_3_sa___pyx_scope_struct_28___str__), /*tp_basicsize*/
   0, /*tp_itemsize*/
-  __pyx_tp_dealloc_3_sa___pyx_scope_struct_30___str__, /*tp_dealloc*/
+  __pyx_tp_dealloc_3_sa___pyx_scope_struct_28___str__, /*tp_dealloc*/
   0, /*tp_print*/
   0, /*tp_getattr*/
   0, /*tp_setattr*/
@@ -79440,24 +78792,24 @@ static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_30___str__ = {
   0, /*reserved*/
   #endif
   0, /*tp_repr*/
-  &__pyx_tp_as_number___pyx_scope_struct_30___str__, /*tp_as_number*/
-  &__pyx_tp_as_sequence___pyx_scope_struct_30___str__, /*tp_as_sequence*/
-  &__pyx_tp_as_mapping___pyx_scope_struct_30___str__, /*tp_as_mapping*/
+  &__pyx_tp_as_number___pyx_scope_struct_28___str__, /*tp_as_number*/
+  &__pyx_tp_as_sequence___pyx_scope_struct_28___str__, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping___pyx_scope_struct_28___str__, /*tp_as_mapping*/
   0, /*tp_hash*/
   0, /*tp_call*/
   0, /*tp_str*/
   0, /*tp_getattro*/
   0, /*tp_setattro*/
-  &__pyx_tp_as_buffer___pyx_scope_struct_30___str__, /*tp_as_buffer*/
+  &__pyx_tp_as_buffer___pyx_scope_struct_28___str__, /*tp_as_buffer*/
   Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
   0, /*tp_doc*/
-  __pyx_tp_traverse_3_sa___pyx_scope_struct_30___str__, /*tp_traverse*/
-  __pyx_tp_clear_3_sa___pyx_scope_struct_30___str__, /*tp_clear*/
+  __pyx_tp_traverse_3_sa___pyx_scope_struct_28___str__, /*tp_traverse*/
+  __pyx_tp_clear_3_sa___pyx_scope_struct_28___str__, /*tp_clear*/
   0, /*tp_richcompare*/
   0, /*tp_weaklistoffset*/
   0, /*tp_iter*/
   0, /*tp_iternext*/
-  __pyx_methods_3_sa___pyx_scope_struct_30___str__, /*tp_methods*/
+  __pyx_methods_3_sa___pyx_scope_struct_28___str__, /*tp_methods*/
   0, /*tp_members*/
   0, /*tp_getset*/
   0, /*tp_base*/
@@ -79467,7 +78819,7 @@ static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_30___str__ = {
   0, /*tp_dictoffset*/
   0, /*tp_init*/
   0, /*tp_alloc*/
-  __pyx_tp_new_3_sa___pyx_scope_struct_30___str__, /*tp_new*/
+  __pyx_tp_new_3_sa___pyx_scope_struct_28___str__, /*tp_new*/
   0, /*tp_free*/
   0, /*tp_is_gc*/
   0, /*tp_bases*/
@@ -79481,28 +78833,28 @@ static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_30___str__ = {
   #endif
 };
 
-static PyObject *__pyx_tp_new_3_sa___pyx_scope_struct_31_genexpr(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_31_genexpr *p;
+static PyObject *__pyx_tp_new_3_sa___pyx_scope_struct_29_genexpr(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_3_sa___pyx_scope_struct_29_genexpr *p;
   PyObject *o = (*t->tp_alloc)(t, 0);
   if (!o) return 0;
-  p = ((struct __pyx_obj_3_sa___pyx_scope_struct_31_genexpr *)o);
+  p = ((struct __pyx_obj_3_sa___pyx_scope_struct_29_genexpr *)o);
   p->__pyx_outer_scope = 0;
   p->__pyx_v_feat = 0;
   p->__pyx_t_0 = 0;
   return o;
 }
 
-static void __pyx_tp_dealloc_3_sa___pyx_scope_struct_31_genexpr(PyObject *o) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_31_genexpr *p = (struct __pyx_obj_3_sa___pyx_scope_struct_31_genexpr *)o;
+static void __pyx_tp_dealloc_3_sa___pyx_scope_struct_29_genexpr(PyObject *o) {
+  struct __pyx_obj_3_sa___pyx_scope_struct_29_genexpr *p = (struct __pyx_obj_3_sa___pyx_scope_struct_29_genexpr *)o;
   Py_CLEAR(p->__pyx_outer_scope);
   Py_CLEAR(p->__pyx_v_feat);
   Py_CLEAR(p->__pyx_t_0);
   (*Py_TYPE(o)->tp_free)(o);
 }
 
-static int __pyx_tp_traverse_3_sa___pyx_scope_struct_31_genexpr(PyObject *o, visitproc v, void *a) {
+static int __pyx_tp_traverse_3_sa___pyx_scope_struct_29_genexpr(PyObject *o, visitproc v, void *a) {
   int e;
-  struct __pyx_obj_3_sa___pyx_scope_struct_31_genexpr *p = (struct __pyx_obj_3_sa___pyx_scope_struct_31_genexpr *)o;
+  struct __pyx_obj_3_sa___pyx_scope_struct_29_genexpr *p = (struct __pyx_obj_3_sa___pyx_scope_struct_29_genexpr *)o;
   if (p->__pyx_outer_scope) {
     e = (*v)(((PyObject*)p->__pyx_outer_scope), a); if (e) return e;
   }
@@ -79515,11 +78867,11 @@ static int __pyx_tp_traverse_3_sa___pyx_scope_struct_31_genexpr(PyObject *o, vis
   return 0;
 }
 
-static int __pyx_tp_clear_3_sa___pyx_scope_struct_31_genexpr(PyObject *o) {
-  struct __pyx_obj_3_sa___pyx_scope_struct_31_genexpr *p = (struct __pyx_obj_3_sa___pyx_scope_struct_31_genexpr *)o;
+static int __pyx_tp_clear_3_sa___pyx_scope_struct_29_genexpr(PyObject *o) {
+  struct __pyx_obj_3_sa___pyx_scope_struct_29_genexpr *p = (struct __pyx_obj_3_sa___pyx_scope_struct_29_genexpr *)o;
   PyObject* tmp;
   tmp = ((PyObject*)p->__pyx_outer_scope);
-  p->__pyx_outer_scope = ((struct __pyx_obj_3_sa___pyx_scope_struct_30___str__ *)Py_None); Py_INCREF(Py_None);
+  p->__pyx_outer_scope = ((struct __pyx_obj_3_sa___pyx_scope_struct_28___str__ *)Py_None); Py_INCREF(Py_None);
   Py_XDECREF(tmp);
   tmp = ((PyObject*)p->__pyx_v_feat);
   p->__pyx_v_feat = Py_None; Py_INCREF(Py_None);
@@ -79530,11 +78882,11 @@ static int __pyx_tp_clear_3_sa___pyx_scope_struct_31_genexpr(PyObject *o) {
   return 0;
 }
 
-static PyMethodDef __pyx_methods_3_sa___pyx_scope_struct_31_genexpr[] = {
+static PyMethodDef __pyx_methods_3_sa___pyx_scope_struct_29_genexpr[] = {
   {0, 0, 0, 0}
 };
 
-static PyNumberMethods __pyx_tp_as_number___pyx_scope_struct_31_genexpr = {
+static PyNumberMethods __pyx_tp_as_number___pyx_scope_struct_29_genexpr = {
   0, /*nb_add*/
   0, /*nb_subtract*/
   0, /*nb_multiply*/
@@ -79592,7 +78944,7 @@ static PyNumberMethods __pyx_tp_as_number___pyx_scope_struct_31_genexpr = {
   #endif
 };
 
-static PySequenceMethods __pyx_tp_as_sequence___pyx_scope_struct_31_genexpr = {
+static PySequenceMethods __pyx_tp_as_sequence___pyx_scope_struct_29_genexpr = {
   0, /*sq_length*/
   0, /*sq_concat*/
   0, /*sq_repeat*/
@@ -79605,13 +78957,13 @@ static PySequenceMethods __pyx_tp_as_sequence___pyx_scope_struct_31_genexpr = {
   0, /*sq_inplace_repeat*/
 };
 
-static PyMappingMethods __pyx_tp_as_mapping___pyx_scope_struct_31_genexpr = {
+static PyMappingMethods __pyx_tp_as_mapping___pyx_scope_struct_29_genexpr = {
   0, /*mp_length*/
   0, /*mp_subscript*/
   0, /*mp_ass_subscript*/
 };
 
-static PyBufferProcs __pyx_tp_as_buffer___pyx_scope_struct_31_genexpr = {
+static PyBufferProcs __pyx_tp_as_buffer___pyx_scope_struct_29_genexpr = {
   #if PY_MAJOR_VERSION < 3
   0, /*bf_getreadbuffer*/
   #endif
@@ -79632,12 +78984,12 @@ static PyBufferProcs __pyx_tp_as_buffer___pyx_scope_struct_31_genexpr = {
   #endif
 };
 
-static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_31_genexpr = {
+static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_29_genexpr = {
   PyVarObject_HEAD_INIT(0, 0)
-  __Pyx_NAMESTR("_sa.__pyx_scope_struct_31_genexpr"), /*tp_name*/
-  sizeof(struct __pyx_obj_3_sa___pyx_scope_struct_31_genexpr), /*tp_basicsize*/
+  __Pyx_NAMESTR("_sa.__pyx_scope_struct_29_genexpr"), /*tp_name*/
+  sizeof(struct __pyx_obj_3_sa___pyx_scope_struct_29_genexpr), /*tp_basicsize*/
   0, /*tp_itemsize*/
-  __pyx_tp_dealloc_3_sa___pyx_scope_struct_31_genexpr, /*tp_dealloc*/
+  __pyx_tp_dealloc_3_sa___pyx_scope_struct_29_genexpr, /*tp_dealloc*/
   0, /*tp_print*/
   0, /*tp_getattr*/
   0, /*tp_setattr*/
@@ -79647,24 +78999,24 @@ static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_31_genexpr = {
   0, /*reserved*/
   #endif
   0, /*tp_repr*/
-  &__pyx_tp_as_number___pyx_scope_struct_31_genexpr, /*tp_as_number*/
-  &__pyx_tp_as_sequence___pyx_scope_struct_31_genexpr, /*tp_as_sequence*/
-  &__pyx_tp_as_mapping___pyx_scope_struct_31_genexpr, /*tp_as_mapping*/
+  &__pyx_tp_as_number___pyx_scope_struct_29_genexpr, /*tp_as_number*/
+  &__pyx_tp_as_sequence___pyx_scope_struct_29_genexpr, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping___pyx_scope_struct_29_genexpr, /*tp_as_mapping*/
   0, /*tp_hash*/
   0, /*tp_call*/
   0, /*tp_str*/
   0, /*tp_getattro*/
   0, /*tp_setattro*/
-  &__pyx_tp_as_buffer___pyx_scope_struct_31_genexpr, /*tp_as_buffer*/
+  &__pyx_tp_as_buffer___pyx_scope_struct_29_genexpr, /*tp_as_buffer*/
   Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
   0, /*tp_doc*/
-  __pyx_tp_traverse_3_sa___pyx_scope_struct_31_genexpr, /*tp_traverse*/
-  __pyx_tp_clear_3_sa___pyx_scope_struct_31_genexpr, /*tp_clear*/
+  __pyx_tp_traverse_3_sa___pyx_scope_struct_29_genexpr, /*tp_traverse*/
+  __pyx_tp_clear_3_sa___pyx_scope_struct_29_genexpr, /*tp_clear*/
   0, /*tp_richcompare*/
   0, /*tp_weaklistoffset*/
   0, /*tp_iter*/
   0, /*tp_iternext*/
-  __pyx_methods_3_sa___pyx_scope_struct_31_genexpr, /*tp_methods*/
+  __pyx_methods_3_sa___pyx_scope_struct_29_genexpr, /*tp_methods*/
   0, /*tp_members*/
   0, /*tp_getset*/
   0, /*tp_base*/
@@ -79674,7 +79026,7 @@ static PyTypeObject __pyx_type_3_sa___pyx_scope_struct_31_genexpr = {
   0, /*tp_dictoffset*/
   0, /*tp_init*/
   0, /*tp_alloc*/
-  __pyx_tp_new_3_sa___pyx_scope_struct_31_genexpr, /*tp_new*/
+  __pyx_tp_new_3_sa___pyx_scope_struct_29_genexpr, /*tp_new*/
   0, /*tp_free*/
   0, /*tp_is_gc*/
   0, /*tp_bases*/
@@ -79746,14 +79098,11 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_kp_s_14, __pyx_k_14, sizeof(__pyx_k_14), 0, 0, 1, 0},
   {&__pyx_kp_s_141, __pyx_k_141, sizeof(__pyx_k_141), 0, 0, 1, 0},
   {&__pyx_kp_s_145, __pyx_k_145, sizeof(__pyx_k_145), 0, 0, 1, 0},
-  {&__pyx_kp_s_151, __pyx_k_151, sizeof(__pyx_k_151), 0, 0, 1, 0},
-  {&__pyx_kp_s_152, __pyx_k_152, sizeof(__pyx_k_152), 0, 0, 1, 0},
-  {&__pyx_n_s_153, __pyx_k_153, sizeof(__pyx_k_153), 0, 0, 1, 1},
-  {&__pyx_kp_s_156, __pyx_k_156, sizeof(__pyx_k_156), 0, 0, 1, 0},
+  {&__pyx_n_s_151, __pyx_k_151, sizeof(__pyx_k_151), 0, 0, 1, 1},
+  {&__pyx_kp_s_154, __pyx_k_154, sizeof(__pyx_k_154), 0, 0, 1, 0},
   {&__pyx_kp_s_157, __pyx_k_157, sizeof(__pyx_k_157), 0, 0, 1, 0},
-  {&__pyx_kp_s_160, __pyx_k_160, sizeof(__pyx_k_160), 0, 0, 1, 0},
-  {&__pyx_kp_s_161, __pyx_k_161, sizeof(__pyx_k_161), 0, 0, 1, 0},
-  {&__pyx_kp_s_165, __pyx_k_165, sizeof(__pyx_k_165), 0, 0, 1, 0},
+  {&__pyx_kp_s_158, __pyx_k_158, sizeof(__pyx_k_158), 0, 0, 1, 0},
+  {&__pyx_kp_s_162, __pyx_k_162, sizeof(__pyx_k_162), 0, 0, 1, 0},
   {&__pyx_kp_s_18, __pyx_k_18, sizeof(__pyx_k_18), 0, 0, 1, 0},
   {&__pyx_kp_s_2, __pyx_k_2, sizeof(__pyx_k_2), 0, 0, 1, 0},
   {&__pyx_kp_s_21, __pyx_k_21, sizeof(__pyx_k_21), 0, 0, 1, 0},
@@ -79856,6 +79205,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s__decode_words, __pyx_k__decode_words, sizeof(__pyx_k__decode_words), 0, 0, 1, 1},
   {&__pyx_n_s__defaultdict, __pyx_k__defaultdict, sizeof(__pyx_k__defaultdict), 0, 0, 1, 1},
   {&__pyx_n_s__dist, __pyx_k__dist, sizeof(__pyx_k__dist), 0, 0, 1, 1},
+  {&__pyx_n_s__dump_online_rules, __pyx_k__dump_online_rules, sizeof(__pyx_k__dump_online_rules), 0, 0, 1, 1},
   {&__pyx_n_s__e, __pyx_k__e, sizeof(__pyx_k__e), 0, 0, 1, 1},
   {&__pyx_n_s__e_i, __pyx_k__e_i, sizeof(__pyx_k__e_i), 0, 0, 1, 1},
   {&__pyx_n_s__e_j, __pyx_k__e_j, sizeof(__pyx_k__e_j), 0, 0, 1, 1},
@@ -79901,6 +79251,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s__getLogger, __pyx_k__getLogger, sizeof(__pyx_k__getLogger), 0, 0, 1, 1},
   {&__pyx_n_s__get_e_id, __pyx_k__get_e_id, sizeof(__pyx_k__get_e_id), 0, 0, 1, 1},
   {&__pyx_n_s__get_f_id, __pyx_k__get_f_id, sizeof(__pyx_k__get_f_id), 0, 0, 1, 1},
+  {&__pyx_n_s__get_f_phrases, __pyx_k__get_f_phrases, sizeof(__pyx_k__get_f_phrases), 0, 0, 1, 1},
   {&__pyx_n_s__get_id, __pyx_k__get_id, sizeof(__pyx_k__get_id), 0, 0, 1, 1},
   {&__pyx_n_s__get_next_states, __pyx_k__get_next_states, sizeof(__pyx_k__get_next_states), 0, 0, 1, 1},
   {&__pyx_n_s__get_word, __pyx_k__get_word, sizeof(__pyx_k__get_word), 0, 0, 1, 1},
@@ -79929,6 +79280,8 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s__k, __pyx_k__k, sizeof(__pyx_k__k), 0, 0, 1, 1},
   {&__pyx_n_s__key, __pyx_k__key, sizeof(__pyx_k__key), 0, 0, 1, 1},
   {&__pyx_n_s__lattice, __pyx_k__lattice, sizeof(__pyx_k__lattice), 0, 0, 1, 1},
+  {&__pyx_n_s__lex_i, __pyx_k__lex_i, sizeof(__pyx_k__lex_i), 0, 0, 1, 1},
+  {&__pyx_n_s__lex_j, __pyx_k__lex_j, sizeof(__pyx_k__lex_j), 0, 0, 1, 1},
   {&__pyx_n_s__lhs, __pyx_k__lhs, sizeof(__pyx_k__lhs), 0, 0, 1, 1},
   {&__pyx_n_s__link, __pyx_k__link, sizeof(__pyx_k__link), 0, 0, 1, 1},
   {&__pyx_n_s__link_i, __pyx_k__link_i, sizeof(__pyx_k__link_i), 0, 0, 1, 1},
@@ -79957,6 +79310,8 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s__namedtuple, __pyx_k__namedtuple, sizeof(__pyx_k__namedtuple), 0, 0, 1, 1},
   {&__pyx_n_s__new_e_i, __pyx_k__new_e_i, sizeof(__pyx_k__new_e_i), 0, 0, 1, 1},
   {&__pyx_n_s__new_e_j, __pyx_k__new_e_j, sizeof(__pyx_k__new_e_j), 0, 0, 1, 1},
+  {&__pyx_n_s__new_lex_i, __pyx_k__new_lex_i, sizeof(__pyx_k__new_lex_i), 0, 0, 1, 1},
+  {&__pyx_n_s__new_lex_j, __pyx_k__new_lex_j, sizeof(__pyx_k__new_lex_j), 0, 0, 1, 1},
   {&__pyx_n_s__new_min_bound, __pyx_k__new_min_bound, sizeof(__pyx_k__new_min_bound), 0, 0, 1, 1},
   {&__pyx_n_s__next_states, __pyx_k__next_states, sizeof(__pyx_k__next_states), 0, 0, 1, 1},
   {&__pyx_n_s__nt, __pyx_k__nt, sizeof(__pyx_k__nt), 0, 0, 1, 1},
@@ -79968,7 +79323,6 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s__old_last_nt, __pyx_k__old_last_nt, sizeof(__pyx_k__old_last_nt), 0, 0, 1, 1},
   {&__pyx_n_s__online, __pyx_k__online, sizeof(__pyx_k__online), 0, 0, 1, 1},
   {&__pyx_n_s__online_ctx_lookup, __pyx_k__online_ctx_lookup, sizeof(__pyx_k__online_ctx_lookup), 0, 0, 1, 1},
-  {&__pyx_n_s__online_match, __pyx_k__online_match, sizeof(__pyx_k__online_match), 0, 0, 1, 1},
   {&__pyx_n_s__open, __pyx_k__open, sizeof(__pyx_k__open), 0, 0, 1, 1},
   {&__pyx_n_s__pad, __pyx_k__pad, sizeof(__pyx_k__pad), 0, 0, 1, 1},
   {&__pyx_n_s__paircount, __pyx_k__paircount, sizeof(__pyx_k__paircount), 0, 0, 1, 1},
@@ -80007,7 +79361,6 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s__scorer, __pyx_k__scorer, sizeof(__pyx_k__scorer), 0, 0, 1, 1},
   {&__pyx_n_s__scores, __pyx_k__scores, sizeof(__pyx_k__scores), 0, 0, 1, 1},
   {&__pyx_n_s__seek, __pyx_k__seek, sizeof(__pyx_k__seek), 0, 0, 1, 1},
-  {&__pyx_n_s__seen_phrases, __pyx_k__seen_phrases, sizeof(__pyx_k__seen_phrases), 0, 0, 1, 1},
   {&__pyx_n_s__set, __pyx_k__set, sizeof(__pyx_k__set), 0, 0, 1, 1},
   {&__pyx_n_s__shortest, __pyx_k__shortest, sizeof(__pyx_k__shortest), 0, 0, 1, 1},
   {&__pyx_n_s__side, __pyx_k__side, sizeof(__pyx_k__side), 0, 0, 1, 1},
@@ -80061,8 +79414,8 @@ static int __Pyx_InitCachedBuiltins(void) {
   __pyx_builtin_zip = __Pyx_GetName(__pyx_b, __pyx_n_s__zip); if (!__pyx_builtin_zip) {__pyx_filename = __pyx_f[5]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_builtin_StopIteration = __Pyx_GetName(__pyx_b, __pyx_n_s__StopIteration); if (!__pyx_builtin_StopIteration) {__pyx_filename = __pyx_f[6]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_builtin_cmp = __Pyx_GetName(__pyx_b, __pyx_n_s__cmp); if (!__pyx_builtin_cmp) {__pyx_filename = __pyx_f[7]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_builtin_sorted = __Pyx_GetName(__pyx_b, __pyx_n_s__sorted); if (!__pyx_builtin_sorted) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 963; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_builtin_max = __Pyx_GetName(__pyx_b, __pyx_n_s__max); if (!__pyx_builtin_max) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_sorted = __Pyx_GetName(__pyx_b, __pyx_n_s__sorted); if (!__pyx_builtin_sorted) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_max = __Pyx_GetName(__pyx_b, __pyx_n_s__max); if (!__pyx_builtin_max) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   return 0;
   __pyx_L1_error:;
   return -1;
@@ -80782,56 +80135,56 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GIVEREF(Py_None);
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_98));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":116
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":117
  *             logger.info("Sampling strategy: uniform, max sample size = %d", sample_size)
  *         else:
  *             logger.info("Sampling strategy: no sampling")             # <<<<<<<<<<<<<<
  * 
  *     def sample(self, PhraseLocation phrase_location):
  */
-  __pyx_k_tuple_102 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_102)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_102 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_102)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_102);
   __Pyx_INCREF(((PyObject *)__pyx_kp_s_101));
   PyTuple_SET_ITEM(__pyx_k_tuple_102, 0, ((PyObject *)__pyx_kp_s_101));
   __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_101));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_102));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":334
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":336
  *         self.rules.root = ExtendedTrieNode(phrase_location=PhraseLocation())
  *         if alignment is None:
  *             raise Exception("Must specify an alignment object")             # <<<<<<<<<<<<<<
  *         self.alignment = alignment
  * 
  */
-  __pyx_k_tuple_107 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_107)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_107 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_107)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 336; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_107);
   __Pyx_INCREF(((PyObject *)__pyx_kp_s_106));
   PyTuple_SET_ITEM(__pyx_k_tuple_107, 0, ((PyObject *)__pyx_kp_s_106));
   __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_106));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_107));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1055
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1060
  *                         else:
  *                             #ERROR: We never get here
  *                             raise Exception("Keyword trie error")             # <<<<<<<<<<<<<<
  *                 # checking whether lookup_required
  *                 if lookup_required:
  */
-  __pyx_k_tuple_122 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_122)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1055; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_122 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_122)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1060; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_122);
   __Pyx_INCREF(((PyObject *)__pyx_kp_s_121));
   PyTuple_SET_ITEM(__pyx_k_tuple_122, 0, ((PyObject *)__pyx_kp_s_121));
   __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_121));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_122));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1897
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1911
  *         # f_ i and j are current, e_ i and j are previous
  *         # We care _considering_ f_j, so it is not yet in counts
  *         def extract(f_i, f_j, e_i, e_j, min_bound, wc, links, nt, nt_open):             # <<<<<<<<<<<<<<
  *             # Phrase extraction limits
  *             if f_j > (f_len - 1) or (f_j - f_i) + 1 > self.max_initial_size:
  */
-  __pyx_k_tuple_134 = PyTuple_New(19); if (unlikely(!__pyx_k_tuple_134)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_134 = PyTuple_New(19); if (unlikely(!__pyx_k_tuple_134)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_134);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__f_i));
   PyTuple_SET_ITEM(__pyx_k_tuple_134, 0, ((PyObject *)__pyx_n_s__f_i));
@@ -80891,166 +80244,175 @@ static int __Pyx_InitCachedConstants(void) {
   PyTuple_SET_ITEM(__pyx_k_tuple_134, 18, ((PyObject *)__pyx_n_s__old_last_nt));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__old_last_nt));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_134));
-  __pyx_k_codeobj_135 = (PyObject*)__Pyx_PyCode_New(9, 0, 19, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_134, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_136, __pyx_n_s__extract, 1897, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_135)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_codeobj_135 = (PyObject*)__Pyx_PyCode_New(9, 0, 19, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_134, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_136, __pyx_n_s__extract, 1911, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_135)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2098
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2118
  *     # Debugging
  *     def dump_online_stats(self):
  *         logger.info('------------------------------')             # <<<<<<<<<<<<<<
  *         logger.info('         Online Stats         ')
  *         logger.info('------------------------------')
  */
-  __pyx_k_tuple_140 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_140)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2098; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_140 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_140)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_140);
   __Pyx_INCREF(((PyObject *)__pyx_kp_s_139));
   PyTuple_SET_ITEM(__pyx_k_tuple_140, 0, ((PyObject *)__pyx_kp_s_139));
   __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_139));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_140));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2099
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2119
  *     def dump_online_stats(self):
  *         logger.info('------------------------------')
  *         logger.info('         Online Stats         ')             # <<<<<<<<<<<<<<
  *         logger.info('------------------------------')
  *         logger.info('f')
  */
-  __pyx_k_tuple_142 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_142)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2099; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_142 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_142)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_142);
   __Pyx_INCREF(((PyObject *)__pyx_kp_s_141));
   PyTuple_SET_ITEM(__pyx_k_tuple_142, 0, ((PyObject *)__pyx_kp_s_141));
   __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_141));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_142));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2100
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2120
  *         logger.info('------------------------------')
  *         logger.info('         Online Stats         ')
  *         logger.info('------------------------------')             # <<<<<<<<<<<<<<
  *         logger.info('f')
  *         for w in self.bilex_f:
  */
-  __pyx_k_tuple_143 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_143)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_143 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_143)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_143);
   __Pyx_INCREF(((PyObject *)__pyx_kp_s_139));
   PyTuple_SET_ITEM(__pyx_k_tuple_143, 0, ((PyObject *)__pyx_kp_s_139));
   __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_139));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_143));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2101
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2121
  *         logger.info('         Online Stats         ')
  *         logger.info('------------------------------')
  *         logger.info('f')             # <<<<<<<<<<<<<<
  *         for w in self.bilex_f:
  *             logger.info(sym_tostring(w) + ' : ' + str(self.bilex_f[w]))
  */
-  __pyx_k_tuple_144 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_144)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_144 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_144)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_144);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__f));
   PyTuple_SET_ITEM(__pyx_k_tuple_144, 0, ((PyObject *)__pyx_n_s__f));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__f));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_144));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2104
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2124
  *         for w in self.bilex_f:
  *             logger.info(sym_tostring(w) + ' : ' + str(self.bilex_f[w]))
  *         logger.info('e')             # <<<<<<<<<<<<<<
  *         for w in self.bilex_e:
  *             logger.info(sym_tostring(w) + ' : ' + str(self.bilex_e[w]))
  */
-  __pyx_k_tuple_146 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_146)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_146 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_146)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_146);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__e));
   PyTuple_SET_ITEM(__pyx_k_tuple_146, 0, ((PyObject *)__pyx_n_s__e));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__e));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_146));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2107
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2127
  *         for w in self.bilex_e:
  *             logger.info(sym_tostring(w) + ' : ' + str(self.bilex_e[w]))
  *         logger.info('fe')             # <<<<<<<<<<<<<<
  *         for w in self.bilex_fe:
  *             for w2 in self.bilex_fe[w]:
  */
-  __pyx_k_tuple_147 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_147)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_147 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_147)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_147);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__fe));
   PyTuple_SET_ITEM(__pyx_k_tuple_147, 0, ((PyObject *)__pyx_n_s__fe));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__fe));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_147));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2111
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2131
  *             for w2 in self.bilex_fe[w]:
  *                 logger.info(sym_tostring(w) + ' : ' + sym_tostring(w2) + ' : ' + str(self.bilex_fe[w][w2]))
  *         logger.info('F')             # <<<<<<<<<<<<<<
  *         for ph in self.phrases_f:
  *             logger.info(str(ph) + ' ||| ' + str(self.phrases_f[ph]))
  */
-  __pyx_k_tuple_148 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_148)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_148 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_148)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_148);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__F));
   PyTuple_SET_ITEM(__pyx_k_tuple_148, 0, ((PyObject *)__pyx_n_s__F));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__F));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_148));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2114
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2134
  *         for ph in self.phrases_f:
  *             logger.info(str(ph) + ' ||| ' + str(self.phrases_f[ph]))
  *         logger.info('E')             # <<<<<<<<<<<<<<
  *         for ph in self.phrases_e:
  *             logger.info(str(ph) + ' ||| ' + str(self.phrases_e[ph]))
  */
-  __pyx_k_tuple_149 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_149)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_149 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_149)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_149);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__E));
   PyTuple_SET_ITEM(__pyx_k_tuple_149, 0, ((PyObject *)__pyx_n_s__E));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__E));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_149));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2117
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2137
  *         for ph in self.phrases_e:
  *             logger.info(str(ph) + ' ||| ' + str(self.phrases_e[ph]))
  *         logger.info('FE')             # <<<<<<<<<<<<<<
- *         for ph in self.phrases_fe:
- *             for ph2 in self.phrases_fe[ph]:
+ *         self.dump_online_rules()
+ * 
  */
-  __pyx_k_tuple_150 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_150)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_150 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_150)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_150);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__FE));
   PyTuple_SET_ITEM(__pyx_k_tuple_150, 0, ((PyObject *)__pyx_n_s__FE));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__FE));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_150));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2141
- *         matches = {} # (f, e) = len
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2164
+ *         phrases = set() # (fphrase, lex_i, lex_j)
  * 
- *         def extract(f_i, f_j, wc, ntc, syms):             # <<<<<<<<<<<<<<
+ *         def extract(f_i, f_j, lex_i, lex_j, wc, ntc, syms):             # <<<<<<<<<<<<<<
  *             # Phrase extraction limits
  *             if f_j > (f_len - 1) or (f_j - f_i) + 1 > self.max_initial_size:
  */
-  __pyx_k_tuple_154 = PyTuple_New(7); if (unlikely(!__pyx_k_tuple_154)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_154);
+  __pyx_k_tuple_152 = PyTuple_New(10); if (unlikely(!__pyx_k_tuple_152)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_152);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__f_i));
-  PyTuple_SET_ITEM(__pyx_k_tuple_154, 0, ((PyObject *)__pyx_n_s__f_i));
+  PyTuple_SET_ITEM(__pyx_k_tuple_152, 0, ((PyObject *)__pyx_n_s__f_i));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__f_i));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__f_j));
-  PyTuple_SET_ITEM(__pyx_k_tuple_154, 1, ((PyObject *)__pyx_n_s__f_j));
+  PyTuple_SET_ITEM(__pyx_k_tuple_152, 1, ((PyObject *)__pyx_n_s__f_j));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__f_j));
+  __Pyx_INCREF(((PyObject *)__pyx_n_s__lex_i));
+  PyTuple_SET_ITEM(__pyx_k_tuple_152, 2, ((PyObject *)__pyx_n_s__lex_i));
+  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__lex_i));
+  __Pyx_INCREF(((PyObject *)__pyx_n_s__lex_j));
+  PyTuple_SET_ITEM(__pyx_k_tuple_152, 3, ((PyObject *)__pyx_n_s__lex_j));
+  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__lex_j));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__wc));
-  PyTuple_SET_ITEM(__pyx_k_tuple_154, 2, ((PyObject *)__pyx_n_s__wc));
+  PyTuple_SET_ITEM(__pyx_k_tuple_152, 4, ((PyObject *)__pyx_n_s__wc));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__wc));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__ntc));
-  PyTuple_SET_ITEM(__pyx_k_tuple_154, 3, ((PyObject *)__pyx_n_s__ntc));
+  PyTuple_SET_ITEM(__pyx_k_tuple_152, 5, ((PyObject *)__pyx_n_s__ntc));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__ntc));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__syms));
-  PyTuple_SET_ITEM(__pyx_k_tuple_154, 4, ((PyObject *)__pyx_n_s__syms));
+  PyTuple_SET_ITEM(__pyx_k_tuple_152, 6, ((PyObject *)__pyx_n_s__syms));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__syms));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__f));
-  PyTuple_SET_ITEM(__pyx_k_tuple_154, 5, ((PyObject *)__pyx_n_s__f));
+  PyTuple_SET_ITEM(__pyx_k_tuple_152, 7, ((PyObject *)__pyx_n_s__f));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__f));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__e));
-  PyTuple_SET_ITEM(__pyx_k_tuple_154, 6, ((PyObject *)__pyx_n_s__e));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__e));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_154));
-  __pyx_k_codeobj_155 = (PyObject*)__Pyx_PyCode_New(5, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_154, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_136, __pyx_n_s__extract, 2141, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_155)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_INCREF(((PyObject *)__pyx_n_s__new_lex_i));
+  PyTuple_SET_ITEM(__pyx_k_tuple_152, 8, ((PyObject *)__pyx_n_s__new_lex_i));
+  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__new_lex_i));
+  __Pyx_INCREF(((PyObject *)__pyx_n_s__new_lex_j));
+  PyTuple_SET_ITEM(__pyx_k_tuple_152, 9, ((PyObject *)__pyx_n_s__new_lex_j));
+  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__new_lex_j));
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_152));
+  __pyx_k_codeobj_153 = (PyObject*)__Pyx_PyCode_New(7, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_152, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_136, __pyx_n_s__extract, 2164, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_153)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
   /* "_sa.pyx":9
  *             resource.getrusage(resource.RUSAGE_SELF).ru_stime)
@@ -81059,16 +80421,16 @@ static int __Pyx_InitCachedConstants(void) {
  *     if filename.endswith('.gz'):
  *         return gzip.GzipFile(filename)
  */
-  __pyx_k_tuple_158 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_158)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_158);
+  __pyx_k_tuple_155 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_155)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_155);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__filename));
-  PyTuple_SET_ITEM(__pyx_k_tuple_158, 0, ((PyObject *)__pyx_n_s__filename));
+  PyTuple_SET_ITEM(__pyx_k_tuple_155, 0, ((PyObject *)__pyx_n_s__filename));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__filename));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__filename));
-  PyTuple_SET_ITEM(__pyx_k_tuple_158, 1, ((PyObject *)__pyx_n_s__filename));
+  PyTuple_SET_ITEM(__pyx_k_tuple_155, 1, ((PyObject *)__pyx_n_s__filename));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__filename));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_158));
-  __pyx_k_codeobj_159 = (PyObject*)__Pyx_PyCode_New(1, 0, 2, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_158, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_160, __pyx_n_s__gzip_or_text, 9, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_159)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_155));
+  __pyx_k_codeobj_156 = (PyObject*)__Pyx_PyCode_New(1, 0, 2, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_155, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_157, __pyx_n_s__gzip_or_text, 9, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_156)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
   /* "_sa.pyx":15
  *         return open(filename)
@@ -81077,12 +80439,12 @@ static int __Pyx_InitCachedConstants(void) {
  * 
  * include "float_list.pxi"
  */
-  __pyx_k_tuple_162 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_162)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_162);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s_161));
-  PyTuple_SET_ITEM(__pyx_k_tuple_162, 0, ((PyObject *)__pyx_kp_s_161));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_161));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_162));
+  __pyx_k_tuple_159 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_159)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_159);
+  __Pyx_INCREF(((PyObject *)__pyx_kp_s_158));
+  PyTuple_SET_ITEM(__pyx_k_tuple_159, 0, ((PyObject *)__pyx_kp_s_158));
+  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_158));
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_159));
 
   /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":107
  *     return ALPHABET.fromstring(string, terminal)
@@ -81091,25 +80453,25 @@ static int __Pyx_InitCachedConstants(void) {
  *     word_ids = (sym_fromstring(word, True) for word in words)
  *     return tuple(((word, None, 1), ) for word in word_ids)
  */
-  __pyx_k_tuple_163 = PyTuple_New(5); if (unlikely(!__pyx_k_tuple_163)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_163);
+  __pyx_k_tuple_160 = PyTuple_New(5); if (unlikely(!__pyx_k_tuple_160)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_160);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__words));
-  PyTuple_SET_ITEM(__pyx_k_tuple_163, 0, ((PyObject *)__pyx_n_s__words));
+  PyTuple_SET_ITEM(__pyx_k_tuple_160, 0, ((PyObject *)__pyx_n_s__words));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__words));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__word_ids));
-  PyTuple_SET_ITEM(__pyx_k_tuple_163, 1, ((PyObject *)__pyx_n_s__word_ids));
+  PyTuple_SET_ITEM(__pyx_k_tuple_160, 1, ((PyObject *)__pyx_n_s__word_ids));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__word_ids));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__genexpr));
-  PyTuple_SET_ITEM(__pyx_k_tuple_163, 2, ((PyObject *)__pyx_n_s__genexpr));
+  PyTuple_SET_ITEM(__pyx_k_tuple_160, 2, ((PyObject *)__pyx_n_s__genexpr));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__genexpr));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__genexpr));
-  PyTuple_SET_ITEM(__pyx_k_tuple_163, 3, ((PyObject *)__pyx_n_s__genexpr));
+  PyTuple_SET_ITEM(__pyx_k_tuple_160, 3, ((PyObject *)__pyx_n_s__genexpr));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__genexpr));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__genexpr));
-  PyTuple_SET_ITEM(__pyx_k_tuple_163, 4, ((PyObject *)__pyx_n_s__genexpr));
+  PyTuple_SET_ITEM(__pyx_k_tuple_160, 4, ((PyObject *)__pyx_n_s__genexpr));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__genexpr));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_163));
-  __pyx_k_codeobj_164 = (PyObject*)__Pyx_PyCode_New(1, 0, 5, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_163, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_165, __pyx_n_s__make_lattice, 107, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_164)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_160));
+  __pyx_k_codeobj_161 = (PyObject*)__Pyx_PyCode_New(1, 0, 5, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_160, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_162, __pyx_n_s__make_lattice, 107, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_161)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
   /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":111
  *     return tuple(((word, None, 1), ) for word in word_ids)
@@ -81118,19 +80480,19 @@ static int __Pyx_InitCachedConstants(void) {
  *     return tuple((sym_tostring(sym), weight, dist) for (sym, weight, dist) in arc
  *             for arc in node for node in lattice)
  */
-  __pyx_k_tuple_166 = PyTuple_New(3); if (unlikely(!__pyx_k_tuple_166)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_166);
+  __pyx_k_tuple_163 = PyTuple_New(3); if (unlikely(!__pyx_k_tuple_163)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_163);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__lattice));
-  PyTuple_SET_ITEM(__pyx_k_tuple_166, 0, ((PyObject *)__pyx_n_s__lattice));
+  PyTuple_SET_ITEM(__pyx_k_tuple_163, 0, ((PyObject *)__pyx_n_s__lattice));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__lattice));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__genexpr));
-  PyTuple_SET_ITEM(__pyx_k_tuple_166, 1, ((PyObject *)__pyx_n_s__genexpr));
+  PyTuple_SET_ITEM(__pyx_k_tuple_163, 1, ((PyObject *)__pyx_n_s__genexpr));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__genexpr));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__genexpr));
-  PyTuple_SET_ITEM(__pyx_k_tuple_166, 2, ((PyObject *)__pyx_n_s__genexpr));
+  PyTuple_SET_ITEM(__pyx_k_tuple_163, 2, ((PyObject *)__pyx_n_s__genexpr));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__genexpr));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_166));
-  __pyx_k_codeobj_167 = (PyObject*)__Pyx_PyCode_New(1, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_166, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_165, __pyx_n_s__decode_lattice, 111, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_167)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_163));
+  __pyx_k_codeobj_164 = (PyObject*)__Pyx_PyCode_New(1, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_163, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_162, __pyx_n_s__decode_lattice, 111, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_164)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
   /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":115
  *             for arc in node for node in lattice)
@@ -81139,19 +80501,19 @@ static int __Pyx_InitCachedConstants(void) {
  *     return tuple(sym_tostring(sym) for ((sym, _, _),) in lattice)
  * 
  */
-  __pyx_k_tuple_168 = PyTuple_New(3); if (unlikely(!__pyx_k_tuple_168)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_168);
+  __pyx_k_tuple_165 = PyTuple_New(3); if (unlikely(!__pyx_k_tuple_165)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_165);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__lattice));
-  PyTuple_SET_ITEM(__pyx_k_tuple_168, 0, ((PyObject *)__pyx_n_s__lattice));
+  PyTuple_SET_ITEM(__pyx_k_tuple_165, 0, ((PyObject *)__pyx_n_s__lattice));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__lattice));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__genexpr));
-  PyTuple_SET_ITEM(__pyx_k_tuple_168, 1, ((PyObject *)__pyx_n_s__genexpr));
+  PyTuple_SET_ITEM(__pyx_k_tuple_165, 1, ((PyObject *)__pyx_n_s__genexpr));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__genexpr));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__genexpr));
-  PyTuple_SET_ITEM(__pyx_k_tuple_168, 2, ((PyObject *)__pyx_n_s__genexpr));
+  PyTuple_SET_ITEM(__pyx_k_tuple_165, 2, ((PyObject *)__pyx_n_s__genexpr));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__genexpr));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_168));
-  __pyx_k_codeobj_169 = (PyObject*)__Pyx_PyCode_New(1, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_168, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_165, __pyx_n_s__decode_sentence, 115, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_169)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_165));
+  __pyx_k_codeobj_166 = (PyObject*)__Pyx_PyCode_New(1, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_165, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_162, __pyx_n_s__decode_sentence, 115, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_166)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
   /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":118
  *     return tuple(sym_tostring(sym) for ((sym, _, _),) in lattice)
@@ -81160,19 +80522,19 @@ static int __Pyx_InitCachedConstants(void) {
  *     return tuple(sym_fromstring(word, True) for word in words)
  * 
  */
-  __pyx_k_tuple_170 = PyTuple_New(3); if (unlikely(!__pyx_k_tuple_170)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_170);
+  __pyx_k_tuple_167 = PyTuple_New(3); if (unlikely(!__pyx_k_tuple_167)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_167);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__words));
-  PyTuple_SET_ITEM(__pyx_k_tuple_170, 0, ((PyObject *)__pyx_n_s__words));
+  PyTuple_SET_ITEM(__pyx_k_tuple_167, 0, ((PyObject *)__pyx_n_s__words));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__words));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__genexpr));
-  PyTuple_SET_ITEM(__pyx_k_tuple_170, 1, ((PyObject *)__pyx_n_s__genexpr));
+  PyTuple_SET_ITEM(__pyx_k_tuple_167, 1, ((PyObject *)__pyx_n_s__genexpr));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__genexpr));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__genexpr));
-  PyTuple_SET_ITEM(__pyx_k_tuple_170, 2, ((PyObject *)__pyx_n_s__genexpr));
+  PyTuple_SET_ITEM(__pyx_k_tuple_167, 2, ((PyObject *)__pyx_n_s__genexpr));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__genexpr));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_170));
-  __pyx_k_codeobj_171 = (PyObject*)__Pyx_PyCode_New(1, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_170, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_165, __pyx_n_s__encode_words, 118, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_171)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_167));
+  __pyx_k_codeobj_168 = (PyObject*)__Pyx_PyCode_New(1, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_167, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_162, __pyx_n_s__encode_words, 118, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_168)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
   /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":121
  *     return tuple(sym_fromstring(word, True) for word in words)
@@ -81180,91 +80542,91 @@ static int __Pyx_InitCachedConstants(void) {
  * def decode_words(syms):             # <<<<<<<<<<<<<<
  *     return tuple(sym_tostring(sym) for sym in syms)
  */
-  __pyx_k_tuple_172 = PyTuple_New(3); if (unlikely(!__pyx_k_tuple_172)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_172);
+  __pyx_k_tuple_169 = PyTuple_New(3); if (unlikely(!__pyx_k_tuple_169)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_169);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__syms));
-  PyTuple_SET_ITEM(__pyx_k_tuple_172, 0, ((PyObject *)__pyx_n_s__syms));
+  PyTuple_SET_ITEM(__pyx_k_tuple_169, 0, ((PyObject *)__pyx_n_s__syms));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__syms));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__genexpr));
-  PyTuple_SET_ITEM(__pyx_k_tuple_172, 1, ((PyObject *)__pyx_n_s__genexpr));
+  PyTuple_SET_ITEM(__pyx_k_tuple_169, 1, ((PyObject *)__pyx_n_s__genexpr));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__genexpr));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__genexpr));
-  PyTuple_SET_ITEM(__pyx_k_tuple_172, 2, ((PyObject *)__pyx_n_s__genexpr));
+  PyTuple_SET_ITEM(__pyx_k_tuple_169, 2, ((PyObject *)__pyx_n_s__genexpr));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__genexpr));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_172));
-  __pyx_k_codeobj_173 = (PyObject*)__Pyx_PyCode_New(1, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_172, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_165, __pyx_n_s__decode_words, 121, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_173)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_169));
+  __pyx_k_codeobj_170 = (PyObject*)__Pyx_PyCode_New(1, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_169, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_162, __pyx_n_s__decode_words, 121, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_170)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2179
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2198
  * 
  * # Spans are _inclusive_ on both ends [i, j]
  * def span_check(vec, i, j):             # <<<<<<<<<<<<<<
  *     k = i
  *     while k <= j:
  */
-  __pyx_k_tuple_175 = PyTuple_New(4); if (unlikely(!__pyx_k_tuple_175)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_175);
+  __pyx_k_tuple_172 = PyTuple_New(4); if (unlikely(!__pyx_k_tuple_172)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2198; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_172);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__vec));
-  PyTuple_SET_ITEM(__pyx_k_tuple_175, 0, ((PyObject *)__pyx_n_s__vec));
+  PyTuple_SET_ITEM(__pyx_k_tuple_172, 0, ((PyObject *)__pyx_n_s__vec));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__vec));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__i));
-  PyTuple_SET_ITEM(__pyx_k_tuple_175, 1, ((PyObject *)__pyx_n_s__i));
+  PyTuple_SET_ITEM(__pyx_k_tuple_172, 1, ((PyObject *)__pyx_n_s__i));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__i));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__j));
-  PyTuple_SET_ITEM(__pyx_k_tuple_175, 2, ((PyObject *)__pyx_n_s__j));
+  PyTuple_SET_ITEM(__pyx_k_tuple_172, 2, ((PyObject *)__pyx_n_s__j));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__j));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__k));
-  PyTuple_SET_ITEM(__pyx_k_tuple_175, 3, ((PyObject *)__pyx_n_s__k));
+  PyTuple_SET_ITEM(__pyx_k_tuple_172, 3, ((PyObject *)__pyx_n_s__k));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__k));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_175));
-  __pyx_k_codeobj_176 = (PyObject*)__Pyx_PyCode_New(3, 0, 4, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_175, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_136, __pyx_n_s__span_check, 2179, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_176)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_172));
+  __pyx_k_codeobj_173 = (PyObject*)__Pyx_PyCode_New(3, 0, 4, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_172, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_136, __pyx_n_s__span_check, 2198, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_173)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2198; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2187
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2206
  *     return True
  * 
  * def span_inc(vec, i, j):             # <<<<<<<<<<<<<<
  *     k = i
  *     while k <= j:
  */
-  __pyx_k_tuple_177 = PyTuple_New(4); if (unlikely(!__pyx_k_tuple_177)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_177);
+  __pyx_k_tuple_174 = PyTuple_New(4); if (unlikely(!__pyx_k_tuple_174)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2206; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_174);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__vec));
-  PyTuple_SET_ITEM(__pyx_k_tuple_177, 0, ((PyObject *)__pyx_n_s__vec));
+  PyTuple_SET_ITEM(__pyx_k_tuple_174, 0, ((PyObject *)__pyx_n_s__vec));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__vec));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__i));
-  PyTuple_SET_ITEM(__pyx_k_tuple_177, 1, ((PyObject *)__pyx_n_s__i));
+  PyTuple_SET_ITEM(__pyx_k_tuple_174, 1, ((PyObject *)__pyx_n_s__i));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__i));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__j));
-  PyTuple_SET_ITEM(__pyx_k_tuple_177, 2, ((PyObject *)__pyx_n_s__j));
+  PyTuple_SET_ITEM(__pyx_k_tuple_174, 2, ((PyObject *)__pyx_n_s__j));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__j));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__k));
-  PyTuple_SET_ITEM(__pyx_k_tuple_177, 3, ((PyObject *)__pyx_n_s__k));
+  PyTuple_SET_ITEM(__pyx_k_tuple_174, 3, ((PyObject *)__pyx_n_s__k));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__k));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_177));
-  __pyx_k_codeobj_178 = (PyObject*)__Pyx_PyCode_New(3, 0, 4, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_177, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_136, __pyx_n_s__span_inc, 2187, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_178)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_174));
+  __pyx_k_codeobj_175 = (PyObject*)__Pyx_PyCode_New(3, 0, 4, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_174, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_136, __pyx_n_s__span_inc, 2206, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_175)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2206; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2193
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2212
  *         k += 1
  * 
  * def span_dec(vec, i, j):             # <<<<<<<<<<<<<<
  *     k = i
  *     while k <= j:
  */
-  __pyx_k_tuple_179 = PyTuple_New(4); if (unlikely(!__pyx_k_tuple_179)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_179);
+  __pyx_k_tuple_176 = PyTuple_New(4); if (unlikely(!__pyx_k_tuple_176)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_176);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__vec));
-  PyTuple_SET_ITEM(__pyx_k_tuple_179, 0, ((PyObject *)__pyx_n_s__vec));
+  PyTuple_SET_ITEM(__pyx_k_tuple_176, 0, ((PyObject *)__pyx_n_s__vec));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__vec));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__i));
-  PyTuple_SET_ITEM(__pyx_k_tuple_179, 1, ((PyObject *)__pyx_n_s__i));
+  PyTuple_SET_ITEM(__pyx_k_tuple_176, 1, ((PyObject *)__pyx_n_s__i));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__i));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__j));
-  PyTuple_SET_ITEM(__pyx_k_tuple_179, 2, ((PyObject *)__pyx_n_s__j));
+  PyTuple_SET_ITEM(__pyx_k_tuple_176, 2, ((PyObject *)__pyx_n_s__j));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__j));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__k));
-  PyTuple_SET_ITEM(__pyx_k_tuple_179, 3, ((PyObject *)__pyx_n_s__k));
+  PyTuple_SET_ITEM(__pyx_k_tuple_176, 3, ((PyObject *)__pyx_n_s__k));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__k));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_179));
-  __pyx_k_codeobj_180 = (PyObject*)__Pyx_PyCode_New(3, 0, 4, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_179, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_136, __pyx_n_s__span_dec, 2193, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_180)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_176));
+  __pyx_k_codeobj_177 = (PyObject*)__Pyx_PyCode_New(3, 0, 4, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_176, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_136, __pyx_n_s__span_dec, 2212, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_177)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_RefNannyFinishContext();
   return 0;
   __pyx_L1_error:;
@@ -81485,24 +80847,24 @@ PyMODINIT_FUNC PyInit__sa(void)
   if (__Pyx_SetVtable(__pyx_type_3_sa_SuffixArray.tp_dict, __pyx_vtabptr_3_sa_SuffixArray) < 0) {__pyx_filename = __pyx_f[12]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   if (__Pyx_SetAttrString(__pyx_m, "SuffixArray", (PyObject *)&__pyx_type_3_sa_SuffixArray) < 0) {__pyx_filename = __pyx_f[12]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa_SuffixArray = &__pyx_type_3_sa_SuffixArray;
-  if (PyType_Ready(&__pyx_type_3_sa_TrieNode) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 43; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (__Pyx_SetAttrString(__pyx_m, "TrieNode", (PyObject *)&__pyx_type_3_sa_TrieNode) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 43; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa_TrieNode) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "TrieNode", (PyObject *)&__pyx_type_3_sa_TrieNode) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa_TrieNode = &__pyx_type_3_sa_TrieNode;
   __pyx_type_3_sa_ExtendedTrieNode.tp_base = __pyx_ptype_3_sa_TrieNode;
-  if (PyType_Ready(&__pyx_type_3_sa_ExtendedTrieNode) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (__Pyx_SetAttrString(__pyx_m, "ExtendedTrieNode", (PyObject *)&__pyx_type_3_sa_ExtendedTrieNode) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa_ExtendedTrieNode) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "ExtendedTrieNode", (PyObject *)&__pyx_type_3_sa_ExtendedTrieNode) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa_ExtendedTrieNode = &__pyx_type_3_sa_ExtendedTrieNode;
-  if (PyType_Ready(&__pyx_type_3_sa_TrieTable) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (__Pyx_SetAttrString(__pyx_m, "TrieTable", (PyObject *)&__pyx_type_3_sa_TrieTable) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa_TrieTable) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "TrieTable", (PyObject *)&__pyx_type_3_sa_TrieTable) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa_TrieTable = &__pyx_type_3_sa_TrieTable;
   __pyx_vtabptr_3_sa_PhraseLocation = &__pyx_vtable_3_sa_PhraseLocation;
   __pyx_vtable_3_sa_PhraseLocation.contains = (int (*)(struct __pyx_obj_3_sa_PhraseLocation *, int))__pyx_f_3_sa_14PhraseLocation_contains;
-  if (PyType_Ready(&__pyx_type_3_sa_PhraseLocation) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (__Pyx_SetVtable(__pyx_type_3_sa_PhraseLocation.tp_dict, __pyx_vtabptr_3_sa_PhraseLocation) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (__Pyx_SetAttrString(__pyx_m, "PhraseLocation", (PyObject *)&__pyx_type_3_sa_PhraseLocation) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa_PhraseLocation) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetVtable(__pyx_type_3_sa_PhraseLocation.tp_dict, __pyx_vtabptr_3_sa_PhraseLocation) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "PhraseLocation", (PyObject *)&__pyx_type_3_sa_PhraseLocation) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa_PhraseLocation = &__pyx_type_3_sa_PhraseLocation;
-  if (PyType_Ready(&__pyx_type_3_sa_Sampler) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (__Pyx_SetAttrString(__pyx_m, "Sampler", (PyObject *)&__pyx_type_3_sa_Sampler) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa_Sampler) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "Sampler", (PyObject *)&__pyx_type_3_sa_Sampler) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa_Sampler = &__pyx_type_3_sa_Sampler;
   __pyx_vtabptr_3_sa_HieroCachingRuleFactory = &__pyx_vtable_3_sa_HieroCachingRuleFactory;
   __pyx_vtable_3_sa_HieroCachingRuleFactory.set_idmap = (PyObject *(*)(struct __pyx_obj_3_sa_HieroCachingRuleFactory *, struct __pyx_obj_3_sa_DataArray *))__pyx_f_3_sa_23HieroCachingRuleFactory_set_idmap;
@@ -81520,9 +80882,9 @@ PyMODINIT_FUNC PyInit__sa(void)
   __pyx_vtable_3_sa_HieroCachingRuleFactory.extract_phrases = (PyObject *(*)(struct __pyx_obj_3_sa_HieroCachingRuleFactory *, int, int, int *, int *, int *, int, int, int, int *, int *, int *, int, int, int))__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases;
   __pyx_vtable_3_sa_HieroCachingRuleFactory.create_alignments = (struct __pyx_obj_3_sa_IntList *(*)(struct __pyx_obj_3_sa_HieroCachingRuleFactory *, int *, int, PyObject *, PyObject *))__pyx_f_3_sa_23HieroCachingRuleFactory_create_alignments;
   __pyx_vtable_3_sa_HieroCachingRuleFactory.extract = (PyObject *(*)(struct __pyx_obj_3_sa_HieroCachingRuleFactory *, struct __pyx_obj_3_sa_Phrase *, struct __pyx_t_3_sa_Matching *, int *, int))__pyx_f_3_sa_23HieroCachingRuleFactory_extract;
-  if (PyType_Ready(&__pyx_type_3_sa_HieroCachingRuleFactory) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (__Pyx_SetVtable(__pyx_type_3_sa_HieroCachingRuleFactory.tp_dict, __pyx_vtabptr_3_sa_HieroCachingRuleFactory) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (__Pyx_SetAttrString(__pyx_m, "HieroCachingRuleFactory", (PyObject *)&__pyx_type_3_sa_HieroCachingRuleFactory) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa_HieroCachingRuleFactory) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetVtable(__pyx_type_3_sa_HieroCachingRuleFactory.tp_dict, __pyx_vtabptr_3_sa_HieroCachingRuleFactory) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "HieroCachingRuleFactory", (PyObject *)&__pyx_type_3_sa_HieroCachingRuleFactory) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa_HieroCachingRuleFactory = &__pyx_type_3_sa_HieroCachingRuleFactory;
   __pyx_vtabptr_3_sa_Scorer = &__pyx_vtable_3_sa_Scorer;
   __pyx_vtable_3_sa_Scorer.score = (struct __pyx_obj_3_sa_FeatureVector *(*)(struct __pyx_obj_3_sa_Scorer *, PyObject *))__pyx_f_3_sa_6Scorer_score;
@@ -81568,32 +80930,28 @@ PyMODINIT_FUNC PyInit__sa(void)
   __pyx_ptype_3_sa___pyx_scope_struct_17_genexpr = &__pyx_type_3_sa___pyx_scope_struct_17_genexpr;
   if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_18_alignments) < 0) {__pyx_filename = __pyx_f[7]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_18_alignments = &__pyx_type_3_sa___pyx_scope_struct_18_alignments;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_19_input) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 965; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_19_input) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 970; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_19_input = &__pyx_type_3_sa___pyx_scope_struct_19_input;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_20_genexpr) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_20_genexpr) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_20_genexpr = &__pyx_type_3_sa___pyx_scope_struct_20_genexpr;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_21_add_instance) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1863; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_21_add_instance) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1877; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_21_add_instance = &__pyx_type_3_sa___pyx_scope_struct_21_add_instance;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_22_form_rule) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2027; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_22_form_rule) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2047; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_22_form_rule = &__pyx_type_3_sa___pyx_scope_struct_22_form_rule;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_23_genexpr) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2088; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_23_genexpr) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_23_genexpr = &__pyx_type_3_sa___pyx_scope_struct_23_genexpr;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_24_fmt_rule) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2092; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_24_fmt_rule) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_24_fmt_rule = &__pyx_type_3_sa___pyx_scope_struct_24_fmt_rule;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_25_genexpr) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_25_genexpr) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_25_genexpr = &__pyx_type_3_sa___pyx_scope_struct_25_genexpr;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_26_online_match) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_ptype_3_sa___pyx_scope_struct_26_online_match = &__pyx_type_3_sa___pyx_scope_struct_26_online_match;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_27_genexpr) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_ptype_3_sa___pyx_scope_struct_27_genexpr = &__pyx_type_3_sa___pyx_scope_struct_27_genexpr;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_28_genexpr) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_ptype_3_sa___pyx_scope_struct_28_genexpr = &__pyx_type_3_sa___pyx_scope_struct_28_genexpr;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_29___iter__) < 0) {__pyx_filename = __pyx_f[13]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_ptype_3_sa___pyx_scope_struct_29___iter__ = &__pyx_type_3_sa___pyx_scope_struct_29___iter__;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_30___str__) < 0) {__pyx_filename = __pyx_f[13]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_ptype_3_sa___pyx_scope_struct_30___str__ = &__pyx_type_3_sa___pyx_scope_struct_30___str__;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_31_genexpr) < 0) {__pyx_filename = __pyx_f[13]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_ptype_3_sa___pyx_scope_struct_31_genexpr = &__pyx_type_3_sa___pyx_scope_struct_31_genexpr;
+  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_26_get_f_phrases) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_3_sa___pyx_scope_struct_26_get_f_phrases = &__pyx_type_3_sa___pyx_scope_struct_26_get_f_phrases;
+  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_27___iter__) < 0) {__pyx_filename = __pyx_f[13]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_3_sa___pyx_scope_struct_27___iter__ = &__pyx_type_3_sa___pyx_scope_struct_27___iter__;
+  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_28___str__) < 0) {__pyx_filename = __pyx_f[13]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_3_sa___pyx_scope_struct_28___str__ = &__pyx_type_3_sa___pyx_scope_struct_28___str__;
+  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_29_genexpr) < 0) {__pyx_filename = __pyx_f[13]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_3_sa___pyx_scope_struct_29_genexpr = &__pyx_type_3_sa___pyx_scope_struct_29_genexpr;
   /*--- Type import code ---*/
   /*--- Variable import code ---*/
   /*--- Function import code ---*/
@@ -81656,7 +81014,7 @@ PyMODINIT_FUNC PyInit__sa(void)
   __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__getLogger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_k_tuple_162), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_k_tuple_159), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   if (PyObject_SetAttr(__pyx_m, __pyx_n_s__logger, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
@@ -81943,7 +81301,7 @@ PyMODINIT_FUNC PyInit__sa(void)
  * 
  * OnlineFeatureContext = namedtuple('OnlineFeatureContext',             # <<<<<<<<<<<<<<
  *     ['fcount',
- *      'paircount',
+ *      'fsample_count',
  */
   __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__namedtuple); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
@@ -81952,25 +81310,28 @@ PyMODINIT_FUNC PyInit__sa(void)
  * 
  * OnlineFeatureContext = namedtuple('OnlineFeatureContext',
  *     ['fcount',             # <<<<<<<<<<<<<<
+ *      'fsample_count',
  *      'paircount',
- *      'bilex'
  */
-  __pyx_t_3 = PyList_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyList_New(4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__fcount));
   PyList_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_n_s__fcount));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__fcount));
+  __Pyx_INCREF(((PyObject *)__pyx_n_s__fsample_count));
+  PyList_SET_ITEM(__pyx_t_3, 1, ((PyObject *)__pyx_n_s__fsample_count));
+  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__fsample_count));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__paircount));
-  PyList_SET_ITEM(__pyx_t_3, 1, ((PyObject *)__pyx_n_s__paircount));
+  PyList_SET_ITEM(__pyx_t_3, 2, ((PyObject *)__pyx_n_s__paircount));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__paircount));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__bilex));
-  PyList_SET_ITEM(__pyx_t_3, 2, ((PyObject *)__pyx_n_s__bilex));
+  PyList_SET_ITEM(__pyx_t_3, 3, ((PyObject *)__pyx_n_s__bilex));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__bilex));
   __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s_153));
-  PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_n_s_153));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s_153));
+  __Pyx_INCREF(((PyObject *)__pyx_n_s_151));
+  PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_n_s_151));
+  __Pyx_GIVEREF(((PyObject *)__pyx_n_s_151));
   PyTuple_SET_ITEM(__pyx_t_2, 1, ((PyObject *)__pyx_t_3));
   __Pyx_GIVEREF(((PyObject *)__pyx_t_3));
   __pyx_t_3 = 0;
@@ -81978,10 +81339,10 @@ PyMODINIT_FUNC PyInit__sa(void)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_153, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_151, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":36
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":37
  *     ])
  * 
  * cdef int PRECOMPUTE = 0             # <<<<<<<<<<<<<<
@@ -81990,7 +81351,7 @@ PyMODINIT_FUNC PyInit__sa(void)
  */
   __pyx_v_3_sa_PRECOMPUTE = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":37
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":38
  * 
  * cdef int PRECOMPUTE = 0
  * cdef int MERGE = 1             # <<<<<<<<<<<<<<
@@ -81999,7 +81360,7 @@ PyMODINIT_FUNC PyInit__sa(void)
  */
   __pyx_v_3_sa_MERGE = 1;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":38
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":39
  * cdef int PRECOMPUTE = 0
  * cdef int MERGE = 1
  * cdef int BAEZA_YATES = 2             # <<<<<<<<<<<<<<
@@ -82008,62 +81369,62 @@ PyMODINIT_FUNC PyInit__sa(void)
  */
   __pyx_v_3_sa_BAEZA_YATES = 2;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":41
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":42
  * 
  * # NOTE: was encoded as a non-terminal in the previous version
  * cdef int EPSILON = sym_fromstring('*EPS*', True)             # <<<<<<<<<<<<<<
  * 
  * cdef class TrieNode:
  */
-  __pyx_v_3_sa_EPSILON = __pyx_f_3_sa_sym_fromstring(__pyx_k_174, 1);
+  __pyx_v_3_sa_EPSILON = __pyx_f_3_sa_sym_fromstring(__pyx_k_171, 1);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":64
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":65
  *     cdef public int count
  *     cdef public root
  *     def __cinit__(self, extended=False):             # <<<<<<<<<<<<<<
  *         self.count = 0
  *         self.extended = extended
  */
-  __pyx_t_3 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_k_99 = __pyx_t_3;
   __Pyx_GIVEREF(__pyx_t_3);
   __pyx_t_3 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2179
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2198
  * 
  * # Spans are _inclusive_ on both ends [i, j]
  * def span_check(vec, i, j):             # <<<<<<<<<<<<<<
  *     k = i
  *     while k <= j:
  */
-  __pyx_t_3 = PyCFunction_NewEx(&__pyx_mdef_3_sa_13span_check, NULL, __pyx_n_s___sa); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyCFunction_NewEx(&__pyx_mdef_3_sa_13span_check, NULL, __pyx_n_s___sa); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2198; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__span_check, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__span_check, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2198; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2187
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2206
  *     return True
  * 
  * def span_inc(vec, i, j):             # <<<<<<<<<<<<<<
  *     k = i
  *     while k <= j:
  */
-  __pyx_t_3 = PyCFunction_NewEx(&__pyx_mdef_3_sa_15span_inc, NULL, __pyx_n_s___sa); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyCFunction_NewEx(&__pyx_mdef_3_sa_15span_inc, NULL, __pyx_n_s___sa); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2206; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__span_inc, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__span_inc, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2206; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2193
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2212
  *         k += 1
  * 
  * def span_dec(vec, i, j):             # <<<<<<<<<<<<<<
  *     k = i
  *     while k <= j:
  */
-  __pyx_t_3 = PyCFunction_NewEx(&__pyx_mdef_3_sa_17span_dec, NULL, __pyx_n_s___sa); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyCFunction_NewEx(&__pyx_mdef_3_sa_17span_dec, NULL, __pyx_n_s___sa); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__span_dec, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__span_dec, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
   /* "/home/m/workspace/cdec/python/src/sa/features.pxi":1
@@ -83396,106 +82757,6 @@ static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *func, PyOb
     Py_INCREF(tuple);
 }
 
-#if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION < 3
-static PyObject *__Pyx_GetStdout(void) {
-    PyObject *f = PySys_GetObject((char *)"stdout");
-    if (!f) {
-        PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
-    }
-    return f;
-}
-static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
-    int i;
-    if (!f) {
-        if (!(f = __Pyx_GetStdout()))
-            return -1;
-    }
-    Py_INCREF(f);
-    for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
-        PyObject* v;
-        if (PyFile_SoftSpace(f, 1)) {
-            if (PyFile_WriteString(" ", f) < 0)
-                goto error;
-        }
-        v = PyTuple_GET_ITEM(arg_tuple, i);
-        if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
-            goto error;
-        if (PyString_Check(v)) {
-            char *s = PyString_AsString(v);
-            Py_ssize_t len = PyString_Size(v);
-            if (len > 0 &&
-                isspace(Py_CHARMASK(s[len-1])) &&
-                s[len-1] != ' ')
-                    PyFile_SoftSpace(f, 0);
-        }
-    }
-    if (newline) {
-        if (PyFile_WriteString("\n", f) < 0)
-            goto error;
-        PyFile_SoftSpace(f, 0);
-    }
-    Py_DECREF(f);
-    return 0;
-error:
-    Py_DECREF(f);
-    return -1;
-}
-#else /* Python 3 has a print function */
-static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
-    PyObject* kwargs = 0;
-    PyObject* result = 0;
-    PyObject* end_string;
-    if (unlikely(!__pyx_print)) {
-        __pyx_print = __Pyx_GetAttrString(__pyx_b, "print");
-        if (!__pyx_print)
-            return -1;
-    }
-    if (stream) {
-        kwargs = PyDict_New();
-        if (unlikely(!kwargs))
-            return -1;
-        if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
-            goto bad;
-        if (!newline) {
-            end_string = PyUnicode_FromStringAndSize(" ", 1);
-            if (unlikely(!end_string))
-                goto bad;
-            if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
-                Py_DECREF(end_string);
-                goto bad;
-            }
-            Py_DECREF(end_string);
-        }
-    } else if (!newline) {
-        if (unlikely(!__pyx_print_kwargs)) {
-            __pyx_print_kwargs = PyDict_New();
-            if (unlikely(!__pyx_print_kwargs))
-                return -1;
-            end_string = PyUnicode_FromStringAndSize(" ", 1);
-            if (unlikely(!end_string))
-                return -1;
-            if (PyDict_SetItemString(__pyx_print_kwargs, "end", end_string) < 0) {
-                Py_DECREF(end_string);
-                return -1;
-            }
-            Py_DECREF(end_string);
-        }
-        kwargs = __pyx_print_kwargs;
-    }
-    result = PyObject_Call(__pyx_print, arg_tuple, kwargs);
-    if (unlikely(kwargs) && (kwargs != __pyx_print_kwargs))
-        Py_DECREF(kwargs);
-    if (!result)
-        return -1;
-    Py_DECREF(result);
-    return 0;
-bad:
-    if (kwargs != __pyx_print_kwargs)
-        Py_XDECREF(kwargs);
-    return -1;
-}
-#endif
-
 static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject* x) {
     const unsigned char neg_one = (unsigned char)-1, const_zero = 0;
     const int is_unsigned = neg_one > const_zero;
diff --git a/python/src/sa/rulefactory.pxi b/python/src/sa/rulefactory.pxi
index b95c23df..88f77a8d 100644
--- a/python/src/sa/rulefactory.pxi
+++ b/python/src/sa/rulefactory.pxi
@@ -29,6 +29,7 @@ FeatureContext = namedtuple('FeatureContext',
 
 OnlineFeatureContext = namedtuple('OnlineFeatureContext',
     ['fcount',
+     'fsample_count',
      'paircount',
      'bilex'
     ])
@@ -272,6 +273,7 @@ cdef class HieroCachingRuleFactory:
     cdef IntList findexes1
 
     cdef bint online
+    cdef samples_f
     cdef phrases_f
     cdef phrases_e
     cdef phrases_fe
@@ -392,6 +394,9 @@ cdef class HieroCachingRuleFactory:
         # True after data is added
         self.online = False
         
+        # Keep track of everything that can be sampled:
+        self.samples_f = defaultdict(int)
+        
         # Phrase counts
         self.phrases_f = defaultdict(int)
         self.phrases_e = defaultdict(int)
@@ -1173,15 +1178,24 @@ cdef class HieroCachingRuleFactory:
         # Online rule extraction and scoring
         if self.online:
             f_syms = tuple(word[0][0] for word in fwords)
-            for (f, e, spanlen) in self.online_match(f_syms, seen_phrases):
-                scores = self.scorer.score(FeatureContext(
-                        f, e, 0, 0, 0,
-                        spanlen, None, None, 
-                        fwords, self.fda, self.eda,
-                        meta,
-                        self.online_ctx_lookup(f, e)))
-                alignment = self.phrases_al[f][e]
-                yield Rule(self.category, f, e, scores, alignment)
+            for (f, lex_i, lex_j) in self.get_f_phrases(f_syms):
+                spanlen = (lex_j - lex_i) + 1
+                if not sym_isvar(f[0]):
+                    spanlen += 1
+                if not sym_isvar(f[1]):
+                    spanlen += 1
+                for e in self.phrases_fe.get(f, ()):
+                    if (f, e) not in seen_phrases:
+                        # Don't add multiple instances of the same phrase here
+                        seen_phrases.add((f, e))
+                        scores = self.scorer.score(FeatureContext(
+                                f, e, 0, 0, 0,
+                                spanlen, None, None, 
+                                fwords, self.fda, self.eda,
+                                meta,
+                                self.online_ctx_lookup(f, e)))
+                        alignment = self.phrases_al[f][e]
+                        yield Rule(self.category, f, e, scores, alignment)
              
         stop_time = monitor_cpu()
         logger.info("Total time for rule lookup, extraction, and scoring = %f seconds", (stop_time - start_time))
@@ -2006,6 +2020,12 @@ cdef class HieroCachingRuleFactory:
                 continue
             extract(f_i, f_i, f_len + 1, -1, f_i, 0, [], [], False)
         
+        # Update possible phrases (samples)
+        # This could be more efficiently integrated with extraction
+        # at the cost of readability
+        for (f, lex_i, lex_j) in self.get_f_phrases(f_words):
+            self.samples_f[f] += 1
+            
         # Update phrase counts
         for rule in rules:
             (f_ph, e_ph, al) = rule[:3]
@@ -2115,30 +2135,33 @@ cdef class HieroCachingRuleFactory:
         for ph in self.phrases_e:
             logger.info(str(ph) + ' ||| ' + str(self.phrases_e[ph]))
         logger.info('FE')
+        self.dump_online_rules()
+
+    def dump_online_rules(self):
         for ph in self.phrases_fe:
             for ph2 in self.phrases_fe[ph]:
                 logger.info(self.fmt_rule(str(ph), str(ph2), self.phrases_al[ph][ph2]) + ' ||| ' + str(self.phrases_fe[ph][ph2]))
-    
+                    
     # Lookup online stats for phrase pair (f, e).  Return None if no match.
     # IMPORTANT: use get() to avoid adding items to defaultdict
     def online_ctx_lookup(self, f, e):
         if self.online:
             fcount = self.phrases_f.get(f, 0)
+            fsample_count = self.samples_f.get(f, 0)
             d = self.phrases_fe.get(f, None)
             paircount = d.get(e, 0) if d else 0
-            if paircount > 0:
-                print 'Online support:', f, '|||', e
-            return OnlineFeatureContext(fcount, paircount, self.bilex_fe)
+            return OnlineFeatureContext(fcount, fsample_count, paircount, self.bilex_fe)
         return None
     
-    # Match source words against online data.
-    # Return (fphrase, ephrase, length)
-    def online_match(self, f_words, seen_phrases):
-        
+    # Find all phrases that we might try to extract
+    # (Used for EGivenFCoherent)
+    # Return set of (fphrase, lex_i, lex_j)
+    def get_f_phrases(self, f_words):
+
         f_len = len(f_words)
-        matches = {} # (f, e) = len
+        phrases = set() # (fphrase, lex_i, lex_j)
         
-        def extract(f_i, f_j, wc, ntc, syms):
+        def extract(f_i, f_j, lex_i, lex_j, wc, ntc, syms):
             # Phrase extraction limits
             if f_j > (f_len - 1) or (f_j - f_i) + 1 > self.max_initial_size:
                 return
@@ -2146,34 +2169,30 @@ cdef class HieroCachingRuleFactory:
             if wc + ntc < self.max_length:
                 syms.append(f_words[f_j])
                 f = Phrase(syms)
-                for e in self.phrases_fe[f]:
-                    if (f, e) not in seen_phrases:
-                        matches[(f, e)] = (f_j - f_i) + 1 
-                extract(f_i, f_j + 1, wc + 1, ntc, syms)
+                new_lex_i = min(lex_i, f_j)
+                new_lex_j = max(lex_j, f_j)
+                phrases.add((f, new_lex_i, new_lex_j))
+                extract(f_i, f_j + 1, new_lex_i, new_lex_j, wc + 1, ntc, syms)
                 syms.pop()
             # Extend with existing non-terminal
             if syms and sym_isvar(syms[-1]):
                 # Don't re-extract the same phrase
-                extract(f_i, f_j + 1, wc, ntc, syms)
+                extract(f_i, f_j + 1, lex_i, lex_j, wc, ntc, syms)
             # Extend with new non-terminal
             if wc + ntc < self.max_length:
                 if not syms or (ntc < self.max_nonterminals and not sym_isvar(syms[-1])):
-                    syms.append(sym_setindex(self.category, ntc))
+                    syms.append(sym_setindex(self.category, ntc + 1))
                     f = Phrase(syms)
                     if wc > 0:
-                        for e in self.phrases_fe[f]:
-                            if (f, e) not in seen_phrases:
-                                matches[(f, e)] = (f_j - f_i) + 1
-                    extract(f_i, f_j + 1, wc, ntc + 1, syms)
+                        phrases.add((f, lex_i, lex_j))
+                    extract(f_i, f_j + 1, lex_i, lex_j, wc, ntc + 1, syms)
                     syms.pop()
             
         # Try to extract phrases from every f index
         for f_i from 0 <= f_i < f_len:
-            extract(f_i, f_i, 0, 0, [])
-        
-        for line in sorted(' ||| '.join((str(f), str(e))) for (f, e) in matches):
-            print 'Online new:', line
-        return ((f, e, matches[(f, e)]) for (f, e) in matches)
+            extract(f_i, f_i, f_len, -1, 0, 0, [])
+
+        return phrases
     
 # Spans are _inclusive_ on both ends [i, j]
 def span_check(vec, i, j):
-- 
cgit v1.2.3


From 2dd5feffac709c2628a593d76eaff590f22f226c Mon Sep 17 00:00:00 2001
From: Michael Denkowski <michael.j.denkowski@gmail.com>
Date: Mon, 28 Jan 2013 14:21:22 -0500
Subject: Bilexical scores for online rules

---
 python/pkg/cdec/sa/__init__.py  |    2 +-
 python/pkg/cdec/sa/extractor.py |    5 +-
 python/pkg/cdec/sa/features.py  |   44 +-
 python/src/sa/_sa.c             | 8559 ++++++++++++++++++++-------------------
 python/src/sa/rulefactory.pxi   |    6 +-
 python/src/sa/sym.pxi           |    3 +
 6 files changed, 4382 insertions(+), 4237 deletions(-)

(limited to 'python/pkg/cdec')

diff --git a/python/pkg/cdec/sa/__init__.py b/python/pkg/cdec/sa/__init__.py
index 418531d9..14ba5ecb 100644
--- a/python/pkg/cdec/sa/__init__.py
+++ b/python/pkg/cdec/sa/__init__.py
@@ -1,5 +1,5 @@
 from cdec.sa._sa import make_lattice, decode_lattice, decode_sentence,\
-        encode_words, decode_words,\
+        encode_words, decode_words, isvar,\
         SuffixArray, DataArray, LCP, Precomputation, Alignment, BiLex,\
         HieroCachingRuleFactory, Sampler, Scorer
 from cdec.sa.extractor import GrammarExtractor
diff --git a/python/pkg/cdec/sa/extractor.py b/python/pkg/cdec/sa/extractor.py
index bb552c49..cd3ab899 100644
--- a/python/pkg/cdec/sa/extractor.py
+++ b/python/pkg/cdec/sa/extractor.py
@@ -61,13 +61,14 @@ class GrammarExtractor:
         # TODO: clean this up
         extended_features = []
         extended_features.append(IsSupportedOnline)
-        #if online:
-        #    extended_features.append(IsSupportedOnline)
+        if online:
+            extended_features.append(IsSupportedOnline)
             
         # TODO: use @cdec.sa.features decorator for standard features too
         # + add a mask to disable features
         for f in cdec.sa._SA_FEATURES:
             extended_features.append(f)
+            
         scorer = cdec.sa.Scorer(EgivenFCoherent, SampleCountF, CountEF, 
             MaxLexFgivenE(tt), MaxLexEgivenF(tt), IsSingletonF, IsSingletonFE,
             *extended_features)
diff --git a/python/pkg/cdec/sa/features.py b/python/pkg/cdec/sa/features.py
index 49064f73..a89499d4 100644
--- a/python/pkg/cdec/sa/features.py
+++ b/python/pkg/cdec/sa/features.py
@@ -1,6 +1,8 @@
 from __future__ import division
 import math
 
+from cdec.sa import isvar
+
 MAXSCORE = 99
 
 def EgivenF(ctx): # p(e|f) = c(e, f)/c(f)
@@ -42,22 +44,48 @@ def MaxLexEgivenF(ttable):
     def MaxLexEgivenF(ctx):
         fwords = ctx.fphrase.words
         fwords.append('NULL')
-        def score():
+        if not ctx.online:
+            maxOffScore = 0.0
+            for e in ctx.ephrase.words:
+                maxScore = max(ttable.get_score(f, e, 0) for f in fwords)
+                maxOffScore += -math.log10(maxScore) if maxScore > 0 else MAXSCORE
+            return maxOffScore
+        else:
+            # For now, straight average
+            maxOffScore = 0.0
+            maxOnScore = 0.0
             for e in ctx.ephrase.words:
-              maxScore = max(ttable.get_score(f, e, 0) for f in fwords)
-              yield -math.log10(maxScore) if maxScore > 0 else MAXSCORE
-        return sum(score())
+                maxScore = max(ttable.get_score(f, e, 0) for f in fwords)
+                maxOffScore += -math.log10(maxScore) if maxScore > 0 else MAXSCORE
+            for e in ctx.ephrase:
+                if not isvar(e):
+                    maxScore = max((ctx.online.bilex_fe[f][e] / ctx.online.bilex_f[f]) for f in ctx.fphrase if not isvar(f))
+                    maxOnScore += -math.log10(maxScore) if maxScore > 0 else MAXSCORE
+            return (maxOffScore + maxOnScore) / 2
     return MaxLexEgivenF
 
 def MaxLexFgivenE(ttable):
     def MaxLexFgivenE(ctx):
         ewords = ctx.ephrase.words
         ewords.append('NULL')
-        def score():
+        if not ctx.online:
+            maxOffScore = 0.0
+            for f in ctx.fphrase.words:
+                maxScore = max(ttable.get_score(f, e, 1) for e in ewords)
+                maxOffScore += -math.log10(maxScore) if maxScore > 0 else MAXSCORE
+            return maxOffScore
+        else:
+            # For now, straight average
+            maxOffScore = 0.0
+            maxOnScore = 0.0
             for f in ctx.fphrase.words:
-              maxScore = max(ttable.get_score(f, e, 1) for e in ewords)
-              yield -math.log10(maxScore) if maxScore > 0 else MAXSCORE
-        return sum(score())
+                maxScore = max(ttable.get_score(f, e, 1) for e in ewords)
+                maxOffScore += -math.log10(maxScore) if maxScore > 0 else MAXSCORE
+            for f in ctx.fphrase:
+                if not isvar(f):
+                    maxScore = max((ctx.online.bilex_fe[f][e] / ctx.online.bilex_e[e]) for e in ctx.ephrase if not isvar(e))
+                    maxOnScore += -math.log10(maxScore) if maxScore > 0 else MAXSCORE
+            return (maxOffScore + maxOnScore) / 2
     return MaxLexFgivenE
 
 def IsSingletonF(ctx):
diff --git a/python/src/sa/_sa.c b/python/src/sa/_sa.c
index 5910a81f..7d73b3b7 100644
--- a/python/src/sa/_sa.c
+++ b/python/src/sa/_sa.c
@@ -1,4 +1,4 @@
-/* Generated by Cython 0.17.1 on Sat Jan 26 21:11:32 2013 */
+/* Generated by Cython 0.17.1 on Mon Jan 28 11:56:59 2013 */
 
 #define PY_SSIZE_T_CLEAN
 #include "Python.h"
@@ -492,7 +492,7 @@ struct __pyx_t_3_sa__Trie_Node {
   int arr_len;
 };
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":74
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":76
  * 
  * # linked list structure for storing matches in BaselineRuleFactory
  * cdef struct match_node:             # <<<<<<<<<<<<<<
@@ -504,7 +504,7 @@ struct __pyx_t_3_sa_match_node {
   struct __pyx_t_3_sa_match_node *next;
 };
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":170
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":172
  * 
  * # struct used to encapsulate a single matching
  * cdef struct Matching:             # <<<<<<<<<<<<<<
@@ -519,7 +519,7 @@ struct __pyx_t_3_sa_Matching {
   int size;
 };
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":226
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":228
  * 
  * 
  * cdef class HieroCachingRuleFactory:             # <<<<<<<<<<<<<<
@@ -577,7 +577,7 @@ struct __pyx_obj_3_sa_HieroCachingRuleFactory {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":115
+/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":118
  *             for arc in node for node in lattice)
  * 
  * def decode_sentence(lattice):             # <<<<<<<<<<<<<<
@@ -607,7 +607,7 @@ struct __pyx_obj_3_sa___pyx_scope_struct_17_genexpr {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1180
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1182
  *         # Online rule extraction and scoring
  *         if self.online:
  *             f_syms = tuple(word[0][0] for word in fwords)             # <<<<<<<<<<<<<<
@@ -655,7 +655,7 @@ struct __pyx_obj_3_sa___pyx_scope_struct_3_compute_stats {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":119
+/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":122
  * 
  * def encode_words(words):
  *     return tuple(sym_fromstring(word, True) for word in words)             # <<<<<<<<<<<<<<
@@ -755,7 +755,7 @@ struct __pyx_obj_3_sa_VEB {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":118
+/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":121
  *     return tuple(sym_tostring(sym) for ((sym, _, _),) in lattice)
  * 
  * def encode_words(words):             # <<<<<<<<<<<<<<
@@ -815,7 +815,7 @@ struct __pyx_obj_3_sa_BitSetIterator {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2108
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2110
  *         f = Phrase(f_sym)
  *         e = Phrase(e_sym)
  *         a = tuple(self.alignment.link(i, j) for (i, j) in links)             # <<<<<<<<<<<<<<
@@ -871,7 +871,7 @@ struct __pyx_obj_3_sa___pyx_scope_struct_18_alignments {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":122
+/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":125
  * 
  * def decode_words(syms):
  *     return tuple(sym_tostring(sym) for sym in syms)             # <<<<<<<<<<<<<<
@@ -951,7 +951,7 @@ struct __pyx_obj_3_sa_Rule {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":109
+/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":112
  * def make_lattice(words):
  *     word_ids = (sym_fromstring(word, True) for word in words)
  *     return tuple(((word, None, 1), ) for word in word_ids)             # <<<<<<<<<<<<<<
@@ -968,7 +968,7 @@ struct __pyx_obj_3_sa___pyx_scope_struct_6_genexpr {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1877
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1879
  *     # Aggregate stats from a training instance
  *     # (Extract rules, update counts)
  *     def add_instance(self, f_words, e_words, alignment):             # <<<<<<<<<<<<<<
@@ -1008,7 +1008,7 @@ struct __pyx_obj_3_sa___pyx_scope_struct_2_genexpr {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":82
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":84
  * # in the suffix array; if discontiguous, it is the set of
  * # actual locations (packed into an array)
  * cdef class PhraseLocation:             # <<<<<<<<<<<<<<
@@ -1042,7 +1042,7 @@ struct __pyx_obj_3_sa___pyx_scope_struct_15___iter__ {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2047
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2049
  * 
  *     # Create a rule from source, target, non-terminals, and alignments
  *     def form_rule(self, f_i, e_i, f_span, e_span, nt, al):             # <<<<<<<<<<<<<<
@@ -1056,7 +1056,7 @@ struct __pyx_obj_3_sa___pyx_scope_struct_22_form_rule {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2113
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2115
  *     # Rule string from rule
  *     def fmt_rule(self, f, e, a):
  *         a_str = ' '.join('{0}-{1}'.format(*self.alignment.unlink(packed)) for packed in a)             # <<<<<<<<<<<<<<
@@ -1073,7 +1073,7 @@ struct __pyx_obj_3_sa___pyx_scope_struct_25_genexpr {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2112
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2114
  * 
  *     # Rule string from rule
  *     def fmt_rule(self, f, e, a):             # <<<<<<<<<<<<<<
@@ -1114,7 +1114,7 @@ struct __pyx_obj_3_sa___pyx_scope_struct_1_read_bitext {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":121
+/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":124
  *     return tuple(sym_fromstring(word, True) for word in words)
  * 
  * def decode_words(syms):             # <<<<<<<<<<<<<<
@@ -1140,7 +1140,7 @@ struct __pyx_obj_3_sa_FeatureVector {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":111
+/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":114
  *     return tuple(((word, None, 1), ) for word in word_ids)
  * 
  * def decode_lattice(lattice):             # <<<<<<<<<<<<<<
@@ -1153,7 +1153,7 @@ struct __pyx_obj_3_sa___pyx_scope_struct_7_decode_lattice {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":970
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":972
  *         return sorted(result);
  * 
  *     def input(self, fwords, meta):             # <<<<<<<<<<<<<<
@@ -1288,7 +1288,7 @@ struct __pyx_obj_3_sa_BitSet {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":104
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":106
  * 
  * 
  * cdef class Sampler:             # <<<<<<<<<<<<<<
@@ -1316,7 +1316,7 @@ struct __pyx_obj_3_sa_StringMap {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2159
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2161
  *     # (Used for EGivenFCoherent)
  *     # Return set of (fphrase, lex_i, lex_j)
  *     def get_f_phrases(self, f_words):             # <<<<<<<<<<<<<<
@@ -1333,7 +1333,7 @@ struct __pyx_obj_3_sa___pyx_scope_struct_26_get_f_phrases {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":44
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":46
  * cdef int EPSILON = sym_fromstring('*EPS*', True)
  * 
  * cdef class TrieNode:             # <<<<<<<<<<<<<<
@@ -1346,7 +1346,7 @@ struct __pyx_obj_3_sa_TrieNode {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":50
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":52
  *         self.children = {}
  * 
  * cdef class ExtendedTrieNode(TrieNode):             # <<<<<<<<<<<<<<
@@ -1376,7 +1376,7 @@ struct __pyx_obj_3_sa_TrieMap {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":112
+/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":115
  * 
  * def decode_lattice(lattice):
  *     return tuple((sym_tostring(sym), weight, dist) for (sym, weight, dist) in arc             # <<<<<<<<<<<<<<
@@ -1403,8 +1403,8 @@ struct __pyx_obj_3_sa___pyx_scope_struct_8_genexpr {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":107
- *     return ALPHABET.fromstring(string, terminal)
+/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":110
+ *     return sym_isvar(sym)
  * 
  * def make_lattice(words):             # <<<<<<<<<<<<<<
  *     word_ids = (sym_fromstring(word, True) for word in words)
@@ -1466,7 +1466,7 @@ struct __pyx_obj_3_sa___pyx_scope_struct____iter__ {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":61
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":63
  * 
  * 
  * cdef class TrieTable:             # <<<<<<<<<<<<<<
@@ -1481,7 +1481,7 @@ struct __pyx_obj_3_sa_TrieTable {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":108
+/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":111
  * 
  * def make_lattice(words):
  *     word_ids = (sym_fromstring(word, True) for word in words)             # <<<<<<<<<<<<<<
@@ -1498,7 +1498,7 @@ struct __pyx_obj_3_sa___pyx_scope_struct_5_genexpr {
 };
 
 
-/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":116
+/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":119
  * 
  * def decode_sentence(lattice):
  *     return tuple(sym_tostring(sym) for ((sym, _, _),) in lattice)             # <<<<<<<<<<<<<<
@@ -1649,7 +1649,7 @@ struct __pyx_vtabstruct_3_sa_Phrase {
 static struct __pyx_vtabstruct_3_sa_Phrase *__pyx_vtabptr_3_sa_Phrase;
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":82
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":84
  * # in the suffix array; if discontiguous, it is the set of
  * # actual locations (packed into an array)
  * cdef class PhraseLocation:             # <<<<<<<<<<<<<<
@@ -1747,7 +1747,7 @@ struct __pyx_vtabstruct_3_sa_Alphabet {
 static struct __pyx_vtabstruct_3_sa_Alphabet *__pyx_vtabptr_3_sa_Alphabet;
 
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":226
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":228
  * 
  * 
  * cdef class HieroCachingRuleFactory:             # <<<<<<<<<<<<<<
@@ -2596,17 +2596,18 @@ static int __pyx_pf_3_sa_8Alphabet___cinit__(struct __pyx_obj_3_sa_Alphabet *__p
 static void __pyx_pf_3_sa_8Alphabet_2__dealloc__(CYTHON_UNUSED struct __pyx_obj_3_sa_Alphabet *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_3_sa_8Alphabet_9terminals___get__(struct __pyx_obj_3_sa_Alphabet *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_3_sa_8Alphabet_12nonterminals___get__(struct __pyx_obj_3_sa_Alphabet *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_3_sa_2isvar(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_sym); /* proto */
 static PyObject *__pyx_pf_3_sa_12make_lattice_genexpr(PyObject *__pyx_self); /* proto */
 static PyObject *__pyx_pf_3_sa_12make_lattice_3genexpr(PyObject *__pyx_self); /* proto */
-static PyObject *__pyx_pf_3_sa_2make_lattice(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_words); /* proto */
+static PyObject *__pyx_pf_3_sa_4make_lattice(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_words); /* proto */
 static PyObject *__pyx_pf_3_sa_14decode_lattice_genexpr(PyObject *__pyx_self); /* proto */
-static PyObject *__pyx_pf_3_sa_4decode_lattice(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_lattice); /* proto */
+static PyObject *__pyx_pf_3_sa_6decode_lattice(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_lattice); /* proto */
 static PyObject *__pyx_pf_3_sa_15decode_sentence_genexpr(PyObject *__pyx_self); /* proto */
-static PyObject *__pyx_pf_3_sa_6decode_sentence(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_lattice); /* proto */
+static PyObject *__pyx_pf_3_sa_8decode_sentence(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_lattice); /* proto */
 static PyObject *__pyx_pf_3_sa_12encode_words_genexpr(PyObject *__pyx_self); /* proto */
-static PyObject *__pyx_pf_3_sa_8encode_words(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_words); /* proto */
+static PyObject *__pyx_pf_3_sa_10encode_words(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_words); /* proto */
 static PyObject *__pyx_pf_3_sa_12decode_words_genexpr(PyObject *__pyx_self); /* proto */
-static PyObject *__pyx_pf_3_sa_10decode_words(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_syms); /* proto */
+static PyObject *__pyx_pf_3_sa_12decode_words(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_syms); /* proto */
 static int __pyx_pf_3_sa_6Phrase___cinit__(struct __pyx_obj_3_sa_Phrase *__pyx_v_self, PyObject *__pyx_v_words); /* proto */
 static void __pyx_pf_3_sa_6Phrase_2__dealloc__(struct __pyx_obj_3_sa_Phrase *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_3_sa_6Phrase_4__str__(struct __pyx_obj_3_sa_Phrase *__pyx_v_self); /* proto */
@@ -2713,9 +2714,9 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_33dump_online_rules(str
 static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_35online_ctx_lookup(struct __pyx_obj_3_sa_HieroCachingRuleFactory *__pyx_v_self, PyObject *__pyx_v_f, PyObject *__pyx_v_e); /* proto */
 static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_13get_f_phrases_extract(PyObject *__pyx_self, PyObject *__pyx_v_f_i, PyObject *__pyx_v_f_j, PyObject *__pyx_v_lex_i, PyObject *__pyx_v_lex_j, PyObject *__pyx_v_wc, PyObject *__pyx_v_ntc, PyObject *__pyx_v_syms); /* proto */
 static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_37get_f_phrases(struct __pyx_obj_3_sa_HieroCachingRuleFactory *__pyx_v_self, PyObject *__pyx_v_f_words); /* proto */
-static PyObject *__pyx_pf_3_sa_12span_check(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_vec, PyObject *__pyx_v_i, PyObject *__pyx_v_j); /* proto */
-static PyObject *__pyx_pf_3_sa_14span_inc(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_vec, PyObject *__pyx_v_i, PyObject *__pyx_v_j); /* proto */
-static PyObject *__pyx_pf_3_sa_16span_dec(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_vec, PyObject *__pyx_v_i, PyObject *__pyx_v_j); /* proto */
+static PyObject *__pyx_pf_3_sa_14span_check(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_vec, PyObject *__pyx_v_i, PyObject *__pyx_v_j); /* proto */
+static PyObject *__pyx_pf_3_sa_16span_inc(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_vec, PyObject *__pyx_v_i, PyObject *__pyx_v_j); /* proto */
+static PyObject *__pyx_pf_3_sa_18span_dec(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_vec, PyObject *__pyx_v_i, PyObject *__pyx_v_j); /* proto */
 static int __pyx_pf_3_sa_13FeatureVector___cinit__(struct __pyx_obj_3_sa_FeatureVector *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_3_sa_13FeatureVector_2set(struct __pyx_obj_3_sa_FeatureVector *__pyx_v_self, unsigned int __pyx_v_name, float __pyx_v_value); /* proto */
 static PyObject *__pyx_pf_3_sa_13FeatureVector_4__iter__(struct __pyx_obj_3_sa_FeatureVector *__pyx_v_self); /* proto */
@@ -2831,7 +2832,7 @@ static char __pyx_k_154[] = "%s=%s";
 static char __pyx_k_157[] = "/home/m/workspace/cdec/python/src/sa/_sa.pyx";
 static char __pyx_k_158[] = "cdec.sa";
 static char __pyx_k_162[] = "/home/m/workspace/cdec/python/src/sa/sym.pxi";
-static char __pyx_k_171[] = "*EPS*";
+static char __pyx_k_173[] = "*EPS*";
 static char __pyx_k__FE[] = "FE";
 static char __pyx_k__al[] = "al";
 static char __pyx_k__fe[] = "fe";
@@ -2862,6 +2863,7 @@ static char __pyx_k__pad[] = "pad";
 static char __pyx_k__pop[] = "pop";
 static char __pyx_k__res[] = "res";
 static char __pyx_k__set[] = "set";
+static char __pyx_k__sym[] = "sym";
 static char __pyx_k__vec[] = "vec";
 static char __pyx_k__zip[] = "zip";
 static char __pyx_k__NULL[] = "NULL";
@@ -2884,13 +2886,13 @@ static char __pyx_k__warn[] = "warn";
 static char __pyx_k__word[] = "word";
 static char __pyx_k___SEP_[] = "_SEP_";
 static char __pyx_k__arity[] = "arity";
-static char __pyx_k__bilex[] = "bilex";
 static char __pyx_k__chain[] = "chain";
 static char __pyx_k__debug[] = "debug";
 static char __pyx_k__eword[] = "eword";
 static char __pyx_k__fword[] = "fword";
 static char __pyx_k__ifrom[] = "ifrom";
 static char __pyx_k__index[] = "index";
+static char __pyx_k__isvar[] = "isvar";
 static char __pyx_k__lex_i[] = "lex_i";
 static char __pyx_k__lex_j[] = "lex_j";
 static char __pyx_k__links[] = "links";
@@ -2934,6 +2936,8 @@ static char __pyx_k__unlink[] = "unlink";
 static char __pyx_k__Counter[] = "Counter";
 static char __pyx_k__advance[] = "advance";
 static char __pyx_k__arr_low[] = "arr_low";
+static char __pyx_k__bilex_e[] = "bilex_e";
+static char __pyx_k__bilex_f[] = "bilex_f";
 static char __pyx_k__collect[] = "collect";
 static char __pyx_k__e_words[] = "e_words";
 static char __pyx_k__edarray[] = "edarray";
@@ -2960,6 +2964,7 @@ static char __pyx_k____name__[] = "__name__";
 static char __pyx_k____test__[] = "__test__";
 static char __pyx_k___columns[] = "_columns";
 static char __pyx_k__arr_high[] = "arr_high";
+static char __pyx_k__bilex_fe[] = "bilex_fe";
 static char __pyx_k__category[] = "category";
 static char __pyx_k__children[] = "children";
 static char __pyx_k__curr_idx[] = "curr_idx";
@@ -3198,7 +3203,9 @@ static PyObject *__pyx_n_s__arity;
 static PyObject *__pyx_n_s__arr;
 static PyObject *__pyx_n_s__arr_high;
 static PyObject *__pyx_n_s__arr_low;
-static PyObject *__pyx_n_s__bilex;
+static PyObject *__pyx_n_s__bilex_e;
+static PyObject *__pyx_n_s__bilex_f;
+static PyObject *__pyx_n_s__bilex_fe;
 static PyObject *__pyx_n_s__by_slack_factor;
 static PyObject *__pyx_n_s__category;
 static PyObject *__pyx_n_s__chain;
@@ -3280,6 +3287,7 @@ static PyObject *__pyx_n_s__input_match;
 static PyObject *__pyx_n_s__input_span;
 static PyObject *__pyx_n_s__insert;
 static PyObject *__pyx_n_s__isa;
+static PyObject *__pyx_n_s__isvar;
 static PyObject *__pyx_n_s__iteritems;
 static PyObject *__pyx_n_s__itertools;
 static PyObject *__pyx_n_s__itervalues;
@@ -3386,6 +3394,7 @@ static PyObject *__pyx_n_s__start;
 static PyObject *__pyx_n_s__stats;
 static PyObject *__pyx_n_s__stop;
 static PyObject *__pyx_n_s__suffix_link;
+static PyObject *__pyx_n_s__sym;
 static PyObject *__pyx_n_s__syms;
 static PyObject *__pyx_n_s__test_sentence;
 static PyObject *__pyx_n_s__tight_phrases;
@@ -3488,9 +3497,10 @@ static PyObject *__pyx_k_tuple_163;
 static PyObject *__pyx_k_tuple_165;
 static PyObject *__pyx_k_tuple_167;
 static PyObject *__pyx_k_tuple_169;
-static PyObject *__pyx_k_tuple_172;
+static PyObject *__pyx_k_tuple_171;
 static PyObject *__pyx_k_tuple_174;
 static PyObject *__pyx_k_tuple_176;
+static PyObject *__pyx_k_tuple_178;
 static PyObject *__pyx_k_codeobj_135;
 static PyObject *__pyx_k_codeobj_153;
 static PyObject *__pyx_k_codeobj_156;
@@ -3499,9 +3509,10 @@ static PyObject *__pyx_k_codeobj_164;
 static PyObject *__pyx_k_codeobj_166;
 static PyObject *__pyx_k_codeobj_168;
 static PyObject *__pyx_k_codeobj_170;
-static PyObject *__pyx_k_codeobj_173;
+static PyObject *__pyx_k_codeobj_172;
 static PyObject *__pyx_k_codeobj_175;
 static PyObject *__pyx_k_codeobj_177;
+static PyObject *__pyx_k_codeobj_179;
 
 /* "_sa.pyx":5
  * import gzip
@@ -23710,7 +23721,7 @@ static int __pyx_f_3_sa_sym_fromstring(char *__pyx_v_string, int __pyx_v_termina
  * cdef int sym_fromstring(char* string, bint terminal):
  *     return ALPHABET.fromstring(string, terminal)             # <<<<<<<<<<<<<<
  * 
- * def make_lattice(words):
+ * def isvar(sym):
  */
   __pyx_r = ((struct __pyx_vtabstruct_3_sa_Alphabet *)__pyx_v_3_sa_ALPHABET->__pyx_vtab)->fromstring(__pyx_v_3_sa_ALPHABET, __pyx_v_string, __pyx_v_terminal);
   goto __pyx_L0;
@@ -23722,19 +23733,76 @@ static int __pyx_f_3_sa_sym_fromstring(char *__pyx_v_string, int __pyx_v_termina
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_3_sa_3make_lattice(PyObject *__pyx_self, PyObject *__pyx_v_words); /*proto*/
-static PyMethodDef __pyx_mdef_3_sa_3make_lattice = {__Pyx_NAMESTR("make_lattice"), (PyCFunction)__pyx_pw_3_sa_3make_lattice, METH_O, __Pyx_DOCSTR(0)};
-static PyObject *__pyx_pw_3_sa_3make_lattice(PyObject *__pyx_self, PyObject *__pyx_v_words) {
+static PyObject *__pyx_pw_3_sa_3isvar(PyObject *__pyx_self, PyObject *__pyx_v_sym); /*proto*/
+static PyMethodDef __pyx_mdef_3_sa_3isvar = {__Pyx_NAMESTR("isvar"), (PyCFunction)__pyx_pw_3_sa_3isvar, METH_O, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pw_3_sa_3isvar(PyObject *__pyx_self, PyObject *__pyx_v_sym) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("isvar (wrapper)", 0);
+  __pyx_r = __pyx_pf_3_sa_2isvar(__pyx_self, ((PyObject *)__pyx_v_sym));
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":107
+ *     return ALPHABET.fromstring(string, terminal)
+ * 
+ * def isvar(sym):             # <<<<<<<<<<<<<<
+ *     return sym_isvar(sym)
+ * 
+ */
+
+static PyObject *__pyx_pf_3_sa_2isvar(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_sym) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("isvar", 0);
+
+  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":108
+ * 
+ * def isvar(sym):
+ *     return sym_isvar(sym)             # <<<<<<<<<<<<<<
+ * 
+ * def make_lattice(words):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_sym); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyInt_FromLong(__pyx_f_3_sa_sym_isvar(__pyx_t_1)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("_sa.isvar", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_3_sa_5make_lattice(PyObject *__pyx_self, PyObject *__pyx_v_words); /*proto*/
+static PyMethodDef __pyx_mdef_3_sa_5make_lattice = {__Pyx_NAMESTR("make_lattice"), (PyCFunction)__pyx_pw_3_sa_5make_lattice, METH_O, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pw_3_sa_5make_lattice(PyObject *__pyx_self, PyObject *__pyx_v_words) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("make_lattice (wrapper)", 0);
-  __pyx_r = __pyx_pf_3_sa_2make_lattice(__pyx_self, ((PyObject *)__pyx_v_words));
+  __pyx_r = __pyx_pf_3_sa_4make_lattice(__pyx_self, ((PyObject *)__pyx_v_words));
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 static PyObject *__pyx_gb_3_sa_12make_lattice_2generator7(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value); /* proto */
 
-/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":108
+/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":111
  * 
  * def make_lattice(words):
  *     word_ids = (sym_fromstring(word, True) for word in words)             # <<<<<<<<<<<<<<
@@ -23760,7 +23828,7 @@ static PyObject *__pyx_pf_3_sa_12make_lattice_genexpr(PyObject *__pyx_self) {
   __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_outer_scope));
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_outer_scope);
   {
-    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_12make_lattice_2generator7, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_12make_lattice_2generator7, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_cur_scope);
     __Pyx_RefNannyFinishContext();
     return (PyObject *) gen;
@@ -23797,13 +23865,13 @@ static PyObject *__pyx_gb_3_sa_12make_lattice_2generator7(__pyx_GeneratorObject
     return NULL;
   }
   __pyx_L3_first_run:;
-  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_words)) { __Pyx_RaiseClosureNameError("words"); {__pyx_filename = __pyx_f[10]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_words)) { __Pyx_RaiseClosureNameError("words"); {__pyx_filename = __pyx_f[10]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
   if (PyList_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_words) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_words)) {
     __pyx_t_1 = __pyx_cur_scope->__pyx_outer_scope->__pyx_v_words; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
     __pyx_t_3 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_words); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_words); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -23811,23 +23879,23 @@ static PyObject *__pyx_gb_3_sa_12make_lattice_2generator7(__pyx_GeneratorObject
     if (!__pyx_t_3 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[10]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[10]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_3 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[10]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[10]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_4 = __pyx_t_3(__pyx_t_1);
       if (unlikely(!__pyx_t_4)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[10]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[10]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -23838,8 +23906,8 @@ static PyObject *__pyx_gb_3_sa_12make_lattice_2generator7(__pyx_GeneratorObject
     __Pyx_GIVEREF(__pyx_t_4);
     __pyx_cur_scope->__pyx_v_word = __pyx_t_4;
     __pyx_t_4 = 0;
-    __pyx_t_5 = PyBytes_AsString(__pyx_cur_scope->__pyx_v_word); if (unlikely((!__pyx_t_5) && PyErr_Occurred())) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_4 = PyInt_FromLong(__pyx_f_3_sa_sym_fromstring(__pyx_t_5, 1)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyBytes_AsString(__pyx_cur_scope->__pyx_v_word); if (unlikely((!__pyx_t_5) && PyErr_Occurred())) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyInt_FromLong(__pyx_f_3_sa_sym_fromstring(__pyx_t_5, 1)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __pyx_r = __pyx_t_4;
     __pyx_t_4 = 0;
@@ -23858,7 +23926,7 @@ static PyObject *__pyx_gb_3_sa_12make_lattice_2generator7(__pyx_GeneratorObject
     __Pyx_XGOTREF(__pyx_t_1);
     __pyx_t_2 = __pyx_cur_scope->__pyx_t_1;
     __pyx_t_3 = __pyx_cur_scope->__pyx_t_2;
-    if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyErr_SetNone(PyExc_StopIteration);
@@ -23876,7 +23944,7 @@ static PyObject *__pyx_gb_3_sa_12make_lattice_2generator7(__pyx_GeneratorObject
 }
 static PyObject *__pyx_gb_3_sa_12make_lattice_5generator8(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value); /* proto */
 
-/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":109
+/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":112
  * def make_lattice(words):
  *     word_ids = (sym_fromstring(word, True) for word in words)
  *     return tuple(((word, None, 1), ) for word in word_ids)             # <<<<<<<<<<<<<<
@@ -23902,7 +23970,7 @@ static PyObject *__pyx_pf_3_sa_12make_lattice_3genexpr(PyObject *__pyx_self) {
   __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_outer_scope));
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_outer_scope);
   {
-    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_12make_lattice_5generator8, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_12make_lattice_5generator8, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_cur_scope);
     __Pyx_RefNannyFinishContext();
     return (PyObject *) gen;
@@ -23939,13 +24007,13 @@ static PyObject *__pyx_gb_3_sa_12make_lattice_5generator8(__pyx_GeneratorObject
     return NULL;
   }
   __pyx_L3_first_run:;
-  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_word_ids)) { __Pyx_RaiseClosureNameError("word_ids"); {__pyx_filename = __pyx_f[10]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_word_ids)) { __Pyx_RaiseClosureNameError("word_ids"); {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
   if (PyList_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_word_ids) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_word_ids)) {
     __pyx_t_1 = __pyx_cur_scope->__pyx_outer_scope->__pyx_v_word_ids; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
     __pyx_t_3 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_word_ids); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_word_ids); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -23953,23 +24021,23 @@ static PyObject *__pyx_gb_3_sa_12make_lattice_5generator8(__pyx_GeneratorObject
     if (!__pyx_t_3 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[10]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_3 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[10]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_4 = __pyx_t_3(__pyx_t_1);
       if (unlikely(!__pyx_t_4)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[10]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -23980,7 +24048,7 @@ static PyObject *__pyx_gb_3_sa_12make_lattice_5generator8(__pyx_GeneratorObject
     __Pyx_GIVEREF(__pyx_t_4);
     __pyx_cur_scope->__pyx_v_word = __pyx_t_4;
     __pyx_t_4 = 0;
-    __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_INCREF(__pyx_cur_scope->__pyx_v_word);
     PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_cur_scope->__pyx_v_word);
@@ -23991,7 +24059,7 @@ static PyObject *__pyx_gb_3_sa_12make_lattice_5generator8(__pyx_GeneratorObject
     __Pyx_INCREF(__pyx_int_1);
     PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_int_1);
     __Pyx_GIVEREF(__pyx_int_1);
-    __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)__pyx_t_4));
     __Pyx_GIVEREF(((PyObject *)__pyx_t_4));
@@ -24013,7 +24081,7 @@ static PyObject *__pyx_gb_3_sa_12make_lattice_5generator8(__pyx_GeneratorObject
     __Pyx_XGOTREF(__pyx_t_1);
     __pyx_t_2 = __pyx_cur_scope->__pyx_t_1;
     __pyx_t_3 = __pyx_cur_scope->__pyx_t_2;
-    if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyErr_SetNone(PyExc_StopIteration);
@@ -24031,15 +24099,15 @@ static PyObject *__pyx_gb_3_sa_12make_lattice_5generator8(__pyx_GeneratorObject
   return NULL;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":107
- *     return ALPHABET.fromstring(string, terminal)
+/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":110
+ *     return sym_isvar(sym)
  * 
  * def make_lattice(words):             # <<<<<<<<<<<<<<
  *     word_ids = (sym_fromstring(word, True) for word in words)
  *     return tuple(((word, None, 1), ) for word in word_ids)
  */
 
-static PyObject *__pyx_pf_3_sa_2make_lattice(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_words) {
+static PyObject *__pyx_pf_3_sa_4make_lattice(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_words) {
   struct __pyx_obj_3_sa___pyx_scope_struct_4_make_lattice *__pyx_cur_scope;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
@@ -24059,20 +24127,20 @@ static PyObject *__pyx_pf_3_sa_2make_lattice(CYTHON_UNUSED PyObject *__pyx_self,
   __Pyx_INCREF(__pyx_cur_scope->__pyx_v_words);
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_words);
 
-  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":108
+  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":111
  * 
  * def make_lattice(words):
  *     word_ids = (sym_fromstring(word, True) for word in words)             # <<<<<<<<<<<<<<
  *     return tuple(((word, None, 1), ) for word in word_ids)
  * 
  */
-  __pyx_t_1 = __pyx_pf_3_sa_12make_lattice_genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __pyx_pf_3_sa_12make_lattice_genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_1);
   __pyx_cur_scope->__pyx_v_word_ids = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":109
+  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":112
  * def make_lattice(words):
  *     word_ids = (sym_fromstring(word, True) for word in words)
  *     return tuple(((word, None, 1), ) for word in word_ids)             # <<<<<<<<<<<<<<
@@ -24080,14 +24148,14 @@ static PyObject *__pyx_pf_3_sa_2make_lattice(CYTHON_UNUSED PyObject *__pyx_self,
  * def decode_lattice(lattice):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_pf_3_sa_12make_lattice_3genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __pyx_pf_3_sa_12make_lattice_3genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_1);
   __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
   __pyx_r = __pyx_t_1;
@@ -24109,19 +24177,19 @@ static PyObject *__pyx_pf_3_sa_2make_lattice(CYTHON_UNUSED PyObject *__pyx_self,
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_3_sa_5decode_lattice(PyObject *__pyx_self, PyObject *__pyx_v_lattice); /*proto*/
-static PyMethodDef __pyx_mdef_3_sa_5decode_lattice = {__Pyx_NAMESTR("decode_lattice"), (PyCFunction)__pyx_pw_3_sa_5decode_lattice, METH_O, __Pyx_DOCSTR(0)};
-static PyObject *__pyx_pw_3_sa_5decode_lattice(PyObject *__pyx_self, PyObject *__pyx_v_lattice) {
+static PyObject *__pyx_pw_3_sa_7decode_lattice(PyObject *__pyx_self, PyObject *__pyx_v_lattice); /*proto*/
+static PyMethodDef __pyx_mdef_3_sa_7decode_lattice = {__Pyx_NAMESTR("decode_lattice"), (PyCFunction)__pyx_pw_3_sa_7decode_lattice, METH_O, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pw_3_sa_7decode_lattice(PyObject *__pyx_self, PyObject *__pyx_v_lattice) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("decode_lattice (wrapper)", 0);
-  __pyx_r = __pyx_pf_3_sa_4decode_lattice(__pyx_self, ((PyObject *)__pyx_v_lattice));
+  __pyx_r = __pyx_pf_3_sa_6decode_lattice(__pyx_self, ((PyObject *)__pyx_v_lattice));
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 static PyObject *__pyx_gb_3_sa_14decode_lattice_2generator9(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value); /* proto */
 
-/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":112
+/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":115
  * 
  * def decode_lattice(lattice):
  *     return tuple((sym_tostring(sym), weight, dist) for (sym, weight, dist) in arc             # <<<<<<<<<<<<<<
@@ -24147,7 +24215,7 @@ static PyObject *__pyx_pf_3_sa_14decode_lattice_genexpr(PyObject *__pyx_self) {
   __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_outer_scope));
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_outer_scope);
   {
-    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_14decode_lattice_2generator9, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_14decode_lattice_2generator9, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_cur_scope);
     __Pyx_RefNannyFinishContext();
     return (PyObject *) gen;
@@ -24193,27 +24261,27 @@ static PyObject *__pyx_gb_3_sa_14decode_lattice_2generator9(__pyx_GeneratorObjec
     return NULL;
   }
   __pyx_L3_first_run:;
-  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":113
+  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":116
  * def decode_lattice(lattice):
  *     return tuple((sym_tostring(sym), weight, dist) for (sym, weight, dist) in arc
  *             for arc in node for node in lattice)             # <<<<<<<<<<<<<<
  * 
  * def decode_sentence(lattice):
  */
-  if (unlikely(!__pyx_cur_scope->__pyx_v_arc)) { __Pyx_RaiseUnboundLocalError("arc"); {__pyx_filename = __pyx_f[10]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+  if (unlikely(!__pyx_cur_scope->__pyx_v_arc)) { __Pyx_RaiseUnboundLocalError("arc"); {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
   if (PyList_CheckExact(__pyx_cur_scope->__pyx_v_arc) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_v_arc)) {
     __pyx_t_1 = __pyx_cur_scope->__pyx_v_arc; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
     __pyx_t_3 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_arc); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_arc); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
   for (;;) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":112
+    /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":115
  * 
  * def decode_lattice(lattice):
  *     return tuple((sym_tostring(sym), weight, dist) for (sym, weight, dist) in arc             # <<<<<<<<<<<<<<
@@ -24223,23 +24291,23 @@ static PyObject *__pyx_gb_3_sa_14decode_lattice_2generator9(__pyx_GeneratorObjec
     if (!__pyx_t_3 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_3 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_4 = __pyx_t_3(__pyx_t_1);
       if (unlikely(!__pyx_t_4)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -24255,7 +24323,7 @@ static PyObject *__pyx_gb_3_sa_14decode_lattice_2generator9(__pyx_GeneratorObjec
       if (unlikely(size != 3)) {
         if (size > 3) __Pyx_RaiseTooManyValuesError(3);
         else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-        {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        {__pyx_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       }
       #if CYTHON_COMPILING_IN_CPYTHON
       if (likely(PyTuple_CheckExact(sequence))) {
@@ -24271,15 +24339,15 @@ static PyObject *__pyx_gb_3_sa_14decode_lattice_2generator9(__pyx_GeneratorObjec
       __Pyx_INCREF(__pyx_t_6);
       __Pyx_INCREF(__pyx_t_7);
       #else
-      __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_7 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     } else
     {
       Py_ssize_t index = -1;
-      __pyx_t_8 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __pyx_t_9 = Py_TYPE(__pyx_t_8)->tp_iternext;
@@ -24289,7 +24357,7 @@ static PyObject *__pyx_gb_3_sa_14decode_lattice_2generator9(__pyx_GeneratorObjec
       __Pyx_GOTREF(__pyx_t_6);
       index = 2; __pyx_t_7 = __pyx_t_9(__pyx_t_8); if (unlikely(!__pyx_t_7)) goto __pyx_L6_unpacking_failed;
       __Pyx_GOTREF(__pyx_t_7);
-      if (__Pyx_IternextUnpackEndCheck(__pyx_t_9(__pyx_t_8), 3) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_9(__pyx_t_8), 3) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_t_9 = NULL;
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       goto __pyx_L7_unpacking_done;
@@ -24297,7 +24365,7 @@ static PyObject *__pyx_gb_3_sa_14decode_lattice_2generator9(__pyx_GeneratorObjec
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       __pyx_t_9 = NULL;
       if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-      {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      {__pyx_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_L7_unpacking_done:;
     }
     __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_sym);
@@ -24316,19 +24384,19 @@ static PyObject *__pyx_gb_3_sa_14decode_lattice_2generator9(__pyx_GeneratorObjec
     __pyx_cur_scope->__pyx_v_dist = __pyx_t_7;
     __pyx_t_7 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":113
+    /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":116
  * def decode_lattice(lattice):
  *     return tuple((sym_tostring(sym), weight, dist) for (sym, weight, dist) in arc
  *             for arc in node for node in lattice)             # <<<<<<<<<<<<<<
  * 
  * def decode_sentence(lattice):
  */
-    if (unlikely(!__pyx_cur_scope->__pyx_v_node)) { __Pyx_RaiseUnboundLocalError("node"); {__pyx_filename = __pyx_f[10]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+    if (unlikely(!__pyx_cur_scope->__pyx_v_node)) { __Pyx_RaiseUnboundLocalError("node"); {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
     if (PyList_CheckExact(__pyx_cur_scope->__pyx_v_node) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_v_node)) {
       __pyx_t_4 = __pyx_cur_scope->__pyx_v_node; __Pyx_INCREF(__pyx_t_4); __pyx_t_10 = 0;
       __pyx_t_11 = NULL;
     } else {
-      __pyx_t_10 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_node); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_10 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_node); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __pyx_t_11 = Py_TYPE(__pyx_t_4)->tp_iternext;
     }
@@ -24336,23 +24404,23 @@ static PyObject *__pyx_gb_3_sa_14decode_lattice_2generator9(__pyx_GeneratorObjec
       if (!__pyx_t_11 && PyList_CheckExact(__pyx_t_4)) {
         if (__pyx_t_10 >= PyList_GET_SIZE(__pyx_t_4)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_7 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_10); __Pyx_INCREF(__pyx_t_7); __pyx_t_10++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_10); __Pyx_INCREF(__pyx_t_7); __pyx_t_10++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_7 = PySequence_ITEM(__pyx_t_4, __pyx_t_10); __pyx_t_10++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PySequence_ITEM(__pyx_t_4, __pyx_t_10); __pyx_t_10++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else if (!__pyx_t_11 && PyTuple_CheckExact(__pyx_t_4)) {
         if (__pyx_t_10 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_10); __Pyx_INCREF(__pyx_t_7); __pyx_t_10++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_10); __Pyx_INCREF(__pyx_t_7); __pyx_t_10++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_7 = PySequence_ITEM(__pyx_t_4, __pyx_t_10); __pyx_t_10++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PySequence_ITEM(__pyx_t_4, __pyx_t_10); __pyx_t_10++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else {
         __pyx_t_7 = __pyx_t_11(__pyx_t_4);
         if (unlikely(!__pyx_t_7)) {
           if (PyErr_Occurred()) {
             if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-            else {__pyx_filename = __pyx_f[10]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            else {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           }
           break;
         }
@@ -24363,12 +24431,12 @@ static PyObject *__pyx_gb_3_sa_14decode_lattice_2generator9(__pyx_GeneratorObjec
       __Pyx_GIVEREF(__pyx_t_7);
       __pyx_cur_scope->__pyx_v_arc = __pyx_t_7;
       __pyx_t_7 = 0;
-      if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_lattice)) { __Pyx_RaiseClosureNameError("lattice"); {__pyx_filename = __pyx_f[10]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_lattice)) { __Pyx_RaiseClosureNameError("lattice"); {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
       if (PyList_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_lattice) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_lattice)) {
         __pyx_t_7 = __pyx_cur_scope->__pyx_outer_scope->__pyx_v_lattice; __Pyx_INCREF(__pyx_t_7); __pyx_t_12 = 0;
         __pyx_t_13 = NULL;
       } else {
-        __pyx_t_12 = -1; __pyx_t_7 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_lattice); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_12 = -1; __pyx_t_7 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_lattice); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_7);
         __pyx_t_13 = Py_TYPE(__pyx_t_7)->tp_iternext;
       }
@@ -24376,23 +24444,23 @@ static PyObject *__pyx_gb_3_sa_14decode_lattice_2generator9(__pyx_GeneratorObjec
         if (!__pyx_t_13 && PyList_CheckExact(__pyx_t_7)) {
           if (__pyx_t_12 >= PyList_GET_SIZE(__pyx_t_7)) break;
           #if CYTHON_COMPILING_IN_CPYTHON
-          __pyx_t_6 = PyList_GET_ITEM(__pyx_t_7, __pyx_t_12); __Pyx_INCREF(__pyx_t_6); __pyx_t_12++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_6 = PyList_GET_ITEM(__pyx_t_7, __pyx_t_12); __Pyx_INCREF(__pyx_t_6); __pyx_t_12++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           #else
-          __pyx_t_6 = PySequence_ITEM(__pyx_t_7, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_6 = PySequence_ITEM(__pyx_t_7, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           #endif
         } else if (!__pyx_t_13 && PyTuple_CheckExact(__pyx_t_7)) {
           if (__pyx_t_12 >= PyTuple_GET_SIZE(__pyx_t_7)) break;
           #if CYTHON_COMPILING_IN_CPYTHON
-          __pyx_t_6 = PyTuple_GET_ITEM(__pyx_t_7, __pyx_t_12); __Pyx_INCREF(__pyx_t_6); __pyx_t_12++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_6 = PyTuple_GET_ITEM(__pyx_t_7, __pyx_t_12); __Pyx_INCREF(__pyx_t_6); __pyx_t_12++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           #else
-          __pyx_t_6 = PySequence_ITEM(__pyx_t_7, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_6 = PySequence_ITEM(__pyx_t_7, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           #endif
         } else {
           __pyx_t_6 = __pyx_t_13(__pyx_t_7);
           if (unlikely(!__pyx_t_6)) {
             if (PyErr_Occurred()) {
               if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-              else {__pyx_filename = __pyx_f[10]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              else {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             }
             break;
           }
@@ -24404,17 +24472,17 @@ static PyObject *__pyx_gb_3_sa_14decode_lattice_2generator9(__pyx_GeneratorObjec
         __pyx_cur_scope->__pyx_v_node = __pyx_t_6;
         __pyx_t_6 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":112
+        /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":115
  * 
  * def decode_lattice(lattice):
  *     return tuple((sym_tostring(sym), weight, dist) for (sym, weight, dist) in arc             # <<<<<<<<<<<<<<
  *             for arc in node for node in lattice)
  * 
  */
-        __pyx_t_14 = __Pyx_PyInt_AsInt(__pyx_cur_scope->__pyx_v_sym); if (unlikely((__pyx_t_14 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __pyx_t_6 = PyBytes_FromString(__pyx_f_3_sa_sym_tostring(__pyx_t_14)); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_14 = __Pyx_PyInt_AsInt(__pyx_cur_scope->__pyx_v_sym); if (unlikely((__pyx_t_14 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_6 = PyBytes_FromString(__pyx_f_3_sa_sym_tostring(__pyx_t_14)); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(((PyObject *)__pyx_t_6));
-        __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_5);
         PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)__pyx_t_6));
         __Pyx_GIVEREF(((PyObject *)__pyx_t_6));
@@ -24460,7 +24528,7 @@ static PyObject *__pyx_gb_3_sa_14decode_lattice_2generator9(__pyx_GeneratorObjec
         __pyx_t_11 = __pyx_cur_scope->__pyx_t_6;
         __pyx_t_12 = __pyx_cur_scope->__pyx_t_7;
         __pyx_t_13 = __pyx_cur_scope->__pyx_t_8;
-        if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       }
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     }
@@ -24485,7 +24553,7 @@ static PyObject *__pyx_gb_3_sa_14decode_lattice_2generator9(__pyx_GeneratorObjec
   return NULL;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":111
+/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":114
  *     return tuple(((word, None, 1), ) for word in word_ids)
  * 
  * def decode_lattice(lattice):             # <<<<<<<<<<<<<<
@@ -24493,7 +24561,7 @@ static PyObject *__pyx_gb_3_sa_14decode_lattice_2generator9(__pyx_GeneratorObjec
  *             for arc in node for node in lattice)
  */
 
-static PyObject *__pyx_pf_3_sa_4decode_lattice(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_lattice) {
+static PyObject *__pyx_pf_3_sa_6decode_lattice(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_lattice) {
   struct __pyx_obj_3_sa___pyx_scope_struct_7_decode_lattice *__pyx_cur_scope;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
@@ -24513,7 +24581,7 @@ static PyObject *__pyx_pf_3_sa_4decode_lattice(CYTHON_UNUSED PyObject *__pyx_sel
   __Pyx_INCREF(__pyx_cur_scope->__pyx_v_lattice);
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_lattice);
 
-  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":112
+  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":115
  * 
  * def decode_lattice(lattice):
  *     return tuple((sym_tostring(sym), weight, dist) for (sym, weight, dist) in arc             # <<<<<<<<<<<<<<
@@ -24521,14 +24589,14 @@ static PyObject *__pyx_pf_3_sa_4decode_lattice(CYTHON_UNUSED PyObject *__pyx_sel
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_pf_3_sa_14decode_lattice_genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __pyx_pf_3_sa_14decode_lattice_genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_1);
   __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
   __pyx_r = __pyx_t_1;
@@ -24550,19 +24618,19 @@ static PyObject *__pyx_pf_3_sa_4decode_lattice(CYTHON_UNUSED PyObject *__pyx_sel
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_3_sa_7decode_sentence(PyObject *__pyx_self, PyObject *__pyx_v_lattice); /*proto*/
-static PyMethodDef __pyx_mdef_3_sa_7decode_sentence = {__Pyx_NAMESTR("decode_sentence"), (PyCFunction)__pyx_pw_3_sa_7decode_sentence, METH_O, __Pyx_DOCSTR(0)};
-static PyObject *__pyx_pw_3_sa_7decode_sentence(PyObject *__pyx_self, PyObject *__pyx_v_lattice) {
+static PyObject *__pyx_pw_3_sa_9decode_sentence(PyObject *__pyx_self, PyObject *__pyx_v_lattice); /*proto*/
+static PyMethodDef __pyx_mdef_3_sa_9decode_sentence = {__Pyx_NAMESTR("decode_sentence"), (PyCFunction)__pyx_pw_3_sa_9decode_sentence, METH_O, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pw_3_sa_9decode_sentence(PyObject *__pyx_self, PyObject *__pyx_v_lattice) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("decode_sentence (wrapper)", 0);
-  __pyx_r = __pyx_pf_3_sa_6decode_sentence(__pyx_self, ((PyObject *)__pyx_v_lattice));
+  __pyx_r = __pyx_pf_3_sa_8decode_sentence(__pyx_self, ((PyObject *)__pyx_v_lattice));
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 static PyObject *__pyx_gb_3_sa_15decode_sentence_2generator10(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value); /* proto */
 
-/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":116
+/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":119
  * 
  * def decode_sentence(lattice):
  *     return tuple(sym_tostring(sym) for ((sym, _, _),) in lattice)             # <<<<<<<<<<<<<<
@@ -24588,7 +24656,7 @@ static PyObject *__pyx_pf_3_sa_15decode_sentence_genexpr(PyObject *__pyx_self) {
   __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_outer_scope));
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_outer_scope);
   {
-    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_15decode_sentence_2generator10, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_15decode_sentence_2generator10, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_cur_scope);
     __Pyx_RefNannyFinishContext();
     return (PyObject *) gen;
@@ -24631,13 +24699,13 @@ static PyObject *__pyx_gb_3_sa_15decode_sentence_2generator10(__pyx_GeneratorObj
     return NULL;
   }
   __pyx_L3_first_run:;
-  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_lattice)) { __Pyx_RaiseClosureNameError("lattice"); {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_lattice)) { __Pyx_RaiseClosureNameError("lattice"); {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
   if (PyList_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_lattice) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_lattice)) {
     __pyx_t_1 = __pyx_cur_scope->__pyx_outer_scope->__pyx_v_lattice; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
     __pyx_t_3 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_lattice); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_lattice); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -24645,23 +24713,23 @@ static PyObject *__pyx_gb_3_sa_15decode_sentence_2generator10(__pyx_GeneratorObj
     if (!__pyx_t_3 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_3 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_4 = __pyx_t_3(__pyx_t_1);
       if (unlikely(!__pyx_t_4)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -24677,7 +24745,7 @@ static PyObject *__pyx_gb_3_sa_15decode_sentence_2generator10(__pyx_GeneratorObj
       if (unlikely(size != 1)) {
         if (size > 1) __Pyx_RaiseTooManyValuesError(1);
         else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-        {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       }
       #if CYTHON_COMPILING_IN_CPYTHON
       if (likely(PyTuple_CheckExact(sequence))) {
@@ -24687,19 +24755,19 @@ static PyObject *__pyx_gb_3_sa_15decode_sentence_2generator10(__pyx_GeneratorObj
       }
       __Pyx_INCREF(__pyx_t_5);
       #else
-      __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     } else
     {
       Py_ssize_t index = -1;
-      __pyx_t_6 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_6);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __pyx_t_7 = Py_TYPE(__pyx_t_6)->tp_iternext;
       index = 0; __pyx_t_5 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_5)) goto __pyx_L6_unpacking_failed;
       __Pyx_GOTREF(__pyx_t_5);
-      if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_6), 1) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_6), 1) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_t_7 = NULL;
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       goto __pyx_L7_unpacking_done;
@@ -24707,7 +24775,7 @@ static PyObject *__pyx_gb_3_sa_15decode_sentence_2generator10(__pyx_GeneratorObj
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       __pyx_t_7 = NULL;
       if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-      {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_L7_unpacking_done:;
     }
     if ((likely(PyTuple_CheckExact(__pyx_t_5))) || (PyList_CheckExact(__pyx_t_5))) {
@@ -24720,7 +24788,7 @@ static PyObject *__pyx_gb_3_sa_15decode_sentence_2generator10(__pyx_GeneratorObj
       if (unlikely(size != 3)) {
         if (size > 3) __Pyx_RaiseTooManyValuesError(3);
         else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-        {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       }
       #if CYTHON_COMPILING_IN_CPYTHON
       if (likely(PyTuple_CheckExact(sequence))) {
@@ -24736,15 +24804,15 @@ static PyObject *__pyx_gb_3_sa_15decode_sentence_2generator10(__pyx_GeneratorObj
       __Pyx_INCREF(__pyx_t_8);
       __Pyx_INCREF(__pyx_t_9);
       #else
-      __pyx_t_6 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_8 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_9 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_9 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     } else
     {
       Py_ssize_t index = -1;
-      __pyx_t_10 = PyObject_GetIter(__pyx_t_5); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_10 = PyObject_GetIter(__pyx_t_5); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_10);
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       __pyx_t_7 = Py_TYPE(__pyx_t_10)->tp_iternext;
@@ -24754,7 +24822,7 @@ static PyObject *__pyx_gb_3_sa_15decode_sentence_2generator10(__pyx_GeneratorObj
       __Pyx_GOTREF(__pyx_t_8);
       index = 2; __pyx_t_9 = __pyx_t_7(__pyx_t_10); if (unlikely(!__pyx_t_9)) goto __pyx_L8_unpacking_failed;
       __Pyx_GOTREF(__pyx_t_9);
-      if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_10), 3) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_10), 3) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_t_7 = NULL;
       __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
       goto __pyx_L9_unpacking_done;
@@ -24762,7 +24830,7 @@ static PyObject *__pyx_gb_3_sa_15decode_sentence_2generator10(__pyx_GeneratorObj
       __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
       __pyx_t_7 = NULL;
       if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-      {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_L9_unpacking_done:;
     }
     __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_sym);
@@ -24780,8 +24848,8 @@ static PyObject *__pyx_gb_3_sa_15decode_sentence_2generator10(__pyx_GeneratorObj
     __Pyx_GIVEREF(__pyx_t_9);
     __pyx_cur_scope->__pyx_v__ = __pyx_t_9;
     __pyx_t_9 = 0;
-    __pyx_t_11 = __Pyx_PyInt_AsInt(__pyx_cur_scope->__pyx_v_sym); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_4 = PyBytes_FromString(__pyx_f_3_sa_sym_tostring(__pyx_t_11)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_11 = __Pyx_PyInt_AsInt(__pyx_cur_scope->__pyx_v_sym); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyBytes_FromString(__pyx_f_3_sa_sym_tostring(__pyx_t_11)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(((PyObject *)__pyx_t_4));
     __pyx_r = ((PyObject *)__pyx_t_4);
     __pyx_t_4 = 0;
@@ -24800,7 +24868,7 @@ static PyObject *__pyx_gb_3_sa_15decode_sentence_2generator10(__pyx_GeneratorObj
     __Pyx_XGOTREF(__pyx_t_1);
     __pyx_t_2 = __pyx_cur_scope->__pyx_t_1;
     __pyx_t_3 = __pyx_cur_scope->__pyx_t_2;
-    if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyErr_SetNone(PyExc_StopIteration);
@@ -24822,7 +24890,7 @@ static PyObject *__pyx_gb_3_sa_15decode_sentence_2generator10(__pyx_GeneratorObj
   return NULL;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":115
+/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":118
  *             for arc in node for node in lattice)
  * 
  * def decode_sentence(lattice):             # <<<<<<<<<<<<<<
@@ -24830,7 +24898,7 @@ static PyObject *__pyx_gb_3_sa_15decode_sentence_2generator10(__pyx_GeneratorObj
  * 
  */
 
-static PyObject *__pyx_pf_3_sa_6decode_sentence(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_lattice) {
+static PyObject *__pyx_pf_3_sa_8decode_sentence(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_lattice) {
   struct __pyx_obj_3_sa___pyx_scope_struct_9_decode_sentence *__pyx_cur_scope;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
@@ -24850,7 +24918,7 @@ static PyObject *__pyx_pf_3_sa_6decode_sentence(CYTHON_UNUSED PyObject *__pyx_se
   __Pyx_INCREF(__pyx_cur_scope->__pyx_v_lattice);
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_lattice);
 
-  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":116
+  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":119
  * 
  * def decode_sentence(lattice):
  *     return tuple(sym_tostring(sym) for ((sym, _, _),) in lattice)             # <<<<<<<<<<<<<<
@@ -24858,14 +24926,14 @@ static PyObject *__pyx_pf_3_sa_6decode_sentence(CYTHON_UNUSED PyObject *__pyx_se
  * def encode_words(words):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_pf_3_sa_15decode_sentence_genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __pyx_pf_3_sa_15decode_sentence_genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_1);
   __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
   __pyx_r = __pyx_t_1;
@@ -24887,19 +24955,19 @@ static PyObject *__pyx_pf_3_sa_6decode_sentence(CYTHON_UNUSED PyObject *__pyx_se
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_3_sa_9encode_words(PyObject *__pyx_self, PyObject *__pyx_v_words); /*proto*/
-static PyMethodDef __pyx_mdef_3_sa_9encode_words = {__Pyx_NAMESTR("encode_words"), (PyCFunction)__pyx_pw_3_sa_9encode_words, METH_O, __Pyx_DOCSTR(0)};
-static PyObject *__pyx_pw_3_sa_9encode_words(PyObject *__pyx_self, PyObject *__pyx_v_words) {
+static PyObject *__pyx_pw_3_sa_11encode_words(PyObject *__pyx_self, PyObject *__pyx_v_words); /*proto*/
+static PyMethodDef __pyx_mdef_3_sa_11encode_words = {__Pyx_NAMESTR("encode_words"), (PyCFunction)__pyx_pw_3_sa_11encode_words, METH_O, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pw_3_sa_11encode_words(PyObject *__pyx_self, PyObject *__pyx_v_words) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("encode_words (wrapper)", 0);
-  __pyx_r = __pyx_pf_3_sa_8encode_words(__pyx_self, ((PyObject *)__pyx_v_words));
+  __pyx_r = __pyx_pf_3_sa_10encode_words(__pyx_self, ((PyObject *)__pyx_v_words));
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 static PyObject *__pyx_gb_3_sa_12encode_words_2generator11(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value); /* proto */
 
-/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":119
+/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":122
  * 
  * def encode_words(words):
  *     return tuple(sym_fromstring(word, True) for word in words)             # <<<<<<<<<<<<<<
@@ -24925,7 +24993,7 @@ static PyObject *__pyx_pf_3_sa_12encode_words_genexpr(PyObject *__pyx_self) {
   __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_outer_scope));
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_outer_scope);
   {
-    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_12encode_words_2generator11, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_12encode_words_2generator11, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_cur_scope);
     __Pyx_RefNannyFinishContext();
     return (PyObject *) gen;
@@ -24962,13 +25030,13 @@ static PyObject *__pyx_gb_3_sa_12encode_words_2generator11(__pyx_GeneratorObject
     return NULL;
   }
   __pyx_L3_first_run:;
-  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_words)) { __Pyx_RaiseClosureNameError("words"); {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_words)) { __Pyx_RaiseClosureNameError("words"); {__pyx_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
   if (PyList_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_words) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_words)) {
     __pyx_t_1 = __pyx_cur_scope->__pyx_outer_scope->__pyx_v_words; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
     __pyx_t_3 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_words); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_words); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -24976,23 +25044,23 @@ static PyObject *__pyx_gb_3_sa_12encode_words_2generator11(__pyx_GeneratorObject
     if (!__pyx_t_3 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_3 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_4 = __pyx_t_3(__pyx_t_1);
       if (unlikely(!__pyx_t_4)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -25003,8 +25071,8 @@ static PyObject *__pyx_gb_3_sa_12encode_words_2generator11(__pyx_GeneratorObject
     __Pyx_GIVEREF(__pyx_t_4);
     __pyx_cur_scope->__pyx_v_word = __pyx_t_4;
     __pyx_t_4 = 0;
-    __pyx_t_5 = PyBytes_AsString(__pyx_cur_scope->__pyx_v_word); if (unlikely((!__pyx_t_5) && PyErr_Occurred())) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_4 = PyInt_FromLong(__pyx_f_3_sa_sym_fromstring(__pyx_t_5, 1)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyBytes_AsString(__pyx_cur_scope->__pyx_v_word); if (unlikely((!__pyx_t_5) && PyErr_Occurred())) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyInt_FromLong(__pyx_f_3_sa_sym_fromstring(__pyx_t_5, 1)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __pyx_r = __pyx_t_4;
     __pyx_t_4 = 0;
@@ -25023,7 +25091,7 @@ static PyObject *__pyx_gb_3_sa_12encode_words_2generator11(__pyx_GeneratorObject
     __Pyx_XGOTREF(__pyx_t_1);
     __pyx_t_2 = __pyx_cur_scope->__pyx_t_1;
     __pyx_t_3 = __pyx_cur_scope->__pyx_t_2;
-    if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyErr_SetNone(PyExc_StopIteration);
@@ -25040,7 +25108,7 @@ static PyObject *__pyx_gb_3_sa_12encode_words_2generator11(__pyx_GeneratorObject
   return NULL;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":118
+/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":121
  *     return tuple(sym_tostring(sym) for ((sym, _, _),) in lattice)
  * 
  * def encode_words(words):             # <<<<<<<<<<<<<<
@@ -25048,7 +25116,7 @@ static PyObject *__pyx_gb_3_sa_12encode_words_2generator11(__pyx_GeneratorObject
  * 
  */
 
-static PyObject *__pyx_pf_3_sa_8encode_words(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_words) {
+static PyObject *__pyx_pf_3_sa_10encode_words(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_words) {
   struct __pyx_obj_3_sa___pyx_scope_struct_11_encode_words *__pyx_cur_scope;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
@@ -25068,7 +25136,7 @@ static PyObject *__pyx_pf_3_sa_8encode_words(CYTHON_UNUSED PyObject *__pyx_self,
   __Pyx_INCREF(__pyx_cur_scope->__pyx_v_words);
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_words);
 
-  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":119
+  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":122
  * 
  * def encode_words(words):
  *     return tuple(sym_fromstring(word, True) for word in words)             # <<<<<<<<<<<<<<
@@ -25076,14 +25144,14 @@ static PyObject *__pyx_pf_3_sa_8encode_words(CYTHON_UNUSED PyObject *__pyx_self,
  * def decode_words(syms):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_pf_3_sa_12encode_words_genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __pyx_pf_3_sa_12encode_words_genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_1);
   __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
   __pyx_r = __pyx_t_1;
@@ -25105,19 +25173,19 @@ static PyObject *__pyx_pf_3_sa_8encode_words(CYTHON_UNUSED PyObject *__pyx_self,
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_3_sa_11decode_words(PyObject *__pyx_self, PyObject *__pyx_v_syms); /*proto*/
-static PyMethodDef __pyx_mdef_3_sa_11decode_words = {__Pyx_NAMESTR("decode_words"), (PyCFunction)__pyx_pw_3_sa_11decode_words, METH_O, __Pyx_DOCSTR(0)};
-static PyObject *__pyx_pw_3_sa_11decode_words(PyObject *__pyx_self, PyObject *__pyx_v_syms) {
+static PyObject *__pyx_pw_3_sa_13decode_words(PyObject *__pyx_self, PyObject *__pyx_v_syms); /*proto*/
+static PyMethodDef __pyx_mdef_3_sa_13decode_words = {__Pyx_NAMESTR("decode_words"), (PyCFunction)__pyx_pw_3_sa_13decode_words, METH_O, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pw_3_sa_13decode_words(PyObject *__pyx_self, PyObject *__pyx_v_syms) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("decode_words (wrapper)", 0);
-  __pyx_r = __pyx_pf_3_sa_10decode_words(__pyx_self, ((PyObject *)__pyx_v_syms));
+  __pyx_r = __pyx_pf_3_sa_12decode_words(__pyx_self, ((PyObject *)__pyx_v_syms));
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 static PyObject *__pyx_gb_3_sa_12decode_words_2generator12(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value); /* proto */
 
-/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":122
+/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":125
  * 
  * def decode_words(syms):
  *     return tuple(sym_tostring(sym) for sym in syms)             # <<<<<<<<<<<<<<
@@ -25141,7 +25209,7 @@ static PyObject *__pyx_pf_3_sa_12decode_words_genexpr(PyObject *__pyx_self) {
   __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_outer_scope));
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_outer_scope);
   {
-    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_12decode_words_2generator12, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_12decode_words_2generator12, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_cur_scope);
     __Pyx_RefNannyFinishContext();
     return (PyObject *) gen;
@@ -25178,13 +25246,13 @@ static PyObject *__pyx_gb_3_sa_12decode_words_2generator12(__pyx_GeneratorObject
     return NULL;
   }
   __pyx_L3_first_run:;
-  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_syms)) { __Pyx_RaiseClosureNameError("syms"); {__pyx_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_syms)) { __Pyx_RaiseClosureNameError("syms"); {__pyx_filename = __pyx_f[10]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
   if (PyList_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_syms) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_syms)) {
     __pyx_t_1 = __pyx_cur_scope->__pyx_outer_scope->__pyx_v_syms; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
     __pyx_t_3 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_syms); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_syms); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -25192,23 +25260,23 @@ static PyObject *__pyx_gb_3_sa_12decode_words_2generator12(__pyx_GeneratorObject
     if (!__pyx_t_3 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[10]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_3 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[10]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_4 = __pyx_t_3(__pyx_t_1);
       if (unlikely(!__pyx_t_4)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[10]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -25219,8 +25287,8 @@ static PyObject *__pyx_gb_3_sa_12decode_words_2generator12(__pyx_GeneratorObject
     __Pyx_GIVEREF(__pyx_t_4);
     __pyx_cur_scope->__pyx_v_sym = __pyx_t_4;
     __pyx_t_4 = 0;
-    __pyx_t_5 = __Pyx_PyInt_AsInt(__pyx_cur_scope->__pyx_v_sym); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_4 = PyBytes_FromString(__pyx_f_3_sa_sym_tostring(__pyx_t_5)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_PyInt_AsInt(__pyx_cur_scope->__pyx_v_sym); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyBytes_FromString(__pyx_f_3_sa_sym_tostring(__pyx_t_5)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(((PyObject *)__pyx_t_4));
     __pyx_r = ((PyObject *)__pyx_t_4);
     __pyx_t_4 = 0;
@@ -25239,7 +25307,7 @@ static PyObject *__pyx_gb_3_sa_12decode_words_2generator12(__pyx_GeneratorObject
     __Pyx_XGOTREF(__pyx_t_1);
     __pyx_t_2 = __pyx_cur_scope->__pyx_t_1;
     __pyx_t_3 = __pyx_cur_scope->__pyx_t_2;
-    if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyErr_SetNone(PyExc_StopIteration);
@@ -25256,14 +25324,14 @@ static PyObject *__pyx_gb_3_sa_12decode_words_2generator12(__pyx_GeneratorObject
   return NULL;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":121
+/* "/home/m/workspace/cdec/python/src/sa/sym.pxi":124
  *     return tuple(sym_fromstring(word, True) for word in words)
  * 
  * def decode_words(syms):             # <<<<<<<<<<<<<<
  *     return tuple(sym_tostring(sym) for sym in syms)
  */
 
-static PyObject *__pyx_pf_3_sa_10decode_words(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_syms) {
+static PyObject *__pyx_pf_3_sa_12decode_words(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_syms) {
   struct __pyx_obj_3_sa___pyx_scope_struct_13_decode_words *__pyx_cur_scope;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
@@ -25283,20 +25351,20 @@ static PyObject *__pyx_pf_3_sa_10decode_words(CYTHON_UNUSED PyObject *__pyx_self
   __Pyx_INCREF(__pyx_cur_scope->__pyx_v_syms);
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_syms);
 
-  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":122
+  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":125
  * 
  * def decode_words(syms):
  *     return tuple(sym_tostring(sym) for sym in syms)             # <<<<<<<<<<<<<<
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_pf_3_sa_12decode_words_genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __pyx_pf_3_sa_12decode_words_genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_1);
   __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
   __pyx_r = __pyx_t_1;
@@ -36652,7 +36720,7 @@ static int __pyx_pw_3_sa_8TrieNode_1__cinit__(PyObject *__pyx_v_self, PyObject *
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":47
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":49
  *     cdef public children
  * 
  *     def __cinit__(self):             # <<<<<<<<<<<<<<
@@ -36669,14 +36737,14 @@ static int __pyx_pf_3_sa_8TrieNode___cinit__(struct __pyx_obj_3_sa_TrieNode *__p
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__cinit__", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":48
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":50
  * 
  *     def __cinit__(self):
  *         self.children = {}             # <<<<<<<<<<<<<<
  * 
  * cdef class ExtendedTrieNode(TrieNode):
  */
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
   __Pyx_GOTREF(__pyx_v_self->children);
@@ -36706,7 +36774,7 @@ static PyObject *__pyx_pw_3_sa_8TrieNode_8children_1__get__(PyObject *__pyx_v_se
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":45
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":47
  * 
  * cdef class TrieNode:
  *     cdef public children             # <<<<<<<<<<<<<<
@@ -36795,7 +36863,7 @@ static int __pyx_pw_3_sa_16ExtendedTrieNode_1__cinit__(PyObject *__pyx_v_self, P
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__phrase,&__pyx_n_s__phrase_location,&__pyx_n_s__suffix_link,0};
     PyObject* values[3] = {0,0,0};
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":55
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":57
  *     cdef public suffix_link
  * 
  *     def __cinit__(self, phrase=None, phrase_location=None, suffix_link=None):             # <<<<<<<<<<<<<<
@@ -36834,7 +36902,7 @@ static int __pyx_pw_3_sa_16ExtendedTrieNode_1__cinit__(PyObject *__pyx_v_self, P
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -36851,7 +36919,7 @@ static int __pyx_pw_3_sa_16ExtendedTrieNode_1__cinit__(PyObject *__pyx_v_self, P
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.ExtendedTrieNode.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -36867,7 +36935,7 @@ static int __pyx_pf_3_sa_16ExtendedTrieNode___cinit__(struct __pyx_obj_3_sa_Exte
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__cinit__", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":56
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":58
  * 
  *     def __cinit__(self, phrase=None, phrase_location=None, suffix_link=None):
  *         self.phrase = phrase             # <<<<<<<<<<<<<<
@@ -36880,7 +36948,7 @@ static int __pyx_pf_3_sa_16ExtendedTrieNode___cinit__(struct __pyx_obj_3_sa_Exte
   __Pyx_DECREF(__pyx_v_self->phrase);
   __pyx_v_self->phrase = __pyx_v_phrase;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":57
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":59
  *     def __cinit__(self, phrase=None, phrase_location=None, suffix_link=None):
  *         self.phrase = phrase
  *         self.phrase_location = phrase_location             # <<<<<<<<<<<<<<
@@ -36893,7 +36961,7 @@ static int __pyx_pf_3_sa_16ExtendedTrieNode___cinit__(struct __pyx_obj_3_sa_Exte
   __Pyx_DECREF(__pyx_v_self->phrase_location);
   __pyx_v_self->phrase_location = __pyx_v_phrase_location;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":58
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":60
  *         self.phrase = phrase
  *         self.phrase_location = phrase_location
  *         self.suffix_link = suffix_link             # <<<<<<<<<<<<<<
@@ -36922,7 +36990,7 @@ static PyObject *__pyx_pw_3_sa_16ExtendedTrieNode_6phrase_1__get__(PyObject *__p
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":51
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":53
  * 
  * cdef class ExtendedTrieNode(TrieNode):
  *     cdef public phrase             # <<<<<<<<<<<<<<
@@ -37009,7 +37077,7 @@ static PyObject *__pyx_pw_3_sa_16ExtendedTrieNode_15phrase_location_1__get__(PyO
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":52
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":54
  * cdef class ExtendedTrieNode(TrieNode):
  *     cdef public phrase
  *     cdef public phrase_location             # <<<<<<<<<<<<<<
@@ -37096,7 +37164,7 @@ static PyObject *__pyx_pw_3_sa_16ExtendedTrieNode_11suffix_link_1__get__(PyObjec
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":53
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":55
  *     cdef public phrase
  *     cdef public phrase_location
  *     cdef public suffix_link             # <<<<<<<<<<<<<<
@@ -37200,7 +37268,7 @@ static int __pyx_pw_3_sa_9TrieTable_1__cinit__(PyObject *__pyx_v_self, PyObject
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -37213,7 +37281,7 @@ static int __pyx_pw_3_sa_9TrieTable_1__cinit__(PyObject *__pyx_v_self, PyObject
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.TrieTable.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -37224,7 +37292,7 @@ static int __pyx_pw_3_sa_9TrieTable_1__cinit__(PyObject *__pyx_v_self, PyObject
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":65
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":67
  *     cdef public int count
  *     cdef public root
  *     def __cinit__(self, extended=False):             # <<<<<<<<<<<<<<
@@ -37243,7 +37311,7 @@ static int __pyx_pf_3_sa_9TrieTable___cinit__(struct __pyx_obj_3_sa_TrieTable *_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__cinit__", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":66
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":68
  *     cdef public root
  *     def __cinit__(self, extended=False):
  *         self.count = 0             # <<<<<<<<<<<<<<
@@ -37252,34 +37320,34 @@ static int __pyx_pf_3_sa_9TrieTable___cinit__(struct __pyx_obj_3_sa_TrieTable *_
  */
   __pyx_v_self->count = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":67
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":69
  *     def __cinit__(self, extended=False):
  *         self.count = 0
  *         self.extended = extended             # <<<<<<<<<<<<<<
  *         if extended:
  *             self.root = ExtendedTrieNode()
  */
-  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_extended); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_extended); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_v_self->extended = __pyx_t_1;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":68
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":70
  *         self.count = 0
  *         self.extended = extended
  *         if extended:             # <<<<<<<<<<<<<<
  *             self.root = ExtendedTrieNode()
  *         else:
  */
-  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_extended); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 68; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_extended); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   if (__pyx_t_2) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":69
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":71
  *         self.extended = extended
  *         if extended:
  *             self.root = ExtendedTrieNode()             # <<<<<<<<<<<<<<
  *         else:
  *             self.root = TrieNode()
  */
-    __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_ExtendedTrieNode)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_ExtendedTrieNode)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_GIVEREF(__pyx_t_3);
     __Pyx_GOTREF(__pyx_v_self->root);
@@ -37290,14 +37358,14 @@ static int __pyx_pf_3_sa_9TrieTable___cinit__(struct __pyx_obj_3_sa_TrieTable *_
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":71
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":73
  *             self.root = ExtendedTrieNode()
  *         else:
  *             self.root = TrieNode()             # <<<<<<<<<<<<<<
  * 
  * # linked list structure for storing matches in BaselineRuleFactory
  */
-    __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_TrieNode)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_TrieNode)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 73; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_GIVEREF(__pyx_t_3);
     __Pyx_GOTREF(__pyx_v_self->root);
@@ -37329,7 +37397,7 @@ static PyObject *__pyx_pw_3_sa_9TrieTable_8extended_1__get__(PyObject *__pyx_v_s
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":62
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":64
  * 
  * cdef class TrieTable:
  *     cdef public int extended             # <<<<<<<<<<<<<<
@@ -37346,7 +37414,7 @@ static PyObject *__pyx_pf_3_sa_9TrieTable_8extended___get__(struct __pyx_obj_3_s
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->extended); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->extended); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -37383,7 +37451,7 @@ static int __pyx_pf_3_sa_9TrieTable_8extended_2__set__(struct __pyx_obj_3_sa_Tri
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__set__", 0);
-  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_value); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_value); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_v_self->extended = __pyx_t_1;
 
   __pyx_r = 0;
@@ -37407,7 +37475,7 @@ static PyObject *__pyx_pw_3_sa_9TrieTable_5count_1__get__(PyObject *__pyx_v_self
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":63
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":65
  * cdef class TrieTable:
  *     cdef public int extended
  *     cdef public int count             # <<<<<<<<<<<<<<
@@ -37424,7 +37492,7 @@ static PyObject *__pyx_pf_3_sa_9TrieTable_5count___get__(struct __pyx_obj_3_sa_T
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->count); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->count); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -37461,7 +37529,7 @@ static int __pyx_pf_3_sa_9TrieTable_5count_2__set__(struct __pyx_obj_3_sa_TrieTa
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__set__", 0);
-  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_value); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_value); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_v_self->count = __pyx_t_1;
 
   __pyx_r = 0;
@@ -37485,7 +37553,7 @@ static PyObject *__pyx_pw_3_sa_9TrieTable_4root_1__get__(PyObject *__pyx_v_self)
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":64
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":66
  *     cdef public int extended
  *     cdef public int count
  *     cdef public root             # <<<<<<<<<<<<<<
@@ -37561,7 +37629,7 @@ static int __pyx_pf_3_sa_9TrieTable_4root_4__del__(struct __pyx_obj_3_sa_TrieTab
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":91
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":93
  * 
  *     # returns true if sent_id is contained
  *     cdef int contains(self, int sent_id):             # <<<<<<<<<<<<<<
@@ -37574,7 +37642,7 @@ static int __pyx_f_3_sa_14PhraseLocation_contains(CYTHON_UNUSED struct __pyx_obj
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("contains", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":92
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":94
  *     # returns true if sent_id is contained
  *     cdef int contains(self, int sent_id):
  *         return 1             # <<<<<<<<<<<<<<
@@ -37606,7 +37674,7 @@ static int __pyx_pw_3_sa_14PhraseLocation_1__cinit__(PyObject *__pyx_v_self, PyO
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__sa_low,&__pyx_n_s__sa_high,&__pyx_n_s__arr_low,&__pyx_n_s__arr_high,&__pyx_n_s__arr,&__pyx_n_s__num_subpatterns,0};
     PyObject* values[6] = {0,0,0,0,0,0};
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":95
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":97
  * 
  *     def __cinit__(self, int sa_low=-1, int sa_high=-1, int arr_low=-1, int arr_high=-1,
  *             arr=None, int num_subpatterns=1):             # <<<<<<<<<<<<<<
@@ -37661,7 +37729,7 @@ static int __pyx_pw_3_sa_14PhraseLocation_1__cinit__(PyObject *__pyx_v_self, PyO
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -37676,35 +37744,35 @@ static int __pyx_pw_3_sa_14PhraseLocation_1__cinit__(PyObject *__pyx_v_self, PyO
       }
     }
     if (values[0]) {
-      __pyx_v_sa_low = __Pyx_PyInt_AsInt(values[0]); if (unlikely((__pyx_v_sa_low == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_sa_low = __Pyx_PyInt_AsInt(values[0]); if (unlikely((__pyx_v_sa_low == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
       __pyx_v_sa_low = ((int)-1);
     }
     if (values[1]) {
-      __pyx_v_sa_high = __Pyx_PyInt_AsInt(values[1]); if (unlikely((__pyx_v_sa_high == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_sa_high = __Pyx_PyInt_AsInt(values[1]); if (unlikely((__pyx_v_sa_high == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
       __pyx_v_sa_high = ((int)-1);
     }
     if (values[2]) {
-      __pyx_v_arr_low = __Pyx_PyInt_AsInt(values[2]); if (unlikely((__pyx_v_arr_low == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_arr_low = __Pyx_PyInt_AsInt(values[2]); if (unlikely((__pyx_v_arr_low == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
       __pyx_v_arr_low = ((int)-1);
     }
     if (values[3]) {
-      __pyx_v_arr_high = __Pyx_PyInt_AsInt(values[3]); if (unlikely((__pyx_v_arr_high == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_arr_high = __Pyx_PyInt_AsInt(values[3]); if (unlikely((__pyx_v_arr_high == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
       __pyx_v_arr_high = ((int)-1);
     }
     __pyx_v_arr = values[4];
     if (values[5]) {
-      __pyx_v_num_subpatterns = __Pyx_PyInt_AsInt(values[5]); if (unlikely((__pyx_v_num_subpatterns == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_num_subpatterns = __Pyx_PyInt_AsInt(values[5]); if (unlikely((__pyx_v_num_subpatterns == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 97; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
       __pyx_v_num_subpatterns = ((int)1);
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 0, 6, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 0, 6, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.PhraseLocation.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -37715,7 +37783,7 @@ static int __pyx_pw_3_sa_14PhraseLocation_1__cinit__(PyObject *__pyx_v_self, PyO
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":94
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":96
  *         return 1
  * 
  *     def __cinit__(self, int sa_low=-1, int sa_high=-1, int arr_low=-1, int arr_high=-1,             # <<<<<<<<<<<<<<
@@ -37731,7 +37799,7 @@ static int __pyx_pf_3_sa_14PhraseLocation___cinit__(struct __pyx_obj_3_sa_Phrase
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__cinit__", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":96
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":98
  *     def __cinit__(self, int sa_low=-1, int sa_high=-1, int arr_low=-1, int arr_high=-1,
  *             arr=None, int num_subpatterns=1):
  *         self.sa_low = sa_low             # <<<<<<<<<<<<<<
@@ -37740,7 +37808,7 @@ static int __pyx_pf_3_sa_14PhraseLocation___cinit__(struct __pyx_obj_3_sa_Phrase
  */
   __pyx_v_self->sa_low = __pyx_v_sa_low;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":97
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":99
  *             arr=None, int num_subpatterns=1):
  *         self.sa_low = sa_low
  *         self.sa_high = sa_high             # <<<<<<<<<<<<<<
@@ -37749,7 +37817,7 @@ static int __pyx_pf_3_sa_14PhraseLocation___cinit__(struct __pyx_obj_3_sa_Phrase
  */
   __pyx_v_self->sa_high = __pyx_v_sa_high;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":98
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":100
  *         self.sa_low = sa_low
  *         self.sa_high = sa_high
  *         self.arr_low = arr_low             # <<<<<<<<<<<<<<
@@ -37758,7 +37826,7 @@ static int __pyx_pf_3_sa_14PhraseLocation___cinit__(struct __pyx_obj_3_sa_Phrase
  */
   __pyx_v_self->arr_low = __pyx_v_arr_low;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":99
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":101
  *         self.sa_high = sa_high
  *         self.arr_low = arr_low
  *         self.arr_high = arr_high             # <<<<<<<<<<<<<<
@@ -37767,21 +37835,21 @@ static int __pyx_pf_3_sa_14PhraseLocation___cinit__(struct __pyx_obj_3_sa_Phrase
  */
   __pyx_v_self->arr_high = __pyx_v_arr_high;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":100
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":102
  *         self.arr_low = arr_low
  *         self.arr_high = arr_high
  *         self.arr = arr             # <<<<<<<<<<<<<<
  *         self.num_subpatterns = num_subpatterns
  * 
  */
-  if (!(likely(((__pyx_v_arr) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_arr, __pyx_ptype_3_sa_IntList))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (!(likely(((__pyx_v_arr) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_arr, __pyx_ptype_3_sa_IntList))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_INCREF(__pyx_v_arr);
   __Pyx_GIVEREF(__pyx_v_arr);
   __Pyx_GOTREF(__pyx_v_self->arr);
   __Pyx_DECREF(((PyObject *)__pyx_v_self->arr));
   __pyx_v_self->arr = ((struct __pyx_obj_3_sa_IntList *)__pyx_v_arr);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":101
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":103
  *         self.arr_high = arr_high
  *         self.arr = arr
  *         self.num_subpatterns = num_subpatterns             # <<<<<<<<<<<<<<
@@ -37828,11 +37896,11 @@ static int __pyx_pw_3_sa_7Sampler_1__cinit__(PyObject *__pyx_v_self, PyObject *_
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__fsarray)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 2, 2, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 2, 2, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -37840,18 +37908,18 @@ static int __pyx_pw_3_sa_7Sampler_1__cinit__(PyObject *__pyx_v_self, PyObject *_
       values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
-    __pyx_v_sample_size = __Pyx_PyInt_AsInt(values[0]); if (unlikely((__pyx_v_sample_size == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_sample_size = __Pyx_PyInt_AsInt(values[0]); if (unlikely((__pyx_v_sample_size == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     __pyx_v_fsarray = ((struct __pyx_obj_3_sa_SuffixArray *)values[1]);
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.Sampler.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return -1;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_fsarray), __pyx_ptype_3_sa_SuffixArray, 1, "fsarray", 0))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_fsarray), __pyx_ptype_3_sa_SuffixArray, 1, "fsarray", 0))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_r = __pyx_pf_3_sa_7Sampler___cinit__(((struct __pyx_obj_3_sa_Sampler *)__pyx_v_self), __pyx_v_sample_size, __pyx_v_fsarray);
   goto __pyx_L0;
   __pyx_L1_error:;
@@ -37861,7 +37929,7 @@ static int __pyx_pw_3_sa_7Sampler_1__cinit__(PyObject *__pyx_v_self, PyObject *_
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":111
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":113
  *     cdef IntList sa
  * 
  *     def __cinit__(self, int sample_size, SuffixArray fsarray):             # <<<<<<<<<<<<<<
@@ -37881,7 +37949,7 @@ static int __pyx_pf_3_sa_7Sampler___cinit__(struct __pyx_obj_3_sa_Sampler *__pyx
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__cinit__", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":112
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":114
  * 
  *     def __cinit__(self, int sample_size, SuffixArray fsarray):
  *         self.sample_size = sample_size             # <<<<<<<<<<<<<<
@@ -37890,7 +37958,7 @@ static int __pyx_pf_3_sa_7Sampler___cinit__(struct __pyx_obj_3_sa_Sampler *__pyx
  */
   __pyx_v_self->sample_size = __pyx_v_sample_size;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":113
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":115
  *     def __cinit__(self, int sample_size, SuffixArray fsarray):
  *         self.sample_size = sample_size
  *         self.sa = fsarray.sa             # <<<<<<<<<<<<<<
@@ -37903,7 +37971,7 @@ static int __pyx_pf_3_sa_7Sampler___cinit__(struct __pyx_obj_3_sa_Sampler *__pyx
   __Pyx_DECREF(((PyObject *)__pyx_v_self->sa));
   __pyx_v_self->sa = __pyx_v_fsarray->sa;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":114
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":116
  *         self.sample_size = sample_size
  *         self.sa = fsarray.sa
  *         if sample_size > 0:             # <<<<<<<<<<<<<<
@@ -37913,21 +37981,21 @@ static int __pyx_pf_3_sa_7Sampler___cinit__(struct __pyx_obj_3_sa_Sampler *__pyx
   __pyx_t_1 = (__pyx_v_sample_size > 0);
   if (__pyx_t_1) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":115
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":117
  *         self.sa = fsarray.sa
  *         if sample_size > 0:
  *             logger.info("Sampling strategy: uniform, max sample size = %d", sample_size)             # <<<<<<<<<<<<<<
  *         else:
  *             logger.info("Sampling strategy: no sampling")
  */
-    __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_3 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__info); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__info); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_2 = PyInt_FromLong(__pyx_v_sample_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyInt_FromLong(__pyx_v_sample_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_INCREF(((PyObject *)__pyx_kp_s_100));
     PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_kp_s_100));
@@ -37935,7 +38003,7 @@ static int __pyx_pf_3_sa_7Sampler___cinit__(struct __pyx_obj_3_sa_Sampler *__pyx
     PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_2);
     __Pyx_GIVEREF(__pyx_t_2);
     __pyx_t_2 = 0;
-    __pyx_t_2 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
@@ -37944,19 +38012,19 @@ static int __pyx_pf_3_sa_7Sampler___cinit__(struct __pyx_obj_3_sa_Sampler *__pyx
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":117
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":119
  *             logger.info("Sampling strategy: uniform, max sample size = %d", sample_size)
  *         else:
  *             logger.info("Sampling strategy: no sampling")             # <<<<<<<<<<<<<<
  * 
  *     def sample(self, PhraseLocation phrase_location):
  */
-    __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_4 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__info); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__info); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_2 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_k_tuple_102), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_k_tuple_102), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __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;
@@ -37983,7 +38051,7 @@ static PyObject *__pyx_pw_3_sa_7Sampler_3sample(PyObject *__pyx_v_self, PyObject
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("sample (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_phrase_location), __pyx_ptype_3_sa_PhraseLocation, 1, "phrase_location", 0))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_phrase_location), __pyx_ptype_3_sa_PhraseLocation, 1, "phrase_location", 0))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_r = __pyx_pf_3_sa_7Sampler_2sample(((struct __pyx_obj_3_sa_Sampler *)__pyx_v_self), ((struct __pyx_obj_3_sa_PhraseLocation *)__pyx_v_phrase_location));
   goto __pyx_L0;
   __pyx_L1_error:;
@@ -37993,7 +38061,7 @@ static PyObject *__pyx_pw_3_sa_7Sampler_3sample(PyObject *__pyx_v_self, PyObject
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":119
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":121
  *             logger.info("Sampling strategy: no sampling")
  * 
  *     def sample(self, PhraseLocation phrase_location):             # <<<<<<<<<<<<<<
@@ -38020,19 +38088,19 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("sample", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":132
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":134
  *         cdef int num_locations, val, j
  * 
  *         sample = IntList()             # <<<<<<<<<<<<<<
  *         if phrase_location.arr is None:
  *             num_locations = phrase_location.sa_high - phrase_location.sa_low
  */
-  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_sample = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":133
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":135
  * 
  *         sample = IntList()
  *         if phrase_location.arr is None:             # <<<<<<<<<<<<<<
@@ -38042,7 +38110,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
   __pyx_t_2 = (((PyObject *)__pyx_v_phrase_location->arr) == Py_None);
   if (__pyx_t_2) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":134
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":136
  *         sample = IntList()
  *         if phrase_location.arr is None:
  *             num_locations = phrase_location.sa_high - phrase_location.sa_low             # <<<<<<<<<<<<<<
@@ -38051,7 +38119,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
  */
     __pyx_v_num_locations = (__pyx_v_phrase_location->sa_high - __pyx_v_phrase_location->sa_low);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":135
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":137
  *         if phrase_location.arr is None:
  *             num_locations = phrase_location.sa_high - phrase_location.sa_low
  *             if self.sample_size == -1 or num_locations <= self.sample_size:             # <<<<<<<<<<<<<<
@@ -38067,7 +38135,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
     }
     if (__pyx_t_4) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":136
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":138
  *             num_locations = phrase_location.sa_high - phrase_location.sa_low
  *             if self.sample_size == -1 or num_locations <= self.sample_size:
  *                 sample._extend_arr(self.sa.arr + phrase_location.sa_low, num_locations)             # <<<<<<<<<<<<<<
@@ -38079,7 +38147,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
     }
     /*else*/ {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":138
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":140
  *                 sample._extend_arr(self.sa.arr + phrase_location.sa_low, num_locations)
  *             else:
  *                 stepsize = float(num_locations)/float(self.sample_size)             # <<<<<<<<<<<<<<
@@ -38088,11 +38156,11 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
  */
       if (unlikely(((double)__pyx_v_self->sample_size) == 0)) {
         PyErr_Format(PyExc_ZeroDivisionError, "float division");
-        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       }
       __pyx_v_stepsize = (((double)__pyx_v_num_locations) / ((double)__pyx_v_self->sample_size));
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":139
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":141
  *             else:
  *                 stepsize = float(num_locations)/float(self.sample_size)
  *                 i = phrase_location.sa_low             # <<<<<<<<<<<<<<
@@ -38101,7 +38169,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
  */
       __pyx_v_i = __pyx_v_phrase_location->sa_low;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":140
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":142
  *                 stepsize = float(num_locations)/float(self.sample_size)
  *                 i = phrase_location.sa_low
  *                 while i < phrase_location.sa_high and sample.len < self.sample_size:             # <<<<<<<<<<<<<<
@@ -38118,7 +38186,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
         }
         if (!__pyx_t_3) break;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":143
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":145
  *                     '''Note: int(i) not guaranteed to have the desired
  *                     effect, according to the python documentation'''
  *                     if fmod(i,1.0) > 0.5:             # <<<<<<<<<<<<<<
@@ -38128,7 +38196,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
         __pyx_t_3 = (fmod(__pyx_v_i, 1.0) > 0.5);
         if (__pyx_t_3) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":144
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":146
  *                     effect, according to the python documentation'''
  *                     if fmod(i,1.0) > 0.5:
  *                         val = int(ceil(i))             # <<<<<<<<<<<<<<
@@ -38140,7 +38208,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
         }
         /*else*/ {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":146
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":148
  *                         val = int(ceil(i))
  *                     else:
  *                         val = int(floor(i))             # <<<<<<<<<<<<<<
@@ -38151,7 +38219,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
         }
         __pyx_L7:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":147
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":149
  *                     else:
  *                         val = int(floor(i))
  *                     sample._append(self.sa.arr[val])             # <<<<<<<<<<<<<<
@@ -38160,7 +38228,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
  */
         ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_sample->__pyx_vtab)->_append(__pyx_v_sample, (__pyx_v_self->sa->arr[__pyx_v_val]));
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":148
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":150
  *                         val = int(floor(i))
  *                     sample._append(self.sa.arr[val])
  *                     i = i + stepsize             # <<<<<<<<<<<<<<
@@ -38175,7 +38243,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":150
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":152
  *                     i = i + stepsize
  *         else:
  *             num_locations = (phrase_location.arr_high - phrase_location.arr_low) / phrase_location.num_subpatterns             # <<<<<<<<<<<<<<
@@ -38185,15 +38253,15 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
     __pyx_t_5 = (__pyx_v_phrase_location->arr_high - __pyx_v_phrase_location->arr_low);
     if (unlikely(__pyx_v_phrase_location->num_subpatterns == 0)) {
       PyErr_Format(PyExc_ZeroDivisionError, "integer division or modulo by zero");
-      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     }
     else if (sizeof(int) == sizeof(long) && unlikely(__pyx_v_phrase_location->num_subpatterns == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_t_5))) {
       PyErr_Format(PyExc_OverflowError, "value too large to perform division");
-      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     }
     __pyx_v_num_locations = __Pyx_div_int(__pyx_t_5, __pyx_v_phrase_location->num_subpatterns);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":151
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":153
  *         else:
  *             num_locations = (phrase_location.arr_high - phrase_location.arr_low) / phrase_location.num_subpatterns
  *             if self.sample_size == -1 or num_locations <= self.sample_size:             # <<<<<<<<<<<<<<
@@ -38209,7 +38277,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
     }
     if (__pyx_t_2) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":152
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":154
  *             num_locations = (phrase_location.arr_high - phrase_location.arr_low) / phrase_location.num_subpatterns
  *             if self.sample_size == -1 or num_locations <= self.sample_size:
  *                 sample = phrase_location.arr             # <<<<<<<<<<<<<<
@@ -38223,7 +38291,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
     }
     /*else*/ {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":154
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":156
  *                 sample = phrase_location.arr
  *             else:
  *                 stepsize = float(num_locations)/float(self.sample_size)             # <<<<<<<<<<<<<<
@@ -38232,11 +38300,11 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
  */
       if (unlikely(((double)__pyx_v_self->sample_size) == 0)) {
         PyErr_Format(PyExc_ZeroDivisionError, "float division");
-        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       }
       __pyx_v_stepsize = (((double)__pyx_v_num_locations) / ((double)__pyx_v_self->sample_size));
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":155
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":157
  *             else:
  *                 stepsize = float(num_locations)/float(self.sample_size)
  *                 i = phrase_location.arr_low             # <<<<<<<<<<<<<<
@@ -38245,7 +38313,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
  */
       __pyx_v_i = __pyx_v_phrase_location->arr_low;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":156
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":158
  *                 stepsize = float(num_locations)/float(self.sample_size)
  *                 i = phrase_location.arr_low
  *                 while i < num_locations and sample.len < self.sample_size * phrase_location.num_subpatterns:             # <<<<<<<<<<<<<<
@@ -38262,7 +38330,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
         }
         if (!__pyx_t_4) break;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":159
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":161
  *                     '''Note: int(i) not guaranteed to have the desired
  *                     effect, according to the python documentation'''
  *                     if fmod(i,1.0) > 0.5:             # <<<<<<<<<<<<<<
@@ -38272,7 +38340,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
         __pyx_t_4 = (fmod(__pyx_v_i, 1.0) > 0.5);
         if (__pyx_t_4) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":160
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":162
  *                     effect, according to the python documentation'''
  *                     if fmod(i,1.0) > 0.5:
  *                         val = int(ceil(i))             # <<<<<<<<<<<<<<
@@ -38284,7 +38352,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
         }
         /*else*/ {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":162
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":164
  *                         val = int(ceil(i))
  *                     else:
  *                         val = int(floor(i))             # <<<<<<<<<<<<<<
@@ -38295,7 +38363,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
         }
         __pyx_L11:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":163
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":165
  *                     else:
  *                         val = int(floor(i))
  *                     j = phrase_location.arr_low + (val*phrase_location.num_subpatterns)             # <<<<<<<<<<<<<<
@@ -38304,7 +38372,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
  */
         __pyx_v_j = (__pyx_v_phrase_location->arr_low + (__pyx_v_val * __pyx_v_phrase_location->num_subpatterns));
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":164
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":166
  *                         val = int(floor(i))
  *                     j = phrase_location.arr_low + (val*phrase_location.num_subpatterns)
  *                     sample._extend_arr(phrase_location.arr.arr + j, phrase_location.num_subpatterns)             # <<<<<<<<<<<<<<
@@ -38313,7 +38381,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
  */
         ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_sample->__pyx_vtab)->_extend_arr(__pyx_v_sample, (__pyx_v_phrase_location->arr->arr + __pyx_v_j), __pyx_v_phrase_location->num_subpatterns);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":165
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":167
  *                     j = phrase_location.arr_low + (val*phrase_location.num_subpatterns)
  *                     sample._extend_arr(phrase_location.arr.arr + j, phrase_location.num_subpatterns)
  *                     i = i + stepsize             # <<<<<<<<<<<<<<
@@ -38327,7 +38395,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":166
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":168
  *                     sample._extend_arr(phrase_location.arr.arr + j, phrase_location.num_subpatterns)
  *                     i = i + stepsize
  *         return sample             # <<<<<<<<<<<<<<
@@ -38352,7 +38420,7 @@ static PyObject *__pyx_pf_3_sa_7Sampler_2sample(struct __pyx_obj_3_sa_Sampler *_
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":178
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":180
  * 
  * 
  * cdef void assign_matching(Matching* m, int* arr, int start, int step, int* sent_id_arr):             # <<<<<<<<<<<<<<
@@ -38364,7 +38432,7 @@ static void __pyx_f_3_sa_assign_matching(struct __pyx_t_3_sa_Matching *__pyx_v_m
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("assign_matching", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":179
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":181
  * 
  * cdef void assign_matching(Matching* m, int* arr, int start, int step, int* sent_id_arr):
  *     m.arr = arr             # <<<<<<<<<<<<<<
@@ -38373,7 +38441,7 @@ static void __pyx_f_3_sa_assign_matching(struct __pyx_t_3_sa_Matching *__pyx_v_m
  */
   __pyx_v_m->arr = __pyx_v_arr;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":180
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":182
  * cdef void assign_matching(Matching* m, int* arr, int start, int step, int* sent_id_arr):
  *     m.arr = arr
  *     m.start = start             # <<<<<<<<<<<<<<
@@ -38382,7 +38450,7 @@ static void __pyx_f_3_sa_assign_matching(struct __pyx_t_3_sa_Matching *__pyx_v_m
  */
   __pyx_v_m->start = __pyx_v_start;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":181
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":183
  *     m.arr = arr
  *     m.start = start
  *     m.end = start + step             # <<<<<<<<<<<<<<
@@ -38391,7 +38459,7 @@ static void __pyx_f_3_sa_assign_matching(struct __pyx_t_3_sa_Matching *__pyx_v_m
  */
   __pyx_v_m->end = (__pyx_v_start + __pyx_v_step);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":182
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":184
  *     m.start = start
  *     m.end = start + step
  *     m.sent_id = sent_id_arr[arr[start]]             # <<<<<<<<<<<<<<
@@ -38400,7 +38468,7 @@ static void __pyx_f_3_sa_assign_matching(struct __pyx_t_3_sa_Matching *__pyx_v_m
  */
   __pyx_v_m->sent_id = (__pyx_v_sent_id_arr[(__pyx_v_arr[__pyx_v_start])]);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":183
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":185
  *     m.end = start + step
  *     m.sent_id = sent_id_arr[arr[start]]
  *     m.size = step             # <<<<<<<<<<<<<<
@@ -38412,7 +38480,7 @@ static void __pyx_f_3_sa_assign_matching(struct __pyx_t_3_sa_Matching *__pyx_v_m
   __Pyx_RefNannyFinishContext();
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":186
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":188
  * 
  * 
  * cdef int* append_combined_matching(int* arr, Matching* loc1, Matching* loc2,             # <<<<<<<<<<<<<<
@@ -38429,7 +38497,7 @@ static int *__pyx_f_3_sa_append_combined_matching(int *__pyx_v_arr, struct __pyx
   int __pyx_t_2;
   __Pyx_RefNannySetupContext("append_combined_matching", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":190
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":192
  *     cdef int i, new_len
  * 
  *     new_len = result_len[0] + num_subpatterns             # <<<<<<<<<<<<<<
@@ -38438,7 +38506,7 @@ static int *__pyx_f_3_sa_append_combined_matching(int *__pyx_v_arr, struct __pyx
  */
   __pyx_v_new_len = ((__pyx_v_result_len[0]) + __pyx_v_num_subpatterns);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":191
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":193
  * 
  *     new_len = result_len[0] + num_subpatterns
  *     arr = <int*> realloc(arr, new_len*sizeof(int))             # <<<<<<<<<<<<<<
@@ -38447,7 +38515,7 @@ static int *__pyx_f_3_sa_append_combined_matching(int *__pyx_v_arr, struct __pyx
  */
   __pyx_v_arr = ((int *)realloc(__pyx_v_arr, (__pyx_v_new_len * (sizeof(int)))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":193
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":195
  *     arr = <int*> realloc(arr, new_len*sizeof(int))
  * 
  *     for i from 0 <= i < loc1.size:             # <<<<<<<<<<<<<<
@@ -38457,7 +38525,7 @@ static int *__pyx_f_3_sa_append_combined_matching(int *__pyx_v_arr, struct __pyx
   __pyx_t_1 = __pyx_v_loc1->size;
   for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_1; __pyx_v_i++) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":194
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":196
  * 
  *     for i from 0 <= i < loc1.size:
  *         arr[result_len[0]+i] = loc1.arr[loc1.start+i]             # <<<<<<<<<<<<<<
@@ -38467,7 +38535,7 @@ static int *__pyx_f_3_sa_append_combined_matching(int *__pyx_v_arr, struct __pyx
     (__pyx_v_arr[((__pyx_v_result_len[0]) + __pyx_v_i)]) = (__pyx_v_loc1->arr[(__pyx_v_loc1->start + __pyx_v_i)]);
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":195
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":197
  *     for i from 0 <= i < loc1.size:
  *         arr[result_len[0]+i] = loc1.arr[loc1.start+i]
  *     if num_subpatterns > loc1.size:             # <<<<<<<<<<<<<<
@@ -38477,7 +38545,7 @@ static int *__pyx_f_3_sa_append_combined_matching(int *__pyx_v_arr, struct __pyx
   __pyx_t_2 = (__pyx_v_num_subpatterns > __pyx_v_loc1->size);
   if (__pyx_t_2) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":196
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":198
  *         arr[result_len[0]+i] = loc1.arr[loc1.start+i]
  *     if num_subpatterns > loc1.size:
  *         arr[new_len-1] = loc2.arr[loc2.end-1]             # <<<<<<<<<<<<<<
@@ -38489,7 +38557,7 @@ static int *__pyx_f_3_sa_append_combined_matching(int *__pyx_v_arr, struct __pyx
   }
   __pyx_L5:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":197
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":199
  *     if num_subpatterns > loc1.size:
  *         arr[new_len-1] = loc2.arr[loc2.end-1]
  *     result_len[0] = new_len             # <<<<<<<<<<<<<<
@@ -38498,7 +38566,7 @@ static int *__pyx_f_3_sa_append_combined_matching(int *__pyx_v_arr, struct __pyx
  */
   (__pyx_v_result_len[0]) = __pyx_v_new_len;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":198
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":200
  *         arr[new_len-1] = loc2.arr[loc2.end-1]
  *     result_len[0] = new_len
  *     return arr             # <<<<<<<<<<<<<<
@@ -38514,7 +38582,7 @@ static int *__pyx_f_3_sa_append_combined_matching(int *__pyx_v_arr, struct __pyx
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":201
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":203
  * 
  * 
  * cdef int* extend_arr(int* arr, int* arr_len, int* appendix, int appendix_len):             # <<<<<<<<<<<<<<
@@ -38528,7 +38596,7 @@ static int *__pyx_f_3_sa_extend_arr(int *__pyx_v_arr, int *__pyx_v_arr_len, int
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("extend_arr", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":204
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":206
  *     cdef int new_len
  * 
  *     new_len = arr_len[0] + appendix_len             # <<<<<<<<<<<<<<
@@ -38537,7 +38605,7 @@ static int *__pyx_f_3_sa_extend_arr(int *__pyx_v_arr, int *__pyx_v_arr_len, int
  */
   __pyx_v_new_len = ((__pyx_v_arr_len[0]) + __pyx_v_appendix_len);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":205
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":207
  * 
  *     new_len = arr_len[0] + appendix_len
  *     arr = <int*> realloc(arr, new_len*sizeof(int))             # <<<<<<<<<<<<<<
@@ -38546,7 +38614,7 @@ static int *__pyx_f_3_sa_extend_arr(int *__pyx_v_arr, int *__pyx_v_arr_len, int
  */
   __pyx_v_arr = ((int *)realloc(__pyx_v_arr, (__pyx_v_new_len * (sizeof(int)))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":206
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":208
  *     new_len = arr_len[0] + appendix_len
  *     arr = <int*> realloc(arr, new_len*sizeof(int))
  *     memcpy(arr+arr_len[0], appendix, appendix_len*sizeof(int))             # <<<<<<<<<<<<<<
@@ -38555,7 +38623,7 @@ static int *__pyx_f_3_sa_extend_arr(int *__pyx_v_arr, int *__pyx_v_arr_len, int
  */
   memcpy((__pyx_v_arr + (__pyx_v_arr_len[0])), __pyx_v_appendix, (__pyx_v_appendix_len * (sizeof(int))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":207
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":209
  *     arr = <int*> realloc(arr, new_len*sizeof(int))
  *     memcpy(arr+arr_len[0], appendix, appendix_len*sizeof(int))
  *     arr_len[0] = new_len             # <<<<<<<<<<<<<<
@@ -38564,7 +38632,7 @@ static int *__pyx_f_3_sa_extend_arr(int *__pyx_v_arr, int *__pyx_v_arr_len, int
  */
   (__pyx_v_arr_len[0]) = __pyx_v_new_len;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":208
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":210
  *     memcpy(arr+arr_len[0], appendix, appendix_len*sizeof(int))
  *     arr_len[0] = new_len
  *     return arr             # <<<<<<<<<<<<<<
@@ -38580,7 +38648,7 @@ static int *__pyx_f_3_sa_extend_arr(int *__pyx_v_arr, int *__pyx_v_arr_len, int
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":210
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":212
  *     return arr
  * 
  * cdef int median(int low, int high, int step):             # <<<<<<<<<<<<<<
@@ -38597,7 +38665,7 @@ static int __pyx_f_3_sa_median(int __pyx_v_low, int __pyx_v_high, int __pyx_v_st
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("median", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":211
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":213
  * 
  * cdef int median(int low, int high, int step):
  *     return low + (((high - low)/step)/2)*step             # <<<<<<<<<<<<<<
@@ -38607,11 +38675,11 @@ static int __pyx_f_3_sa_median(int __pyx_v_low, int __pyx_v_high, int __pyx_v_st
   __pyx_t_1 = (__pyx_v_high - __pyx_v_low);
   if (unlikely(__pyx_v_step == 0)) {
     PyErr_Format(PyExc_ZeroDivisionError, "integer division or modulo by zero");
-    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 211; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 213; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   else if (sizeof(int) == sizeof(long) && unlikely(__pyx_v_step == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_t_1))) {
     PyErr_Format(PyExc_OverflowError, "value too large to perform division");
-    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 211; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 213; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __pyx_r = (__pyx_v_low + (__Pyx_div_long(__Pyx_div_int(__pyx_t_1, __pyx_v_step), 2) * __pyx_v_step));
   goto __pyx_L0;
@@ -38626,7 +38694,7 @@ static int __pyx_f_3_sa_median(int __pyx_v_low, int __pyx_v_high, int __pyx_v_st
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":214
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":216
  * 
  * 
  * cdef void find_comparable_matchings(int low, int high, int* arr, int step, int loc, int* loc_minus, int* loc_plus):             # <<<<<<<<<<<<<<
@@ -38641,7 +38709,7 @@ static void __pyx_f_3_sa_find_comparable_matchings(int __pyx_v_low, int __pyx_v_
   int __pyx_t_3;
   __Pyx_RefNannySetupContext("find_comparable_matchings", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":218
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":220
  *     # in which all matchings have the same first index as the one
  *     # starting at loc
  *     loc_plus[0] = loc + step             # <<<<<<<<<<<<<<
@@ -38650,7 +38718,7 @@ static void __pyx_f_3_sa_find_comparable_matchings(int __pyx_v_low, int __pyx_v_
  */
   (__pyx_v_loc_plus[0]) = (__pyx_v_loc + __pyx_v_step);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":219
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":221
  *     # starting at loc
  *     loc_plus[0] = loc + step
  *     while loc_plus[0] < high and arr[loc_plus[0]] == arr[loc]:             # <<<<<<<<<<<<<<
@@ -38667,7 +38735,7 @@ static void __pyx_f_3_sa_find_comparable_matchings(int __pyx_v_low, int __pyx_v_
     }
     if (!__pyx_t_3) break;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":220
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":222
  *     loc_plus[0] = loc + step
  *     while loc_plus[0] < high and arr[loc_plus[0]] == arr[loc]:
  *         loc_plus[0] = loc_plus[0] + step             # <<<<<<<<<<<<<<
@@ -38677,7 +38745,7 @@ static void __pyx_f_3_sa_find_comparable_matchings(int __pyx_v_low, int __pyx_v_
     (__pyx_v_loc_plus[0]) = ((__pyx_v_loc_plus[0]) + __pyx_v_step);
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":221
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":223
  *     while loc_plus[0] < high and arr[loc_plus[0]] == arr[loc]:
  *         loc_plus[0] = loc_plus[0] + step
  *     loc_minus[0] = loc             # <<<<<<<<<<<<<<
@@ -38686,7 +38754,7 @@ static void __pyx_f_3_sa_find_comparable_matchings(int __pyx_v_low, int __pyx_v_
  */
   (__pyx_v_loc_minus[0]) = __pyx_v_loc;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":222
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":224
  *         loc_plus[0] = loc_plus[0] + step
  *     loc_minus[0] = loc
  *     while loc_minus[0]-step >= low and arr[loc_minus[0]-step] == arr[loc]:             # <<<<<<<<<<<<<<
@@ -38703,7 +38771,7 @@ static void __pyx_f_3_sa_find_comparable_matchings(int __pyx_v_low, int __pyx_v_
     }
     if (!__pyx_t_2) break;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":223
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":225
  *     loc_minus[0] = loc
  *     while loc_minus[0]-step >= low and arr[loc_minus[0]-step] == arr[loc]:
  *         loc_minus[0] = loc_minus[0] - step             # <<<<<<<<<<<<<<
@@ -38747,7 +38815,7 @@ static int __pyx_pw_3_sa_23HieroCachingRuleFactory_1__cinit__(PyObject *__pyx_v_
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__alignment,&__pyx_n_s__by_slack_factor,&__pyx_n_s__category,&__pyx_n_s__max_chunks,&__pyx_n_s__max_initial_size,&__pyx_n_s__max_length,&__pyx_n_s__max_nonterminals,&__pyx_n_s__max_target_chunks,&__pyx_n_s__max_target_length,&__pyx_n_s__min_gap_size,&__pyx_n_s__precompute_file,&__pyx_n_s_70,&__pyx_n_s__precompute_rank,&__pyx_n_s_103,&__pyx_n_s_104,&__pyx_n_s_71,&__pyx_n_s__train_min_gap_size,&__pyx_n_s__tight_phrases,&__pyx_n_s__use_baeza_yates,&__pyx_n_s__use_collocations,&__pyx_n_s__use_index,0};
     PyObject* values[21] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":293
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":295
  *             char* category="[X]",
  *             # maximum number of contiguous chunks of terminal symbols in RHS of a rule. If None, defaults to max_nonterminals+1
  *             max_chunks=None,             # <<<<<<<<<<<<<<
@@ -38756,7 +38824,7 @@ static int __pyx_pw_3_sa_23HieroCachingRuleFactory_1__cinit__(PyObject *__pyx_v_
  */
     values[3] = ((PyObject *)Py_None);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":301
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":303
  *             unsigned max_nonterminals=2,
  *             # maximum number of contiguous chunks of terminal symbols in target-side RHS of a rule. If None, defaults to max_nonterminals+1
  *             max_target_chunks=None,             # <<<<<<<<<<<<<<
@@ -38765,7 +38833,7 @@ static int __pyx_pw_3_sa_23HieroCachingRuleFactory_1__cinit__(PyObject *__pyx_v_
  */
     values[7] = ((PyObject *)Py_None);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":303
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":305
  *             max_target_chunks=None,
  *             # maximum number of target side symbols (both T and NT) allowed in a rule. If None, defaults to max_initial_size
  *             max_target_length=None,             # <<<<<<<<<<<<<<
@@ -38774,7 +38842,7 @@ static int __pyx_pw_3_sa_23HieroCachingRuleFactory_1__cinit__(PyObject *__pyx_v_
  */
     values[8] = ((PyObject *)Py_None);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":307
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":309
  *             unsigned min_gap_size=2,
  *             # filename of file containing precomputed collocations
  *             precompute_file=None,             # <<<<<<<<<<<<<<
@@ -38917,7 +38985,7 @@ static int __pyx_pw_3_sa_23HieroCachingRuleFactory_1__cinit__(PyObject *__pyx_v_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -38948,10 +39016,10 @@ static int __pyx_pw_3_sa_23HieroCachingRuleFactory_1__cinit__(PyObject *__pyx_v_
     }
     __pyx_v_alignment = ((struct __pyx_obj_3_sa_Alignment *)values[0]);
     if (values[1]) {
-      __pyx_v_by_slack_factor = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_by_slack_factor == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_by_slack_factor = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_by_slack_factor == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 291; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":289
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":291
  *             Alignment alignment,
  *             # parameter for double-binary search; doesn't seem to matter much
  *             float by_slack_factor=1.0,             # <<<<<<<<<<<<<<
@@ -38961,49 +39029,49 @@ static int __pyx_pw_3_sa_23HieroCachingRuleFactory_1__cinit__(PyObject *__pyx_v_
       __pyx_v_by_slack_factor = ((float)1.0);
     }
     if (values[2]) {
-      __pyx_v_category = PyBytes_AsString(values[2]); if (unlikely((!__pyx_v_category) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 291; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_category = PyBytes_AsString(values[2]); if (unlikely((!__pyx_v_category) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
       __pyx_v_category = ((char *)__pyx_k_105);
     }
     __pyx_v_max_chunks = values[3];
     if (values[4]) {
-      __pyx_v_max_initial_size = __Pyx_PyInt_AsUnsignedInt(values[4]); if (unlikely((__pyx_v_max_initial_size == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 295; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_max_initial_size = __Pyx_PyInt_AsUnsignedInt(values[4]); if (unlikely((__pyx_v_max_initial_size == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
       __pyx_v_max_initial_size = ((unsigned int)10);
     }
     if (values[5]) {
-      __pyx_v_max_length = __Pyx_PyInt_AsUnsignedInt(values[5]); if (unlikely((__pyx_v_max_length == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_max_length = __Pyx_PyInt_AsUnsignedInt(values[5]); if (unlikely((__pyx_v_max_length == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
       __pyx_v_max_length = ((unsigned int)5);
     }
     if (values[6]) {
-      __pyx_v_max_nonterminals = __Pyx_PyInt_AsUnsignedInt(values[6]); if (unlikely((__pyx_v_max_nonterminals == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_max_nonterminals = __Pyx_PyInt_AsUnsignedInt(values[6]); if (unlikely((__pyx_v_max_nonterminals == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 301; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
       __pyx_v_max_nonterminals = ((unsigned int)2);
     }
     __pyx_v_max_target_chunks = values[7];
     __pyx_v_max_target_length = values[8];
     if (values[9]) {
-      __pyx_v_min_gap_size = __Pyx_PyInt_AsUnsignedInt(values[9]); if (unlikely((__pyx_v_min_gap_size == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_min_gap_size = __Pyx_PyInt_AsUnsignedInt(values[9]); if (unlikely((__pyx_v_min_gap_size == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 307; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
       __pyx_v_min_gap_size = ((unsigned int)2);
     }
     __pyx_v_precompute_file = values[10];
     if (values[11]) {
-      __pyx_v_precompute_secondary_rank = __Pyx_PyInt_AsUnsignedInt(values[11]); if (unlikely((__pyx_v_precompute_secondary_rank == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_precompute_secondary_rank = __Pyx_PyInt_AsUnsignedInt(values[11]); if (unlikely((__pyx_v_precompute_secondary_rank == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
       __pyx_v_precompute_secondary_rank = ((unsigned int)20);
     }
     if (values[12]) {
-      __pyx_v_precompute_rank = __Pyx_PyInt_AsUnsignedInt(values[12]); if (unlikely((__pyx_v_precompute_rank == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_precompute_rank = __Pyx_PyInt_AsUnsignedInt(values[12]); if (unlikely((__pyx_v_precompute_rank == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 313; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
       __pyx_v_precompute_rank = ((unsigned int)100);
     }
     if (values[13]) {
-      __pyx_v_require_aligned_terminal = __Pyx_PyObject_IsTrue(values[13]); if (unlikely((__pyx_v_require_aligned_terminal == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 313; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_require_aligned_terminal = __Pyx_PyObject_IsTrue(values[13]); if (unlikely((__pyx_v_require_aligned_terminal == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":313
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":315
  *             unsigned precompute_rank=100,
  *             # require extracted rules to have at least one aligned word
  *             bint require_aligned_terminal=True,             # <<<<<<<<<<<<<<
@@ -39013,10 +39081,10 @@ static int __pyx_pw_3_sa_23HieroCachingRuleFactory_1__cinit__(PyObject *__pyx_v_
       __pyx_v_require_aligned_terminal = ((int)1);
     }
     if (values[14]) {
-      __pyx_v_require_aligned_chunks = __Pyx_PyObject_IsTrue(values[14]); if (unlikely((__pyx_v_require_aligned_chunks == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_require_aligned_chunks = __Pyx_PyObject_IsTrue(values[14]); if (unlikely((__pyx_v_require_aligned_chunks == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":315
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":317
  *             bint require_aligned_terminal=True,
  *             # require each contiguous chunk of extracted rules to have at least one aligned word
  *             bint require_aligned_chunks=False,             # <<<<<<<<<<<<<<
@@ -39026,20 +39094,20 @@ static int __pyx_pw_3_sa_23HieroCachingRuleFactory_1__cinit__(PyObject *__pyx_v_
       __pyx_v_require_aligned_chunks = ((int)0);
     }
     if (values[15]) {
-      __pyx_v_train_max_initial_size = __Pyx_PyInt_AsUnsignedInt(values[15]); if (unlikely((__pyx_v_train_max_initial_size == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_train_max_initial_size = __Pyx_PyInt_AsUnsignedInt(values[15]); if (unlikely((__pyx_v_train_max_initial_size == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 319; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
       __pyx_v_train_max_initial_size = ((unsigned int)10);
     }
     if (values[16]) {
-      __pyx_v_train_min_gap_size = __Pyx_PyInt_AsUnsignedInt(values[16]); if (unlikely((__pyx_v_train_min_gap_size == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 319; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_train_min_gap_size = __Pyx_PyInt_AsUnsignedInt(values[16]); if (unlikely((__pyx_v_train_min_gap_size == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
       __pyx_v_train_min_gap_size = ((unsigned int)2);
     }
     if (values[17]) {
-      __pyx_v_tight_phrases = __Pyx_PyObject_IsTrue(values[17]); if (unlikely((__pyx_v_tight_phrases == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_tight_phrases = __Pyx_PyObject_IsTrue(values[17]); if (unlikely((__pyx_v_tight_phrases == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":321
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":323
  *             unsigned train_min_gap_size=2,
  *             # False if phrases should be loose (better but slower), True otherwise
  *             bint tight_phrases=True,             # <<<<<<<<<<<<<<
@@ -39049,10 +39117,10 @@ static int __pyx_pw_3_sa_23HieroCachingRuleFactory_1__cinit__(PyObject *__pyx_v_
       __pyx_v_tight_phrases = ((int)1);
     }
     if (values[18]) {
-      __pyx_v_use_baeza_yates = __Pyx_PyObject_IsTrue(values[18]); if (unlikely((__pyx_v_use_baeza_yates == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_use_baeza_yates = __Pyx_PyObject_IsTrue(values[18]); if (unlikely((__pyx_v_use_baeza_yates == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":323
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":325
  *             bint tight_phrases=True,
  *             # True to require use of double-binary alg, false otherwise
  *             bint use_baeza_yates=True,             # <<<<<<<<<<<<<<
@@ -39062,10 +39130,10 @@ static int __pyx_pw_3_sa_23HieroCachingRuleFactory_1__cinit__(PyObject *__pyx_v_
       __pyx_v_use_baeza_yates = ((int)1);
     }
     if (values[19]) {
-      __pyx_v_use_collocations = __Pyx_PyObject_IsTrue(values[19]); if (unlikely((__pyx_v_use_collocations == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_use_collocations = __Pyx_PyObject_IsTrue(values[19]); if (unlikely((__pyx_v_use_collocations == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":325
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":327
  *             bint use_baeza_yates=True,
  *             # True to enable used of precomputed collocations
  *             bint use_collocations=True,             # <<<<<<<<<<<<<<
@@ -39075,10 +39143,10 @@ static int __pyx_pw_3_sa_23HieroCachingRuleFactory_1__cinit__(PyObject *__pyx_v_
       __pyx_v_use_collocations = ((int)1);
     }
     if (values[20]) {
-      __pyx_v_use_index = __Pyx_PyObject_IsTrue(values[20]); if (unlikely((__pyx_v_use_index == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_use_index = __Pyx_PyObject_IsTrue(values[20]); if (unlikely((__pyx_v_use_index == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":327
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":329
  *             bint use_collocations=True,
  *             # True to enable use of precomputed inverted indices
  *             bint use_index=True):             # <<<<<<<<<<<<<<
@@ -39090,13 +39158,13 @@ static int __pyx_pw_3_sa_23HieroCachingRuleFactory_1__cinit__(PyObject *__pyx_v_
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 1, 21, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 1, 21, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return -1;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_alignment), __pyx_ptype_3_sa_Alignment, 1, "alignment", 0))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_alignment), __pyx_ptype_3_sa_Alignment, 1, "alignment", 0))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_r = __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(((struct __pyx_obj_3_sa_HieroCachingRuleFactory *)__pyx_v_self), __pyx_v_alignment, __pyx_v_by_slack_factor, __pyx_v_category, __pyx_v_max_chunks, __pyx_v_max_initial_size, __pyx_v_max_length, __pyx_v_max_nonterminals, __pyx_v_max_target_chunks, __pyx_v_max_target_length, __pyx_v_min_gap_size, __pyx_v_precompute_file, __pyx_v_precompute_secondary_rank, __pyx_v_precompute_rank, __pyx_v_require_aligned_terminal, __pyx_v_require_aligned_chunks, __pyx_v_train_max_initial_size, __pyx_v_train_min_gap_size, __pyx_v_tight_phrases, __pyx_v_use_baeza_yates, __pyx_v_use_collocations, __pyx_v_use_index);
   goto __pyx_L0;
   __pyx_L1_error:;
@@ -39118,7 +39186,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_9__cinit___lambda1(PyOb
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":403
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":405
  *         self.phrases_f = defaultdict(int)
  *         self.phrases_e = defaultdict(int)
  *         self.phrases_fe = defaultdict(lambda: defaultdict(int))             # <<<<<<<<<<<<<<
@@ -39137,14 +39205,14 @@ static PyObject *__pyx_lambda_funcdef_lambda1(CYTHON_UNUSED PyObject *__pyx_self
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("lambda1", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_INCREF(((PyObject *)((PyObject*)(&PyInt_Type))));
   PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)((PyObject*)(&PyInt_Type))));
   __Pyx_GIVEREF(((PyObject *)((PyObject*)(&PyInt_Type))));
-  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
@@ -39178,7 +39246,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_9__cinit___1lambda2(PyO
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":404
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":406
  *         self.phrases_e = defaultdict(int)
  *         self.phrases_fe = defaultdict(lambda: defaultdict(int))
  *         self.phrases_al = defaultdict(lambda: defaultdict(tuple))             # <<<<<<<<<<<<<<
@@ -39197,14 +39265,14 @@ static PyObject *__pyx_lambda_funcdef_lambda2(CYTHON_UNUSED PyObject *__pyx_self
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("lambda2", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_INCREF(((PyObject *)((PyObject*)(&PyTuple_Type))));
   PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)((PyObject*)(&PyTuple_Type))));
   __Pyx_GIVEREF(((PyObject *)((PyObject*)(&PyTuple_Type))));
-  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
@@ -39238,7 +39306,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_9__cinit___2lambda3(PyO
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":409
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":411
  *         self.bilex_f = defaultdict(int)
  *         self.bilex_e = defaultdict(int)
  *         self.bilex_fe = defaultdict(lambda: defaultdict(int))             # <<<<<<<<<<<<<<
@@ -39257,14 +39325,14 @@ static PyObject *__pyx_lambda_funcdef_lambda3(CYTHON_UNUSED PyObject *__pyx_self
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("lambda3", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_INCREF(((PyObject *)((PyObject*)(&PyInt_Type))));
   PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)((PyObject*)(&PyInt_Type))));
   __Pyx_GIVEREF(((PyObject *)((PyObject*)(&PyInt_Type))));
-  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
@@ -39286,7 +39354,7 @@ static PyObject *__pyx_lambda_funcdef_lambda3(CYTHON_UNUSED PyObject *__pyx_self
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":285
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":287
  *     cdef bilex_fe
  * 
  *     def __cinit__(self,             # <<<<<<<<<<<<<<
@@ -39307,21 +39375,21 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__cinit__", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":333
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":335
  *         respectively.    This is because Chiang's model does not require
  *         them to be the same, therefore we don't either.'''
  *         self.rules = TrieTable(True) # cache             # <<<<<<<<<<<<<<
  *         self.rules.root = ExtendedTrieNode(phrase_location=PhraseLocation())
  *         if alignment is None:
  */
-  __pyx_t_1 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 333; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 333; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_1);
   __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_TrieTable)), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 333; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_TrieTable)), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
   __Pyx_GIVEREF(__pyx_t_1);
@@ -39330,20 +39398,20 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __pyx_v_self->rules = ((struct __pyx_obj_3_sa_TrieTable *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":334
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":336
  *         them to be the same, therefore we don't either.'''
  *         self.rules = TrieTable(True) # cache
  *         self.rules.root = ExtendedTrieNode(phrase_location=PhraseLocation())             # <<<<<<<<<<<<<<
  *         if alignment is None:
  *             raise Exception("Must specify an alignment object")
  */
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 336; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_PhraseLocation)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_PhraseLocation)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 336; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__phrase_location), __pyx_t_2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__phrase_location), __pyx_t_2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 336; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_ExtendedTrieNode)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_ExtendedTrieNode)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 336; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
   __Pyx_GIVEREF(__pyx_t_2);
@@ -39352,7 +39420,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __pyx_v_self->rules->root = __pyx_t_2;
   __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":335
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":337
  *         self.rules = TrieTable(True) # cache
  *         self.rules.root = ExtendedTrieNode(phrase_location=PhraseLocation())
  *         if alignment is None:             # <<<<<<<<<<<<<<
@@ -39362,23 +39430,23 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __pyx_t_3 = (((PyObject *)__pyx_v_alignment) == Py_None);
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":336
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":338
  *         self.rules.root = ExtendedTrieNode(phrase_location=PhraseLocation())
  *         if alignment is None:
  *             raise Exception("Must specify an alignment object")             # <<<<<<<<<<<<<<
  *         self.alignment = alignment
  * 
  */
-    __pyx_t_2 = PyObject_Call(__pyx_builtin_Exception, ((PyObject *)__pyx_k_tuple_107), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 336; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyObject_Call(__pyx_builtin_Exception, ((PyObject *)__pyx_k_tuple_107), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 338; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 336; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 338; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     goto __pyx_L3;
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":337
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":339
  *         if alignment is None:
  *             raise Exception("Must specify an alignment object")
  *         self.alignment = alignment             # <<<<<<<<<<<<<<
@@ -39391,7 +39459,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __Pyx_DECREF(((PyObject *)__pyx_v_self->alignment));
   __pyx_v_self->alignment = __pyx_v_alignment;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":341
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":343
  *         # grammar parameters and settings
  *         # NOTE: setting max_nonterminals > 2 is not currently supported in Hiero
  *         self.max_length = max_length             # <<<<<<<<<<<<<<
@@ -39400,7 +39468,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   __pyx_v_self->max_length = __pyx_v_max_length;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":342
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":344
  *         # NOTE: setting max_nonterminals > 2 is not currently supported in Hiero
  *         self.max_length = max_length
  *         self.max_nonterminals = max_nonterminals             # <<<<<<<<<<<<<<
@@ -39409,7 +39477,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   __pyx_v_self->max_nonterminals = __pyx_v_max_nonterminals;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":343
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":345
  *         self.max_length = max_length
  *         self.max_nonterminals = max_nonterminals
  *         self.max_initial_size = max_initial_size             # <<<<<<<<<<<<<<
@@ -39418,7 +39486,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   __pyx_v_self->max_initial_size = __pyx_v_max_initial_size;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":344
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":346
  *         self.max_nonterminals = max_nonterminals
  *         self.max_initial_size = max_initial_size
  *         self.train_max_initial_size = train_max_initial_size             # <<<<<<<<<<<<<<
@@ -39427,7 +39495,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   __pyx_v_self->train_max_initial_size = __pyx_v_train_max_initial_size;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":345
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":347
  *         self.max_initial_size = max_initial_size
  *         self.train_max_initial_size = train_max_initial_size
  *         self.min_gap_size = min_gap_size             # <<<<<<<<<<<<<<
@@ -39436,7 +39504,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   __pyx_v_self->min_gap_size = __pyx_v_min_gap_size;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":346
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":348
  *         self.train_max_initial_size = train_max_initial_size
  *         self.min_gap_size = min_gap_size
  *         self.train_min_gap_size = train_min_gap_size             # <<<<<<<<<<<<<<
@@ -39445,7 +39513,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   __pyx_v_self->train_min_gap_size = __pyx_v_train_min_gap_size;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":347
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":349
  *         self.min_gap_size = min_gap_size
  *         self.train_min_gap_size = train_min_gap_size
  *         self.category = sym_fromstring(category, False)             # <<<<<<<<<<<<<<
@@ -39454,7 +39522,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   __pyx_v_self->category = __pyx_f_3_sa_sym_fromstring(__pyx_v_category, 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":349
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":351
  *         self.category = sym_fromstring(category, False)
  * 
  *         if max_chunks is None:             # <<<<<<<<<<<<<<
@@ -39464,7 +39532,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __pyx_t_3 = (__pyx_v_max_chunks == Py_None);
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":350
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":352
  * 
  *         if max_chunks is None:
  *             self.max_chunks = self.max_nonterminals + 1             # <<<<<<<<<<<<<<
@@ -39476,19 +39544,19 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":352
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":354
  *             self.max_chunks = self.max_nonterminals + 1
  *         else:
  *             self.max_chunks = max_chunks             # <<<<<<<<<<<<<<
  * 
  *         if max_target_chunks is None:
  */
-    __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_v_max_chunks); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_v_max_chunks); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 354; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __pyx_v_self->max_chunks = __pyx_t_4;
   }
   __pyx_L4:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":354
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":356
  *             self.max_chunks = max_chunks
  * 
  *         if max_target_chunks is None:             # <<<<<<<<<<<<<<
@@ -39498,7 +39566,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __pyx_t_3 = (__pyx_v_max_target_chunks == Py_None);
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":355
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":357
  * 
  *         if max_target_chunks is None:
  *             self.max_target_chunks = self.max_nonterminals + 1             # <<<<<<<<<<<<<<
@@ -39510,19 +39578,19 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":357
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":359
  *             self.max_target_chunks = self.max_nonterminals + 1
  *         else:
  *             self.max_target_chunks = max_target_chunks             # <<<<<<<<<<<<<<
  * 
  *         if max_target_length is None:
  */
-    __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_v_max_target_chunks); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_v_max_target_chunks); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 359; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __pyx_v_self->max_target_chunks = __pyx_t_4;
   }
   __pyx_L5:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":359
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":361
  *             self.max_target_chunks = max_target_chunks
  * 
  *         if max_target_length is None:             # <<<<<<<<<<<<<<
@@ -39532,7 +39600,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __pyx_t_3 = (__pyx_v_max_target_length == Py_None);
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":360
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":362
  * 
  *         if max_target_length is None:
  *             self.max_target_length = max_initial_size             # <<<<<<<<<<<<<<
@@ -39544,26 +39612,26 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":362
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":364
  *             self.max_target_length = max_initial_size
  *         else:
  *             self.max_target_length = max_target_length             # <<<<<<<<<<<<<<
  * 
  *         # algorithmic parameters and settings
  */
-    __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_v_max_target_length); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 362; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_v_max_target_length); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 364; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __pyx_v_self->max_target_length = __pyx_t_4;
   }
   __pyx_L6:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":365
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":367
  * 
  *         # algorithmic parameters and settings
  *         self.precomputed_collocations = {}             # <<<<<<<<<<<<<<
  *         self.precomputed_index = {}
  *         self.use_index = use_index
  */
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 365; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_2));
   __Pyx_GIVEREF(((PyObject *)__pyx_t_2));
   __Pyx_GOTREF(__pyx_v_self->precomputed_collocations);
@@ -39571,14 +39639,14 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __pyx_v_self->precomputed_collocations = ((PyObject *)__pyx_t_2);
   __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":366
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":368
  *         # algorithmic parameters and settings
  *         self.precomputed_collocations = {}
  *         self.precomputed_index = {}             # <<<<<<<<<<<<<<
  *         self.use_index = use_index
  *         self.use_collocations = use_collocations
  */
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 366; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_2));
   __Pyx_GIVEREF(((PyObject *)__pyx_t_2));
   __Pyx_GOTREF(__pyx_v_self->precomputed_index);
@@ -39586,7 +39654,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __pyx_v_self->precomputed_index = ((PyObject *)__pyx_t_2);
   __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":367
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":369
  *         self.precomputed_collocations = {}
  *         self.precomputed_index = {}
  *         self.use_index = use_index             # <<<<<<<<<<<<<<
@@ -39595,7 +39663,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   __pyx_v_self->use_index = __pyx_v_use_index;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":368
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":370
  *         self.precomputed_index = {}
  *         self.use_index = use_index
  *         self.use_collocations = use_collocations             # <<<<<<<<<<<<<<
@@ -39604,14 +39672,14 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   __pyx_v_self->use_collocations = __pyx_v_use_collocations;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":369
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":371
  *         self.use_index = use_index
  *         self.use_collocations = use_collocations
  *         self.max_rank = {}             # <<<<<<<<<<<<<<
  *         self.precompute_file = precompute_file
  *         self.precompute_rank = precompute_rank
  */
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 369; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 371; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_2));
   __Pyx_GIVEREF(((PyObject *)__pyx_t_2));
   __Pyx_GOTREF(__pyx_v_self->max_rank);
@@ -39619,7 +39687,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __pyx_v_self->max_rank = ((PyObject *)__pyx_t_2);
   __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":370
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":372
  *         self.use_collocations = use_collocations
  *         self.max_rank = {}
  *         self.precompute_file = precompute_file             # <<<<<<<<<<<<<<
@@ -39632,7 +39700,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __Pyx_DECREF(__pyx_v_self->precompute_file);
   __pyx_v_self->precompute_file = __pyx_v_precompute_file;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":371
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":373
  *         self.max_rank = {}
  *         self.precompute_file = precompute_file
  *         self.precompute_rank = precompute_rank             # <<<<<<<<<<<<<<
@@ -39641,7 +39709,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   __pyx_v_self->precompute_rank = __pyx_v_precompute_rank;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":372
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":374
  *         self.precompute_file = precompute_file
  *         self.precompute_rank = precompute_rank
  *         self.precompute_secondary_rank = precompute_secondary_rank             # <<<<<<<<<<<<<<
@@ -39650,7 +39718,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   __pyx_v_self->precompute_secondary_rank = __pyx_v_precompute_secondary_rank;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":373
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":375
  *         self.precompute_rank = precompute_rank
  *         self.precompute_secondary_rank = precompute_secondary_rank
  *         self.use_baeza_yates = use_baeza_yates             # <<<<<<<<<<<<<<
@@ -39659,7 +39727,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   __pyx_v_self->use_baeza_yates = __pyx_v_use_baeza_yates;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":374
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":376
  *         self.precompute_secondary_rank = precompute_secondary_rank
  *         self.use_baeza_yates = use_baeza_yates
  *         self.by_slack_factor = by_slack_factor             # <<<<<<<<<<<<<<
@@ -39668,7 +39736,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   __pyx_v_self->by_slack_factor = __pyx_v_by_slack_factor;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":375
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":377
  *         self.use_baeza_yates = use_baeza_yates
  *         self.by_slack_factor = by_slack_factor
  *         self.tight_phrases = tight_phrases             # <<<<<<<<<<<<<<
@@ -39677,7 +39745,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   __pyx_v_self->tight_phrases = __pyx_v_tight_phrases;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":377
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":379
  *         self.tight_phrases = tight_phrases
  * 
  *         if require_aligned_chunks:             # <<<<<<<<<<<<<<
@@ -39686,7 +39754,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   if (__pyx_v_require_aligned_chunks) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":379
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":381
  *         if require_aligned_chunks:
  *             # one condition is a stronger version of the other.
  *             self.require_aligned_chunks = self.require_aligned_terminal = True             # <<<<<<<<<<<<<<
@@ -39698,7 +39766,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
     goto __pyx_L7;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":380
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":382
  *             # one condition is a stronger version of the other.
  *             self.require_aligned_chunks = self.require_aligned_terminal = True
  *         elif require_aligned_terminal:             # <<<<<<<<<<<<<<
@@ -39707,7 +39775,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   if (__pyx_v_require_aligned_terminal) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":381
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":383
  *             self.require_aligned_chunks = self.require_aligned_terminal = True
  *         elif require_aligned_terminal:
  *             self.require_aligned_chunks = False             # <<<<<<<<<<<<<<
@@ -39716,7 +39784,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
     __pyx_v_self->require_aligned_chunks = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":382
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":384
  *         elif require_aligned_terminal:
  *             self.require_aligned_chunks = False
  *             self.require_aligned_terminal = True             # <<<<<<<<<<<<<<
@@ -39728,7 +39796,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":384
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":386
  *             self.require_aligned_terminal = True
  *         else:
  *             self.require_aligned_chunks = self.require_aligned_terminal = False             # <<<<<<<<<<<<<<
@@ -39740,7 +39808,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   }
   __pyx_L7:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":387
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":389
  * 
  *         # diagnostics
  *         self.prev_norm_prefix = ()             # <<<<<<<<<<<<<<
@@ -39753,17 +39821,17 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __Pyx_DECREF(__pyx_v_self->prev_norm_prefix);
   __pyx_v_self->prev_norm_prefix = ((PyObject *)__pyx_empty_tuple);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":389
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":391
  *         self.prev_norm_prefix = ()
  * 
  *         self.findexes = IntList(initial_len=10)             # <<<<<<<<<<<<<<
  *         self.findexes1 = IntList(initial_len=10)
  * 
  */
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 389; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 391; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_2));
-  if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__initial_len), __pyx_int_10) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 389; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_2)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 389; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__initial_len), __pyx_int_10) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 391; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_2)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 391; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
   __Pyx_GIVEREF(__pyx_t_1);
@@ -39772,17 +39840,17 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __pyx_v_self->findexes = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":390
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":392
  * 
  *         self.findexes = IntList(initial_len=10)
  *         self.findexes1 = IntList(initial_len=10)             # <<<<<<<<<<<<<<
  * 
  *         # Online stats
  */
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 390; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 392; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__initial_len), __pyx_int_10) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 390; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 390; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__initial_len), __pyx_int_10) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 392; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 392; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
   __Pyx_GIVEREF(__pyx_t_2);
@@ -39791,7 +39859,7 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __pyx_v_self->findexes1 = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_2);
   __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":395
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":397
  * 
  *         # True after data is added
  *         self.online = False             # <<<<<<<<<<<<<<
@@ -39800,21 +39868,21 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
  */
   __pyx_v_self->online = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":398
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":400
  * 
  *         # Keep track of everything that can be sampled:
  *         self.samples_f = defaultdict(int)             # <<<<<<<<<<<<<<
  * 
  *         # Phrase counts
  */
-  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 400; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 400; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(((PyObject *)((PyObject*)(&PyInt_Type))));
   PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)((PyObject*)(&PyInt_Type))));
   __Pyx_GIVEREF(((PyObject *)((PyObject*)(&PyInt_Type))));
-  __pyx_t_5 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 400; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
@@ -39824,21 +39892,21 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __pyx_v_self->samples_f = __pyx_t_5;
   __pyx_t_5 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":401
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":403
  * 
  *         # Phrase counts
  *         self.phrases_f = defaultdict(int)             # <<<<<<<<<<<<<<
  *         self.phrases_e = defaultdict(int)
  *         self.phrases_fe = defaultdict(lambda: defaultdict(int))
  */
-  __pyx_t_5 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 401; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 401; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(((PyObject *)((PyObject*)(&PyInt_Type))));
   PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)((PyObject*)(&PyInt_Type))));
   __Pyx_GIVEREF(((PyObject *)((PyObject*)(&PyInt_Type))));
-  __pyx_t_2 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 401; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
@@ -39848,21 +39916,21 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __pyx_v_self->phrases_f = __pyx_t_2;
   __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":402
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":404
  *         # Phrase counts
  *         self.phrases_f = defaultdict(int)
  *         self.phrases_e = defaultdict(int)             # <<<<<<<<<<<<<<
  *         self.phrases_fe = defaultdict(lambda: defaultdict(int))
  *         self.phrases_al = defaultdict(lambda: defaultdict(tuple))
  */
-  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 402; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 402; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(((PyObject *)((PyObject*)(&PyInt_Type))));
   PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)((PyObject*)(&PyInt_Type))));
   __Pyx_GIVEREF(((PyObject *)((PyObject*)(&PyInt_Type))));
-  __pyx_t_5 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 402; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
@@ -39872,23 +39940,23 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __pyx_v_self->phrases_e = __pyx_t_5;
   __pyx_t_5 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":403
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":405
  *         self.phrases_f = defaultdict(int)
  *         self.phrases_e = defaultdict(int)
  *         self.phrases_fe = defaultdict(lambda: defaultdict(int))             # <<<<<<<<<<<<<<
  *         self.phrases_al = defaultdict(lambda: defaultdict(tuple))
  * 
  */
-  __pyx_t_5 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_1 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_9__cinit___lambda1, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_9__cinit___lambda1, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_1);
   __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
@@ -39898,23 +39966,23 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __pyx_v_self->phrases_fe = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":404
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":406
  *         self.phrases_e = defaultdict(int)
  *         self.phrases_fe = defaultdict(lambda: defaultdict(int))
  *         self.phrases_al = defaultdict(lambda: defaultdict(tuple))             # <<<<<<<<<<<<<<
  * 
  *         # Bilexical counts
  */
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_9__cinit___1lambda2, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_9__cinit___1lambda2, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_5);
   PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2);
   __Pyx_GIVEREF(__pyx_t_2);
   __pyx_t_2 = 0;
-  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
@@ -39924,21 +39992,21 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __pyx_v_self->phrases_al = __pyx_t_2;
   __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":407
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":409
  * 
  *         # Bilexical counts
  *         self.bilex_f = defaultdict(int)             # <<<<<<<<<<<<<<
  *         self.bilex_e = defaultdict(int)
  *         self.bilex_fe = defaultdict(lambda: defaultdict(int))
  */
-  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_INCREF(((PyObject *)((PyObject*)(&PyInt_Type))));
   PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)((PyObject*)(&PyInt_Type))));
   __Pyx_GIVEREF(((PyObject *)((PyObject*)(&PyInt_Type))));
-  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
@@ -39948,21 +40016,21 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __pyx_v_self->bilex_f = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":408
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":410
  *         # Bilexical counts
  *         self.bilex_f = defaultdict(int)
  *         self.bilex_e = defaultdict(int)             # <<<<<<<<<<<<<<
  *         self.bilex_fe = defaultdict(lambda: defaultdict(int))
  * 
  */
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 410; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 410; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_INCREF(((PyObject *)((PyObject*)(&PyInt_Type))));
   PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)((PyObject*)(&PyInt_Type))));
   __Pyx_GIVEREF(((PyObject *)((PyObject*)(&PyInt_Type))));
-  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 410; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
@@ -39972,23 +40040,23 @@ static int __pyx_pf_3_sa_23HieroCachingRuleFactory___cinit__(struct __pyx_obj_3_
   __pyx_v_self->bilex_e = __pyx_t_2;
   __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":409
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":411
  *         self.bilex_f = defaultdict(int)
  *         self.bilex_e = defaultdict(int)
  *         self.bilex_fe = defaultdict(lambda: defaultdict(int))             # <<<<<<<<<<<<<<
  * 
  *     def configure(self, SuffixArray fsarray, DataArray edarray,
  */
-  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_5 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_9__cinit___2lambda3, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_9__cinit___2lambda3, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_5);
   __Pyx_GIVEREF(__pyx_t_5);
   __pyx_t_5 = 0;
-  __pyx_t_5 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
@@ -40044,21 +40112,21 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_3configure(PyObject *__
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__edarray)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("configure", 1, 4, 4, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("configure", 1, 4, 4, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 413; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__sampler)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("configure", 1, 4, 4, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("configure", 1, 4, 4, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 413; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  3:
         if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__scorer)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("configure", 1, 4, 4, 3); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("configure", 1, 4, 4, 3); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 413; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "configure") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "configure") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 413; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
       goto __pyx_L5_argtuple_error;
@@ -40075,16 +40143,16 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_3configure(PyObject *__
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("configure", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("configure", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 413; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.configure", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_fsarray), __pyx_ptype_3_sa_SuffixArray, 1, "fsarray", 0))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_edarray), __pyx_ptype_3_sa_DataArray, 1, "edarray", 0))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_sampler), __pyx_ptype_3_sa_Sampler, 1, "sampler", 0))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_scorer), __pyx_ptype_3_sa_Scorer, 1, "scorer", 0))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_fsarray), __pyx_ptype_3_sa_SuffixArray, 1, "fsarray", 0))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 413; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_edarray), __pyx_ptype_3_sa_DataArray, 1, "edarray", 0))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 413; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_sampler), __pyx_ptype_3_sa_Sampler, 1, "sampler", 0))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 414; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_scorer), __pyx_ptype_3_sa_Scorer, 1, "scorer", 0))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 414; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_r = __pyx_pf_3_sa_23HieroCachingRuleFactory_2configure(((struct __pyx_obj_3_sa_HieroCachingRuleFactory *)__pyx_v_self), __pyx_v_fsarray, __pyx_v_edarray, __pyx_v_sampler, __pyx_v_scorer);
   goto __pyx_L0;
   __pyx_L1_error:;
@@ -40094,7 +40162,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_3configure(PyObject *__
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":411
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":413
  *         self.bilex_fe = defaultdict(lambda: defaultdict(int))
  * 
  *     def configure(self, SuffixArray fsarray, DataArray edarray,             # <<<<<<<<<<<<<<
@@ -40112,7 +40180,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_2configure(struct __pyx
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("configure", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":416
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":418
  *         Here we also use it to precompute the most expensive intersections
  *         in the corpus quickly.'''
  *         self.fsa = fsarray             # <<<<<<<<<<<<<<
@@ -40125,7 +40193,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_2configure(struct __pyx
   __Pyx_DECREF(((PyObject *)__pyx_v_self->fsa));
   __pyx_v_self->fsa = __pyx_v_fsarray;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":417
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":419
  *         in the corpus quickly.'''
  *         self.fsa = fsarray
  *         self.fda = fsarray.darray             # <<<<<<<<<<<<<<
@@ -40138,7 +40206,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_2configure(struct __pyx
   __Pyx_DECREF(((PyObject *)__pyx_v_self->fda));
   __pyx_v_self->fda = __pyx_v_fsarray->darray;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":418
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":420
  *         self.fsa = fsarray
  *         self.fda = fsarray.darray
  *         self.eda = edarray             # <<<<<<<<<<<<<<
@@ -40151,7 +40219,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_2configure(struct __pyx
   __Pyx_DECREF(((PyObject *)__pyx_v_self->eda));
   __pyx_v_self->eda = __pyx_v_edarray;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":419
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":421
  *         self.fda = fsarray.darray
  *         self.eda = edarray
  *         self.fid2symid = self.set_idmap(self.fda)             # <<<<<<<<<<<<<<
@@ -40160,17 +40228,17 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_2configure(struct __pyx
  */
   __pyx_t_1 = ((PyObject *)__pyx_v_self->fda);
   __Pyx_INCREF(__pyx_t_1);
-  __pyx_t_2 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->set_idmap(__pyx_v_self, ((struct __pyx_obj_3_sa_DataArray *)__pyx_t_1)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->set_idmap(__pyx_v_self, ((struct __pyx_obj_3_sa_DataArray *)__pyx_t_1)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 421; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_3_sa_IntList))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_3_sa_IntList))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 421; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GIVEREF(__pyx_t_2);
   __Pyx_GOTREF(__pyx_v_self->fid2symid);
   __Pyx_DECREF(((PyObject *)__pyx_v_self->fid2symid));
   __pyx_v_self->fid2symid = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_2);
   __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":420
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":422
  *         self.eda = edarray
  *         self.fid2symid = self.set_idmap(self.fda)
  *         self.eid2symid = self.set_idmap(self.eda)             # <<<<<<<<<<<<<<
@@ -40179,31 +40247,31 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_2configure(struct __pyx
  */
   __pyx_t_2 = ((PyObject *)__pyx_v_self->eda);
   __Pyx_INCREF(__pyx_t_2);
-  __pyx_t_1 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->set_idmap(__pyx_v_self, ((struct __pyx_obj_3_sa_DataArray *)__pyx_t_2)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->set_idmap(__pyx_v_self, ((struct __pyx_obj_3_sa_DataArray *)__pyx_t_2)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 422; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_3_sa_IntList))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_3_sa_IntList))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 422; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GIVEREF(__pyx_t_1);
   __Pyx_GOTREF(__pyx_v_self->eid2symid);
   __Pyx_DECREF(((PyObject *)__pyx_v_self->eid2symid));
   __pyx_v_self->eid2symid = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":421
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":423
  *         self.fid2symid = self.set_idmap(self.fda)
  *         self.eid2symid = self.set_idmap(self.eda)
  *         self.precompute()             # <<<<<<<<<<<<<<
  *         self.sampler = sampler
  *         self.scorer = scorer
  */
-  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__precompute); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 421; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__precompute); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 423; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 421; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 423; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":422
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":424
  *         self.eid2symid = self.set_idmap(self.eda)
  *         self.precompute()
  *         self.sampler = sampler             # <<<<<<<<<<<<<<
@@ -40216,7 +40284,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_2configure(struct __pyx
   __Pyx_DECREF(((PyObject *)__pyx_v_self->sampler));
   __pyx_v_self->sampler = __pyx_v_sampler;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":423
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":425
  *         self.precompute()
  *         self.sampler = sampler
  *         self.scorer = scorer             # <<<<<<<<<<<<<<
@@ -40242,7 +40310,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_2configure(struct __pyx
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":425
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":427
  *         self.scorer = scorer
  * 
  *     cdef set_idmap(self, DataArray darray):             # <<<<<<<<<<<<<<
@@ -40267,7 +40335,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_set_idmap(CYTHON_UNUSED
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("set_idmap", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":429
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":431
  *         cdef IntList idmap
  * 
  *         N = len(darray.id2word)             # <<<<<<<<<<<<<<
@@ -40276,30 +40344,30 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_set_idmap(CYTHON_UNUSED
  */
   __pyx_t_1 = __pyx_v_darray->id2word;
   __Pyx_INCREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 431; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_v_N = __pyx_t_2;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":430
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":432
  * 
  *         N = len(darray.id2word)
  *         idmap = IntList(initial_len=N)             # <<<<<<<<<<<<<<
  *         for word_id from 0 <= word_id < N:
  *             new_word_id = sym_fromstring(darray.id2word[word_id], True)
  */
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 430; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 432; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  __pyx_t_3 = PyInt_FromLong(__pyx_v_N); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 430; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyInt_FromLong(__pyx_v_N); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 432; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__initial_len), __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 430; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__initial_len), __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 432; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 430; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 432; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
   __pyx_v_idmap = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_3);
   __pyx_t_3 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":431
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":433
  *         N = len(darray.id2word)
  *         idmap = IntList(initial_len=N)
  *         for word_id from 0 <= word_id < N:             # <<<<<<<<<<<<<<
@@ -40309,20 +40377,20 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_set_idmap(CYTHON_UNUSED
   __pyx_t_4 = __pyx_v_N;
   for (__pyx_v_word_id = 0; __pyx_v_word_id < __pyx_t_4; __pyx_v_word_id++) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":432
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":434
  *         idmap = IntList(initial_len=N)
  *         for word_id from 0 <= word_id < N:
  *             new_word_id = sym_fromstring(darray.id2word[word_id], True)             # <<<<<<<<<<<<<<
  *             idmap.arr[word_id] = new_word_id
  *         return idmap
  */
-    __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_darray->id2word, __pyx_v_word_id, sizeof(int), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 432; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_darray->id2word, __pyx_v_word_id, sizeof(int), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 434; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_5 = PyBytes_AsString(__pyx_t_3); if (unlikely((!__pyx_t_5) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 432; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyBytes_AsString(__pyx_t_3); if (unlikely((!__pyx_t_5) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 434; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __pyx_v_new_word_id = __pyx_f_3_sa_sym_fromstring(__pyx_t_5, 1);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":433
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":435
  *         for word_id from 0 <= word_id < N:
  *             new_word_id = sym_fromstring(darray.id2word[word_id], True)
  *             idmap.arr[word_id] = new_word_id             # <<<<<<<<<<<<<<
@@ -40332,7 +40400,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_set_idmap(CYTHON_UNUSED
     (__pyx_v_idmap->arr[__pyx_v_word_id]) = __pyx_v_new_word_id;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":434
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":436
  *             new_word_id = sym_fromstring(darray.id2word[word_id], True)
  *             idmap.arr[word_id] = new_word_id
  *         return idmap             # <<<<<<<<<<<<<<
@@ -40369,7 +40437,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_5pattern2phrase(PyObjec
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":437
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":439
  * 
  * 
  *     def pattern2phrase(self, pattern):             # <<<<<<<<<<<<<<
@@ -40397,7 +40465,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_4pattern2phrase(struct
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("pattern2phrase", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":439
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":441
  *     def pattern2phrase(self, pattern):
  *         # pattern is a tuple, which we must convert to a hiero Phrase
  *         result = ()             # <<<<<<<<<<<<<<
@@ -40407,7 +40475,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_4pattern2phrase(struct
   __Pyx_INCREF(((PyObject *)__pyx_empty_tuple));
   __pyx_v_result = __pyx_empty_tuple;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":440
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":442
  *         # pattern is a tuple, which we must convert to a hiero Phrase
  *         result = ()
  *         arity = 0             # <<<<<<<<<<<<<<
@@ -40417,7 +40485,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_4pattern2phrase(struct
   __Pyx_INCREF(__pyx_int_0);
   __pyx_v_arity = __pyx_int_0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":441
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":443
  *         result = ()
  *         arity = 0
  *         for word_id in pattern:             # <<<<<<<<<<<<<<
@@ -40428,7 +40496,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_4pattern2phrase(struct
     __pyx_t_1 = __pyx_v_pattern; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
     __pyx_t_3 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_pattern); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_pattern); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -40436,23 +40504,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_4pattern2phrase(struct
     if (!__pyx_t_3 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_3 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_4 = __pyx_t_3(__pyx_t_1);
       if (unlikely(!__pyx_t_4)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -40462,74 +40530,74 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_4pattern2phrase(struct
     __pyx_v_word_id = __pyx_t_4;
     __pyx_t_4 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":442
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":444
  *         arity = 0
  *         for word_id in pattern:
  *             if word_id == -1:             # <<<<<<<<<<<<<<
  *                 arity = arity + 1
  *                 new_id = sym_setindex(self.category, arity)
  */
-    __pyx_t_4 = PyObject_RichCompare(__pyx_v_word_id, __pyx_int_neg_1, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 442; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 442; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_RichCompare(__pyx_v_word_id, __pyx_int_neg_1, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     if (__pyx_t_5) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":443
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":445
  *         for word_id in pattern:
  *             if word_id == -1:
  *                 arity = arity + 1             # <<<<<<<<<<<<<<
  *                 new_id = sym_setindex(self.category, arity)
  *             else:
  */
-      __pyx_t_4 = PyNumber_Add(__pyx_v_arity, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyNumber_Add(__pyx_v_arity, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_v_arity);
       __pyx_v_arity = __pyx_t_4;
       __pyx_t_4 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":444
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":446
  *             if word_id == -1:
  *                 arity = arity + 1
  *                 new_id = sym_setindex(self.category, arity)             # <<<<<<<<<<<<<<
  *             else:
  *                 new_id = sym_fromstring(self.fda.id2word[word_id], True)
  */
-      __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_arity); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_arity); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_v_new_id = __pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_t_6);
       goto __pyx_L5;
     }
     /*else*/ {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":446
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":448
  *                 new_id = sym_setindex(self.category, arity)
  *             else:
  *                 new_id = sym_fromstring(self.fda.id2word[word_id], True)             # <<<<<<<<<<<<<<
  *             result = result + (new_id,)
  *         return Phrase(result)
  */
-      __pyx_t_4 = PyObject_GetItem(__pyx_v_self->fda->id2word, __pyx_v_word_id); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_GetItem(__pyx_v_self->fda->id2word, __pyx_v_word_id); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 448; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_7 = PyBytes_AsString(__pyx_t_4); if (unlikely((!__pyx_t_7) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyBytes_AsString(__pyx_t_4); if (unlikely((!__pyx_t_7) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 448; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __pyx_v_new_id = __pyx_f_3_sa_sym_fromstring(__pyx_t_7, 1);
     }
     __pyx_L5:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":447
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":449
  *             else:
  *                 new_id = sym_fromstring(self.fda.id2word[word_id], True)
  *             result = result + (new_id,)             # <<<<<<<<<<<<<<
  *         return Phrase(result)
  * 
  */
-    __pyx_t_4 = PyInt_FromLong(__pyx_v_new_id); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyInt_FromLong(__pyx_v_new_id); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
     PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_4);
     __Pyx_GIVEREF(__pyx_t_4);
     __pyx_t_4 = 0;
-    __pyx_t_4 = PyNumber_Add(((PyObject *)__pyx_v_result), ((PyObject *)__pyx_t_8)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyNumber_Add(((PyObject *)__pyx_v_result), ((PyObject *)__pyx_t_8)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(((PyObject *)__pyx_t_4));
     __Pyx_DECREF(((PyObject *)__pyx_t_8)); __pyx_t_8 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_v_result));
@@ -40538,7 +40606,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_4pattern2phrase(struct
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":448
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":450
  *                 new_id = sym_fromstring(self.fda.id2word[word_id], True)
  *             result = result + (new_id,)
  *         return Phrase(result)             # <<<<<<<<<<<<<<
@@ -40546,12 +40614,12 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_4pattern2phrase(struct
  *     def pattern2phrase_plus(self, pattern):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 448; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(((PyObject *)__pyx_v_result));
   PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_v_result));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_result));
-  __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 448; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_4;
@@ -40586,7 +40654,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_7pattern2phrase_plus(Py
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":450
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":452
  *         return Phrase(result)
  * 
  *     def pattern2phrase_plus(self, pattern):             # <<<<<<<<<<<<<<
@@ -40616,19 +40684,19 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_6pattern2phrase_plus(st
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("pattern2phrase_plus", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":453
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":455
  *         # returns a list containing both the pattern, and pattern
  *         # suffixed/prefixed with the NT category.
  *         patterns = []             # <<<<<<<<<<<<<<
  *         result = ()
  *         arity = 0
  */
-  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 453; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_patterns = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":454
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":456
  *         # suffixed/prefixed with the NT category.
  *         patterns = []
  *         result = ()             # <<<<<<<<<<<<<<
@@ -40638,7 +40706,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_6pattern2phrase_plus(st
   __Pyx_INCREF(((PyObject *)__pyx_empty_tuple));
   __pyx_v_result = __pyx_empty_tuple;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":455
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":457
  *         patterns = []
  *         result = ()
  *         arity = 0             # <<<<<<<<<<<<<<
@@ -40648,7 +40716,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_6pattern2phrase_plus(st
   __Pyx_INCREF(__pyx_int_0);
   __pyx_v_arity = __pyx_int_0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":456
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":458
  *         result = ()
  *         arity = 0
  *         for word_id in pattern:             # <<<<<<<<<<<<<<
@@ -40659,7 +40727,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_6pattern2phrase_plus(st
     __pyx_t_1 = __pyx_v_pattern; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
     __pyx_t_3 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_pattern); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_pattern); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 458; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -40667,23 +40735,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_6pattern2phrase_plus(st
     if (!__pyx_t_3 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 458; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 458; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_3 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 458; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 458; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_4 = __pyx_t_3(__pyx_t_1);
       if (unlikely(!__pyx_t_4)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 458; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -40693,74 +40761,74 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_6pattern2phrase_plus(st
     __pyx_v_word_id = __pyx_t_4;
     __pyx_t_4 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":457
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":459
  *         arity = 0
  *         for word_id in pattern:
  *             if word_id == -1:             # <<<<<<<<<<<<<<
  *                 arity = arity + 1
  *                 new_id = sym_setindex(self.category, arity)
  */
-    __pyx_t_4 = PyObject_RichCompare(__pyx_v_word_id, __pyx_int_neg_1, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_RichCompare(__pyx_v_word_id, __pyx_int_neg_1, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     if (__pyx_t_5) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":458
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":460
  *         for word_id in pattern:
  *             if word_id == -1:
  *                 arity = arity + 1             # <<<<<<<<<<<<<<
  *                 new_id = sym_setindex(self.category, arity)
  *             else:
  */
-      __pyx_t_4 = PyNumber_Add(__pyx_v_arity, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 458; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyNumber_Add(__pyx_v_arity, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_v_arity);
       __pyx_v_arity = __pyx_t_4;
       __pyx_t_4 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":459
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":461
  *             if word_id == -1:
  *                 arity = arity + 1
  *                 new_id = sym_setindex(self.category, arity)             # <<<<<<<<<<<<<<
  *             else:
  *                 new_id = sym_fromstring(self.fda.id2word[word_id], True)
  */
-      __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_arity); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_arity); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 461; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_v_new_id = __pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_t_6);
       goto __pyx_L5;
     }
     /*else*/ {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":461
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":463
  *                 new_id = sym_setindex(self.category, arity)
  *             else:
  *                 new_id = sym_fromstring(self.fda.id2word[word_id], True)             # <<<<<<<<<<<<<<
  *             result = result + (new_id,)
  *         patterns.append(Phrase(result))
  */
-      __pyx_t_4 = PyObject_GetItem(__pyx_v_self->fda->id2word, __pyx_v_word_id); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 461; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_GetItem(__pyx_v_self->fda->id2word, __pyx_v_word_id); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_7 = PyBytes_AsString(__pyx_t_4); if (unlikely((!__pyx_t_7) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 461; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyBytes_AsString(__pyx_t_4); if (unlikely((!__pyx_t_7) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __pyx_v_new_id = __pyx_f_3_sa_sym_fromstring(__pyx_t_7, 1);
     }
     __pyx_L5:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":462
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":464
  *             else:
  *                 new_id = sym_fromstring(self.fda.id2word[word_id], True)
  *             result = result + (new_id,)             # <<<<<<<<<<<<<<
  *         patterns.append(Phrase(result))
  *         patterns.append(Phrase(result + (sym_setindex(self.category, 1),)))
  */
-    __pyx_t_4 = PyInt_FromLong(__pyx_v_new_id); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyInt_FromLong(__pyx_v_new_id); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
     PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_4);
     __Pyx_GIVEREF(__pyx_t_4);
     __pyx_t_4 = 0;
-    __pyx_t_4 = PyNumber_Add(((PyObject *)__pyx_v_result), ((PyObject *)__pyx_t_8)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyNumber_Add(((PyObject *)__pyx_v_result), ((PyObject *)__pyx_t_8)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(((PyObject *)__pyx_t_4));
     __Pyx_DECREF(((PyObject *)__pyx_t_8)); __pyx_t_8 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_v_result));
@@ -40769,81 +40837,81 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_6pattern2phrase_plus(st
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":463
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":465
  *                 new_id = sym_fromstring(self.fda.id2word[word_id], True)
  *             result = result + (new_id,)
  *         patterns.append(Phrase(result))             # <<<<<<<<<<<<<<
  *         patterns.append(Phrase(result + (sym_setindex(self.category, 1),)))
  *         patterns.append(Phrase((sym_setindex(self.category, 1),) + result))
  */
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(((PyObject *)__pyx_v_result));
   PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_v_result));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_result));
-  __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-  __pyx_t_9 = PyList_Append(__pyx_v_patterns, __pyx_t_4); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_9 = PyList_Append(__pyx_v_patterns, __pyx_t_4); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":464
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":466
  *             result = result + (new_id,)
  *         patterns.append(Phrase(result))
  *         patterns.append(Phrase(result + (sym_setindex(self.category, 1),)))             # <<<<<<<<<<<<<<
  *         patterns.append(Phrase((sym_setindex(self.category, 1),) + result))
  *         return patterns
  */
-  __pyx_t_4 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, 1)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, 1)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_4);
   __Pyx_GIVEREF(__pyx_t_4);
   __pyx_t_4 = 0;
-  __pyx_t_4 = PyNumber_Add(((PyObject *)__pyx_v_result), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyNumber_Add(((PyObject *)__pyx_v_result), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_4));
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_t_4));
   __Pyx_GIVEREF(((PyObject *)__pyx_t_4));
   __pyx_t_4 = 0;
-  __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-  __pyx_t_9 = PyList_Append(__pyx_v_patterns, __pyx_t_4); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_9 = PyList_Append(__pyx_v_patterns, __pyx_t_4); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":465
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":467
  *         patterns.append(Phrase(result))
  *         patterns.append(Phrase(result + (sym_setindex(self.category, 1),)))
  *         patterns.append(Phrase((sym_setindex(self.category, 1),) + result))             # <<<<<<<<<<<<<<
  *         return patterns
  * 
  */
-  __pyx_t_4 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, 1)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, 1)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_4);
   __Pyx_GIVEREF(__pyx_t_4);
   __pyx_t_4 = 0;
-  __pyx_t_4 = PyNumber_Add(((PyObject *)__pyx_t_1), ((PyObject *)__pyx_v_result)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyNumber_Add(((PyObject *)__pyx_t_1), ((PyObject *)__pyx_v_result)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_4));
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_t_4));
   __Pyx_GIVEREF(((PyObject *)__pyx_t_4));
   __pyx_t_4 = 0;
-  __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-  __pyx_t_9 = PyList_Append(__pyx_v_patterns, __pyx_t_4); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_9 = PyList_Append(__pyx_v_patterns, __pyx_t_4); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":466
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":468
  *         patterns.append(Phrase(result + (sym_setindex(self.category, 1),)))
  *         patterns.append(Phrase((sym_setindex(self.category, 1),) + result))
  *         return patterns             # <<<<<<<<<<<<<<
@@ -40884,7 +40952,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_9precompute(PyObject *_
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":468
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":470
  *         return patterns
  * 
  *     def precompute(self):             # <<<<<<<<<<<<<<
@@ -40918,7 +40986,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("precompute", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":471
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":473
  *         cdef Precomputation pre
  * 
  *         if self.precompute_file is not None:             # <<<<<<<<<<<<<<
@@ -40928,31 +40996,31 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
   __pyx_t_1 = (__pyx_v_self->precompute_file != Py_None);
   if (__pyx_t_1) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":472
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":474
  * 
  *         if self.precompute_file is not None:
  *             start_time = monitor_cpu()             # <<<<<<<<<<<<<<
  *             logger.info("Reading precomputed data from file %s... ", self.precompute_file)
  *             pre = Precomputation(from_binary=self.precompute_file)
  */
-    __pyx_t_2 = PyFloat_FromDouble(__pyx_f_3_sa_monitor_cpu()); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 472; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyFloat_FromDouble(__pyx_f_3_sa_monitor_cpu()); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_v_start_time = __pyx_t_2;
     __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":473
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":475
  *         if self.precompute_file is not None:
  *             start_time = monitor_cpu()
  *             logger.info("Reading precomputed data from file %s... ", self.precompute_file)             # <<<<<<<<<<<<<<
  *             pre = Precomputation(from_binary=self.precompute_file)
  *             # check parameters of precomputation -- some are critical and some are not
  */
-    __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 473; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 475; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_3 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__info); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 473; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__info); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 475; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 473; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 475; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_INCREF(((PyObject *)__pyx_kp_s_108));
     PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_kp_s_108));
@@ -40960,29 +41028,29 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
     __Pyx_INCREF(__pyx_v_self->precompute_file);
     PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_self->precompute_file);
     __Pyx_GIVEREF(__pyx_v_self->precompute_file);
-    __pyx_t_4 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 473; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 475; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":474
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":476
  *             start_time = monitor_cpu()
  *             logger.info("Reading precomputed data from file %s... ", self.precompute_file)
  *             pre = Precomputation(from_binary=self.precompute_file)             # <<<<<<<<<<<<<<
  *             # check parameters of precomputation -- some are critical and some are not
  *             if pre.max_nonterminals != self.max_nonterminals:
  */
-    __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 476; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(((PyObject *)__pyx_t_4));
-    if (PyDict_SetItem(__pyx_t_4, ((PyObject *)__pyx_n_s__from_binary), __pyx_v_self->precompute_file) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Precomputation)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_4)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyDict_SetItem(__pyx_t_4, ((PyObject *)__pyx_n_s__from_binary), __pyx_v_self->precompute_file) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 476; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Precomputation)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_4)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 476; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
     __pyx_v_pre = ((struct __pyx_obj_3_sa_Precomputation *)__pyx_t_2);
     __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":476
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":478
  *             pre = Precomputation(from_binary=self.precompute_file)
  *             # check parameters of precomputation -- some are critical and some are not
  *             if pre.max_nonterminals != self.max_nonterminals:             # <<<<<<<<<<<<<<
@@ -40992,23 +41060,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
     __pyx_t_1 = (__pyx_v_pre->max_nonterminals != __pyx_v_self->max_nonterminals);
     if (__pyx_t_1) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":477
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":479
  *             # check parameters of precomputation -- some are critical and some are not
  *             if pre.max_nonterminals != self.max_nonterminals:
  *                 logger.warn("Precomputation done with max nonterminals %d, decoder uses %d", pre.max_nonterminals, self.max_nonterminals)             # <<<<<<<<<<<<<<
  *             if pre.max_length != self.max_length:
  *                 logger.warn("Precomputation done with max terminals %d, decoder uses %d", pre.max_length, self.max_length)
  */
-      __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 479; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_4 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__warn); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__warn); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 479; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_2 = PyInt_FromLong(__pyx_v_pre->max_nonterminals); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyInt_FromLong(__pyx_v_pre->max_nonterminals); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 479; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_3 = PyInt_FromLong(__pyx_v_self->max_nonterminals); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyInt_FromLong(__pyx_v_self->max_nonterminals); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 479; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 479; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_INCREF(((PyObject *)__pyx_kp_s_109));
       PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)__pyx_kp_s_109));
@@ -41019,7 +41087,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
       __Pyx_GIVEREF(__pyx_t_3);
       __pyx_t_2 = 0;
       __pyx_t_3 = 0;
-      __pyx_t_3 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 479; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
@@ -41028,7 +41096,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
     }
     __pyx_L4:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":478
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":480
  *             if pre.max_nonterminals != self.max_nonterminals:
  *                 logger.warn("Precomputation done with max nonterminals %d, decoder uses %d", pre.max_nonterminals, self.max_nonterminals)
  *             if pre.max_length != self.max_length:             # <<<<<<<<<<<<<<
@@ -41038,23 +41106,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
     __pyx_t_1 = (__pyx_v_pre->max_length != __pyx_v_self->max_length);
     if (__pyx_t_1) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":479
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":481
  *                 logger.warn("Precomputation done with max nonterminals %d, decoder uses %d", pre.max_nonterminals, self.max_nonterminals)
  *             if pre.max_length != self.max_length:
  *                 logger.warn("Precomputation done with max terminals %d, decoder uses %d", pre.max_length, self.max_length)             # <<<<<<<<<<<<<<
  *             if pre.train_max_initial_size != self.train_max_initial_size:
  *                 raise Exception("Precomputation done with max initial size %d, decoder uses %d" % (pre.train_max_initial_size, self.train_max_initial_size))
  */
-      __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 479; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_5 = PyObject_GetAttr(__pyx_t_3, __pyx_n_s__warn); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 479; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyObject_GetAttr(__pyx_t_3, __pyx_n_s__warn); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_3 = PyInt_FromLong(__pyx_v_pre->max_length); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 479; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyInt_FromLong(__pyx_v_pre->max_length); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_4 = PyInt_FromLong(__pyx_v_self->max_length); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 479; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyInt_FromLong(__pyx_v_self->max_length); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 479; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_INCREF(((PyObject *)__pyx_kp_s_110));
       PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_kp_s_110));
@@ -41065,7 +41133,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
       __Pyx_GIVEREF(__pyx_t_4);
       __pyx_t_3 = 0;
       __pyx_t_4 = 0;
-      __pyx_t_4 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 479; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
@@ -41074,7 +41142,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
     }
     __pyx_L5:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":480
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":482
  *             if pre.max_length != self.max_length:
  *                 logger.warn("Precomputation done with max terminals %d, decoder uses %d", pre.max_length, self.max_length)
  *             if pre.train_max_initial_size != self.train_max_initial_size:             # <<<<<<<<<<<<<<
@@ -41084,18 +41152,18 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
     __pyx_t_1 = (__pyx_v_pre->train_max_initial_size != __pyx_v_self->train_max_initial_size);
     if (__pyx_t_1) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":481
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":483
  *                 logger.warn("Precomputation done with max terminals %d, decoder uses %d", pre.max_length, self.max_length)
  *             if pre.train_max_initial_size != self.train_max_initial_size:
  *                 raise Exception("Precomputation done with max initial size %d, decoder uses %d" % (pre.train_max_initial_size, self.train_max_initial_size))             # <<<<<<<<<<<<<<
  *             if pre.train_min_gap_size != self.train_min_gap_size:
  *                 raise Exception("Precomputation done with min gap size %d, decoder uses %d" % (pre.train_min_gap_size, self.train_min_gap_size))
  */
-      __pyx_t_4 = PyInt_FromLong(__pyx_v_pre->train_max_initial_size); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyInt_FromLong(__pyx_v_pre->train_max_initial_size); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 483; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_2 = PyInt_FromLong(__pyx_v_self->train_max_initial_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyInt_FromLong(__pyx_v_self->train_max_initial_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 483; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 483; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
       PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4);
       __Pyx_GIVEREF(__pyx_t_4);
@@ -41103,25 +41171,25 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
       __Pyx_GIVEREF(__pyx_t_2);
       __pyx_t_4 = 0;
       __pyx_t_2 = 0;
-      __pyx_t_2 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_111), ((PyObject *)__pyx_t_5)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_111), ((PyObject *)__pyx_t_5)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 483; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(((PyObject *)__pyx_t_2));
       __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
-      __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 483; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
       PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)__pyx_t_2));
       __Pyx_GIVEREF(((PyObject *)__pyx_t_2));
       __pyx_t_2 = 0;
-      __pyx_t_2 = PyObject_Call(__pyx_builtin_Exception, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_Call(__pyx_builtin_Exception, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 483; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
       __Pyx_Raise(__pyx_t_2, 0, 0, 0);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 483; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       goto __pyx_L6;
     }
     __pyx_L6:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":482
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":484
  *             if pre.train_max_initial_size != self.train_max_initial_size:
  *                 raise Exception("Precomputation done with max initial size %d, decoder uses %d" % (pre.train_max_initial_size, self.train_max_initial_size))
  *             if pre.train_min_gap_size != self.train_min_gap_size:             # <<<<<<<<<<<<<<
@@ -41131,18 +41199,18 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
     __pyx_t_1 = (__pyx_v_pre->train_min_gap_size != __pyx_v_self->train_min_gap_size);
     if (__pyx_t_1) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":483
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":485
  *                 raise Exception("Precomputation done with max initial size %d, decoder uses %d" % (pre.train_max_initial_size, self.train_max_initial_size))
  *             if pre.train_min_gap_size != self.train_min_gap_size:
  *                 raise Exception("Precomputation done with min gap size %d, decoder uses %d" % (pre.train_min_gap_size, self.train_min_gap_size))             # <<<<<<<<<<<<<<
  *             if self.use_index:
  *                 logger.info("Converting %d hash keys on precomputed inverted index... ", len(pre.precomputed_index))
  */
-      __pyx_t_2 = PyInt_FromLong(__pyx_v_pre->train_min_gap_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 483; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyInt_FromLong(__pyx_v_pre->train_min_gap_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_5 = PyInt_FromLong(__pyx_v_self->train_min_gap_size); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 483; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyInt_FromLong(__pyx_v_self->train_min_gap_size); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 483; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
       __Pyx_GIVEREF(__pyx_t_2);
@@ -41150,25 +41218,25 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
       __Pyx_GIVEREF(__pyx_t_5);
       __pyx_t_2 = 0;
       __pyx_t_5 = 0;
-      __pyx_t_5 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_112), ((PyObject *)__pyx_t_4)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 483; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_112), ((PyObject *)__pyx_t_4)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(((PyObject *)__pyx_t_5));
       __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
-      __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 483; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_t_5));
       __Pyx_GIVEREF(((PyObject *)__pyx_t_5));
       __pyx_t_5 = 0;
-      __pyx_t_5 = PyObject_Call(__pyx_builtin_Exception, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 483; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyObject_Call(__pyx_builtin_Exception, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
       __Pyx_Raise(__pyx_t_5, 0, 0, 0);
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 483; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       goto __pyx_L7;
     }
     __pyx_L7:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":484
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":486
  *             if pre.train_min_gap_size != self.train_min_gap_size:
  *                 raise Exception("Precomputation done with min gap size %d, decoder uses %d" % (pre.train_min_gap_size, self.train_min_gap_size))
  *             if self.use_index:             # <<<<<<<<<<<<<<
@@ -41177,25 +41245,25 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
  */
     if (__pyx_v_self->use_index) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":485
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":487
  *                 raise Exception("Precomputation done with min gap size %d, decoder uses %d" % (pre.train_min_gap_size, self.train_min_gap_size))
  *             if self.use_index:
  *                 logger.info("Converting %d hash keys on precomputed inverted index... ", len(pre.precomputed_index))             # <<<<<<<<<<<<<<
  *                 for pattern, arr in pre.precomputed_index.iteritems():
  *                     phrases = self.pattern2phrase_plus(pattern)
  */
-      __pyx_t_5 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_4 = PyObject_GetAttr(__pyx_t_5, __pyx_n_s__info); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_GetAttr(__pyx_t_5, __pyx_n_s__info); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       __pyx_t_5 = __pyx_v_pre->precomputed_index;
       __Pyx_INCREF(__pyx_t_5);
-      __pyx_t_6 = PyObject_Length(__pyx_t_5); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PyObject_Length(__pyx_t_5); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      __pyx_t_5 = PyInt_FromSsize_t(__pyx_t_6); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyInt_FromSsize_t(__pyx_t_6); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_INCREF(((PyObject *)__pyx_kp_s_113));
       PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_kp_s_113));
@@ -41203,13 +41271,13 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
       PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_5);
       __Pyx_GIVEREF(__pyx_t_5);
       __pyx_t_5 = 0;
-      __pyx_t_5 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":486
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":488
  *             if self.use_index:
  *                 logger.info("Converting %d hash keys on precomputed inverted index... ", len(pre.precomputed_index))
  *                 for pattern, arr in pre.precomputed_index.iteritems():             # <<<<<<<<<<<<<<
@@ -41219,9 +41287,9 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
       __pyx_t_6 = 0;
       if (unlikely(__pyx_v_pre->precomputed_index == Py_None)) {
         PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "iteritems");
-        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 486; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 488; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       }
-      __pyx_t_2 = __Pyx_dict_iterator(__pyx_v_pre->precomputed_index, 0, ((PyObject *)__pyx_n_s__iteritems), (&__pyx_t_7), (&__pyx_t_8)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 486; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_dict_iterator(__pyx_v_pre->precomputed_index, 0, ((PyObject *)__pyx_n_s__iteritems), (&__pyx_t_7), (&__pyx_t_8)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 488; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_XDECREF(__pyx_t_5);
       __pyx_t_5 = __pyx_t_2;
@@ -41229,7 +41297,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
       while (1) {
         __pyx_t_9 = __Pyx_dict_iter_next(__pyx_t_5, __pyx_t_7, &__pyx_t_6, &__pyx_t_2, &__pyx_t_4, NULL, __pyx_t_8);
         if (unlikely(__pyx_t_9 == 0)) break;
-        if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 486; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 488; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_XDECREF(__pyx_v_pattern);
@@ -41239,21 +41307,21 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
         __pyx_v_arr = __pyx_t_4;
         __pyx_t_4 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":487
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":489
  *                 logger.info("Converting %d hash keys on precomputed inverted index... ", len(pre.precomputed_index))
  *                 for pattern, arr in pre.precomputed_index.iteritems():
  *                     phrases = self.pattern2phrase_plus(pattern)             # <<<<<<<<<<<<<<
  *                     for phrase in phrases:
  *                         self.precomputed_index[phrase] = arr
  */
-        __pyx_t_4 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__pattern2phrase_plus); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__pattern2phrase_plus); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 489; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_4);
-        __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 489; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_INCREF(__pyx_v_pattern);
         PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_pattern);
         __Pyx_GIVEREF(__pyx_v_pattern);
-        __pyx_t_3 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 489; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
         __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
@@ -41261,7 +41329,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
         __pyx_v_phrases = __pyx_t_3;
         __pyx_t_3 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":488
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":490
  *                 for pattern, arr in pre.precomputed_index.iteritems():
  *                     phrases = self.pattern2phrase_plus(pattern)
  *                     for phrase in phrases:             # <<<<<<<<<<<<<<
@@ -41272,7 +41340,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
           __pyx_t_3 = __pyx_v_phrases; __Pyx_INCREF(__pyx_t_3); __pyx_t_10 = 0;
           __pyx_t_11 = NULL;
         } else {
-          __pyx_t_10 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_phrases); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 488; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_10 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_phrases); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 490; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_3);
           __pyx_t_11 = Py_TYPE(__pyx_t_3)->tp_iternext;
         }
@@ -41280,23 +41348,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
           if (!__pyx_t_11 && PyList_CheckExact(__pyx_t_3)) {
             if (__pyx_t_10 >= PyList_GET_SIZE(__pyx_t_3)) break;
             #if CYTHON_COMPILING_IN_CPYTHON
-            __pyx_t_2 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_10); __Pyx_INCREF(__pyx_t_2); __pyx_t_10++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 488; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_2 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_10); __Pyx_INCREF(__pyx_t_2); __pyx_t_10++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 490; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             #else
-            __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_10); __pyx_t_10++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 488; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_10); __pyx_t_10++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 490; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             #endif
           } else if (!__pyx_t_11 && PyTuple_CheckExact(__pyx_t_3)) {
             if (__pyx_t_10 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
             #if CYTHON_COMPILING_IN_CPYTHON
-            __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_10); __Pyx_INCREF(__pyx_t_2); __pyx_t_10++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 488; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_10); __Pyx_INCREF(__pyx_t_2); __pyx_t_10++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 490; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             #else
-            __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_10); __pyx_t_10++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 488; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_10); __pyx_t_10++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 490; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             #endif
           } else {
             __pyx_t_2 = __pyx_t_11(__pyx_t_3);
             if (unlikely(!__pyx_t_2)) {
               if (PyErr_Occurred()) {
                 if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-                else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 488; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 490; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               }
               break;
             }
@@ -41306,14 +41374,14 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
           __pyx_v_phrase = __pyx_t_2;
           __pyx_t_2 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":489
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":491
  *                     phrases = self.pattern2phrase_plus(pattern)
  *                     for phrase in phrases:
  *                         self.precomputed_index[phrase] = arr             # <<<<<<<<<<<<<<
  *             if self.use_collocations:
  *                 logger.info("Converting %d hash keys on precomputed collocations... ", len(pre.precomputed_collocations))
  */
-          if (PyObject_SetItem(__pyx_v_self->precomputed_index, __pyx_v_phrase, __pyx_v_arr) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 489; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          if (PyObject_SetItem(__pyx_v_self->precomputed_index, __pyx_v_phrase, __pyx_v_arr) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 491; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
       }
@@ -41322,7 +41390,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
     }
     __pyx_L8:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":490
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":492
  *                     for phrase in phrases:
  *                         self.precomputed_index[phrase] = arr
  *             if self.use_collocations:             # <<<<<<<<<<<<<<
@@ -41331,25 +41399,25 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
  */
     if (__pyx_v_self->use_collocations) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":491
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":493
  *                         self.precomputed_index[phrase] = arr
  *             if self.use_collocations:
  *                 logger.info("Converting %d hash keys on precomputed collocations... ", len(pre.precomputed_collocations))             # <<<<<<<<<<<<<<
  *                 for pattern, arr in pre.precomputed_collocations.iteritems():
  *                     phrase = self.pattern2phrase(pattern)
  */
-      __pyx_t_5 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 491; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 493; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_3 = PyObject_GetAttr(__pyx_t_5, __pyx_n_s__info); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 491; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyObject_GetAttr(__pyx_t_5, __pyx_n_s__info); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 493; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       __pyx_t_5 = __pyx_v_pre->precomputed_collocations;
       __Pyx_INCREF(__pyx_t_5);
-      __pyx_t_7 = PyObject_Length(__pyx_t_5); if (unlikely(__pyx_t_7 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 491; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyObject_Length(__pyx_t_5); if (unlikely(__pyx_t_7 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 493; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      __pyx_t_5 = PyInt_FromSsize_t(__pyx_t_7); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 491; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyInt_FromSsize_t(__pyx_t_7); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 493; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 491; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 493; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_INCREF(((PyObject *)__pyx_kp_s_114));
       PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_kp_s_114));
@@ -41357,13 +41425,13 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
       PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_5);
       __Pyx_GIVEREF(__pyx_t_5);
       __pyx_t_5 = 0;
-      __pyx_t_5 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 491; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 493; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":492
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":494
  *             if self.use_collocations:
  *                 logger.info("Converting %d hash keys on precomputed collocations... ", len(pre.precomputed_collocations))
  *                 for pattern, arr in pre.precomputed_collocations.iteritems():             # <<<<<<<<<<<<<<
@@ -41373,9 +41441,9 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
       __pyx_t_7 = 0;
       if (unlikely(__pyx_v_pre->precomputed_collocations == Py_None)) {
         PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "iteritems");
-        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 492; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 494; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       }
-      __pyx_t_2 = __Pyx_dict_iterator(__pyx_v_pre->precomputed_collocations, 0, ((PyObject *)__pyx_n_s__iteritems), (&__pyx_t_6), (&__pyx_t_8)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 492; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_dict_iterator(__pyx_v_pre->precomputed_collocations, 0, ((PyObject *)__pyx_n_s__iteritems), (&__pyx_t_6), (&__pyx_t_8)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 494; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_XDECREF(__pyx_t_5);
       __pyx_t_5 = __pyx_t_2;
@@ -41383,7 +41451,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
       while (1) {
         __pyx_t_9 = __Pyx_dict_iter_next(__pyx_t_5, __pyx_t_6, &__pyx_t_7, &__pyx_t_2, &__pyx_t_3, NULL, __pyx_t_8);
         if (unlikely(__pyx_t_9 == 0)) break;
-        if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 492; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 494; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_XDECREF(__pyx_v_pattern);
@@ -41393,21 +41461,21 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
         __pyx_v_arr = __pyx_t_3;
         __pyx_t_3 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":493
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":495
  *                 logger.info("Converting %d hash keys on precomputed collocations... ", len(pre.precomputed_collocations))
  *                 for pattern, arr in pre.precomputed_collocations.iteritems():
  *                     phrase = self.pattern2phrase(pattern)             # <<<<<<<<<<<<<<
  *                     self.precomputed_collocations[phrase] = arr
  *             stop_time = monitor_cpu()
  */
-        __pyx_t_3 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__pattern2phrase); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 493; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__pattern2phrase); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 495; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_3);
-        __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 493; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 495; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_INCREF(__pyx_v_pattern);
         PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_pattern);
         __Pyx_GIVEREF(__pyx_v_pattern);
-        __pyx_t_4 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 493; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 495; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
@@ -41415,47 +41483,47 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
         __pyx_v_phrase = __pyx_t_4;
         __pyx_t_4 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":494
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":496
  *                 for pattern, arr in pre.precomputed_collocations.iteritems():
  *                     phrase = self.pattern2phrase(pattern)
  *                     self.precomputed_collocations[phrase] = arr             # <<<<<<<<<<<<<<
  *             stop_time = monitor_cpu()
  *             logger.info("Processing precomputations took %f seconds", stop_time - start_time)
  */
-        if (PyObject_SetItem(__pyx_v_self->precomputed_collocations, __pyx_v_phrase, __pyx_v_arr) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 494; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (PyObject_SetItem(__pyx_v_self->precomputed_collocations, __pyx_v_phrase, __pyx_v_arr) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       }
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       goto __pyx_L13;
     }
     __pyx_L13:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":495
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":497
  *                     phrase = self.pattern2phrase(pattern)
  *                     self.precomputed_collocations[phrase] = arr
  *             stop_time = monitor_cpu()             # <<<<<<<<<<<<<<
  *             logger.info("Processing precomputations took %f seconds", stop_time - start_time)
  * 
  */
-    __pyx_t_5 = PyFloat_FromDouble(__pyx_f_3_sa_monitor_cpu()); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 495; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyFloat_FromDouble(__pyx_f_3_sa_monitor_cpu()); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 497; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __pyx_v_stop_time = __pyx_t_5;
     __pyx_t_5 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":496
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":498
  *                     self.precomputed_collocations[phrase] = arr
  *             stop_time = monitor_cpu()
  *             logger.info("Processing precomputations took %f seconds", stop_time - start_time)             # <<<<<<<<<<<<<<
  * 
  * 
  */
-    __pyx_t_5 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 498; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_4 = PyObject_GetAttr(__pyx_t_5, __pyx_n_s__info); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_GetAttr(__pyx_t_5, __pyx_n_s__info); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 498; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __pyx_t_5 = PyNumber_Subtract(__pyx_v_stop_time, __pyx_v_start_time); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyNumber_Subtract(__pyx_v_stop_time, __pyx_v_start_time); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 498; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 498; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_INCREF(((PyObject *)__pyx_kp_s_115));
     PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_kp_s_115));
@@ -41463,7 +41531,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8precompute(struct __py
     PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_5);
     __Pyx_GIVEREF(__pyx_t_5);
     __pyx_t_5 = 0;
-    __pyx_t_5 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 498; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
@@ -41505,7 +41573,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_11get_precomputed_collo
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":499
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":501
  * 
  * 
  *     def get_precomputed_collocation(self, phrase):             # <<<<<<<<<<<<<<
@@ -41527,29 +41595,29 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_10get_precomputed_collo
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_precomputed_collocation", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":500
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":502
  * 
  *     def get_precomputed_collocation(self, phrase):
  *         if phrase in self.precomputed_collocations:             # <<<<<<<<<<<<<<
  *             arr = self.precomputed_collocations[phrase]
  *             return PhraseLocation(arr=arr, arr_low=0, arr_high=len(arr), num_subpatterns=phrase.arity()+1)
  */
-  __pyx_t_1 = (__Pyx_PySequence_Contains(__pyx_v_phrase, __pyx_v_self->precomputed_collocations, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 500; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = (__Pyx_PySequence_Contains(__pyx_v_phrase, __pyx_v_self->precomputed_collocations, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   if (__pyx_t_1) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":501
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":503
  *     def get_precomputed_collocation(self, phrase):
  *         if phrase in self.precomputed_collocations:
  *             arr = self.precomputed_collocations[phrase]             # <<<<<<<<<<<<<<
  *             return PhraseLocation(arr=arr, arr_low=0, arr_high=len(arr), num_subpatterns=phrase.arity()+1)
  *         return None
  */
-    __pyx_t_2 = PyObject_GetItem(__pyx_v_self->precomputed_collocations, __pyx_v_phrase); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 501; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyObject_GetItem(__pyx_v_self->precomputed_collocations, __pyx_v_phrase); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 503; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_v_arr = __pyx_t_2;
     __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":502
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":504
  *         if phrase in self.precomputed_collocations:
  *             arr = self.precomputed_collocations[phrase]
  *             return PhraseLocation(arr=arr, arr_low=0, arr_high=len(arr), num_subpatterns=phrase.arity()+1)             # <<<<<<<<<<<<<<
@@ -41557,26 +41625,26 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_10get_precomputed_collo
  * 
  */
     __Pyx_XDECREF(__pyx_r);
-    __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 504; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(((PyObject *)__pyx_t_2));
-    if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__arr), __pyx_v_arr) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__arr_low), __pyx_int_0) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_3 = PyObject_Length(__pyx_v_arr); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_4 = PyInt_FromSsize_t(__pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__arr), __pyx_v_arr) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 504; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__arr_low), __pyx_int_0) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 504; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_Length(__pyx_v_arr); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 504; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyInt_FromSsize_t(__pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 504; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__arr_high), __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__arr_high), __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 504; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = PyObject_GetAttr(__pyx_v_phrase, __pyx_n_s__arity); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_GetAttr(__pyx_v_phrase, __pyx_n_s__arity); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 504; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 504; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = PyNumber_Add(__pyx_t_5, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyNumber_Add(__pyx_t_5, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 504; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__num_subpatterns), __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__num_subpatterns), __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 504; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_PhraseLocation)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_2)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_PhraseLocation)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_2)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 504; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
     __pyx_r = __pyx_t_4;
@@ -41586,7 +41654,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_10get_precomputed_collo
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":503
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":505
  *             arr = self.precomputed_collocations[phrase]
  *             return PhraseLocation(arr=arr, arr_low=0, arr_high=len(arr), num_subpatterns=phrase.arity()+1)
  *         return None             # <<<<<<<<<<<<<<
@@ -41613,7 +41681,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_10get_precomputed_collo
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":506
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":508
  * 
  * 
  *     cdef int* baeza_yates_helper(self, int low1, int high1, int* arr1, int step1,             # <<<<<<<<<<<<<<
@@ -41659,7 +41727,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("baeza_yates_helper", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":519
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":521
  *         cdef Matching loc1, loc2
  * 
  *         result = <int*> malloc(0*sizeof(int*))             # <<<<<<<<<<<<<<
@@ -41668,7 +41736,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   __pyx_v_result = ((int *)malloc((0 * (sizeof(int *)))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":521
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":523
  *         result = <int*> malloc(0*sizeof(int*))
  * 
  *         d_first = 0             # <<<<<<<<<<<<<<
@@ -41677,7 +41745,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   __pyx_v_d_first = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":522
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":524
  * 
  *         d_first = 0
  *         if high1 - low1 > high2 - low2:             # <<<<<<<<<<<<<<
@@ -41687,7 +41755,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   __pyx_t_1 = ((__pyx_v_high1 - __pyx_v_low1) > (__pyx_v_high2 - __pyx_v_low2));
   if (__pyx_t_1) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":523
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":525
  *         d_first = 0
  *         if high1 - low1 > high2 - low2:
  *             d_first = 1             # <<<<<<<<<<<<<<
@@ -41699,7 +41767,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":527
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":529
  *         # First, check to see if we are at any of the recursive base cases
  *         # Case 1: one of the sets is empty
  *         if low1 >= high1 or low2 >= high2:             # <<<<<<<<<<<<<<
@@ -41715,7 +41783,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   }
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":528
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":530
  *         # Case 1: one of the sets is empty
  *         if low1 >= high1 or low2 >= high2:
  *             return result             # <<<<<<<<<<<<<<
@@ -41728,7 +41796,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   }
   __pyx_L4:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":531
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":533
  * 
  *         # Case 2: sets are non-overlapping
  *         assign_matching(&loc1, arr1, high1-step1, step1, self.fda.sent_id.arr)             # <<<<<<<<<<<<<<
@@ -41737,7 +41805,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   __pyx_f_3_sa_assign_matching((&__pyx_v_loc1), __pyx_v_arr1, (__pyx_v_high1 - __pyx_v_step1), __pyx_v_step1, __pyx_v_self->fda->sent_id->arr);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":532
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":534
  *         # Case 2: sets are non-overlapping
  *         assign_matching(&loc1, arr1, high1-step1, step1, self.fda.sent_id.arr)
  *         assign_matching(&loc2, arr2, low2, step2, self.fda.sent_id.arr)             # <<<<<<<<<<<<<<
@@ -41746,7 +41814,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   __pyx_f_3_sa_assign_matching((&__pyx_v_loc2), __pyx_v_arr2, __pyx_v_low2, __pyx_v_step2, __pyx_v_self->fda->sent_id->arr);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":533
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":535
  *         assign_matching(&loc1, arr1, high1-step1, step1, self.fda.sent_id.arr)
  *         assign_matching(&loc2, arr2, low2, step2, self.fda.sent_id.arr)
  *         if self.compare_matchings(&loc1, &loc2, offset_by_one, len_last) == -1:             # <<<<<<<<<<<<<<
@@ -41756,7 +41824,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   __pyx_t_3 = (((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->compare_matchings(__pyx_v_self, (&__pyx_v_loc1), (&__pyx_v_loc2), __pyx_v_offset_by_one, __pyx_v_len_last) == -1);
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":534
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":536
  *         assign_matching(&loc2, arr2, low2, step2, self.fda.sent_id.arr)
  *         if self.compare_matchings(&loc1, &loc2, offset_by_one, len_last) == -1:
  *             return result             # <<<<<<<<<<<<<<
@@ -41769,7 +41837,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   }
   __pyx_L5:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":536
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":538
  *             return result
  * 
  *         assign_matching(&loc1, arr1, low1, step1, self.fda.sent_id.arr)             # <<<<<<<<<<<<<<
@@ -41778,7 +41846,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   __pyx_f_3_sa_assign_matching((&__pyx_v_loc1), __pyx_v_arr1, __pyx_v_low1, __pyx_v_step1, __pyx_v_self->fda->sent_id->arr);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":537
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":539
  * 
  *         assign_matching(&loc1, arr1, low1, step1, self.fda.sent_id.arr)
  *         assign_matching(&loc2, arr2, high2-step2, step2, self.fda.sent_id.arr)             # <<<<<<<<<<<<<<
@@ -41787,7 +41855,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   __pyx_f_3_sa_assign_matching((&__pyx_v_loc2), __pyx_v_arr2, (__pyx_v_high2 - __pyx_v_step2), __pyx_v_step2, __pyx_v_self->fda->sent_id->arr);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":538
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":540
  *         assign_matching(&loc1, arr1, low1, step1, self.fda.sent_id.arr)
  *         assign_matching(&loc2, arr2, high2-step2, step2, self.fda.sent_id.arr)
  *         if self.compare_matchings(&loc1, &loc2, offset_by_one, len_last) == 1:             # <<<<<<<<<<<<<<
@@ -41797,7 +41865,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   __pyx_t_3 = (((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->compare_matchings(__pyx_v_self, (&__pyx_v_loc1), (&__pyx_v_loc2), __pyx_v_offset_by_one, __pyx_v_len_last) == 1);
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":539
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":541
  *         assign_matching(&loc2, arr2, high2-step2, step2, self.fda.sent_id.arr)
  *         if self.compare_matchings(&loc1, &loc2, offset_by_one, len_last) == 1:
  *             return result             # <<<<<<<<<<<<<<
@@ -41810,7 +41878,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   }
   __pyx_L6:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":543
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":545
  *         # Case 3: query set and data set do not meet size mismatch constraints;
  *         # We use mergesort instead in this case
  *         qsetsize = (high1-low1) / step1             # <<<<<<<<<<<<<<
@@ -41820,15 +41888,15 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   __pyx_t_4 = (__pyx_v_high1 - __pyx_v_low1);
   if (unlikely(__pyx_v_step1 == 0)) {
     PyErr_Format(PyExc_ZeroDivisionError, "integer division or modulo by zero");
-    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 543; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 545; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   else if (sizeof(int) == sizeof(long) && unlikely(__pyx_v_step1 == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_t_4))) {
     PyErr_Format(PyExc_OverflowError, "value too large to perform division");
-    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 543; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 545; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __pyx_v_qsetsize = __Pyx_div_int(__pyx_t_4, __pyx_v_step1);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":544
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":546
  *         # We use mergesort instead in this case
  *         qsetsize = (high1-low1) / step1
  *         dsetsize = (high2-low2) / step2             # <<<<<<<<<<<<<<
@@ -41838,15 +41906,15 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   __pyx_t_4 = (__pyx_v_high2 - __pyx_v_low2);
   if (unlikely(__pyx_v_step2 == 0)) {
     PyErr_Format(PyExc_ZeroDivisionError, "integer division or modulo by zero");
-    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 544; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   else if (sizeof(int) == sizeof(long) && unlikely(__pyx_v_step2 == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_t_4))) {
     PyErr_Format(PyExc_OverflowError, "value too large to perform division");
-    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 544; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __pyx_v_dsetsize = __Pyx_div_int(__pyx_t_4, __pyx_v_step2);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":545
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":547
  *         qsetsize = (high1-low1) / step1
  *         dsetsize = (high2-low2) / step2
  *         if d_first:             # <<<<<<<<<<<<<<
@@ -41855,7 +41923,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   if (__pyx_v_d_first) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":546
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":548
  *         dsetsize = (high2-low2) / step2
  *         if d_first:
  *             tmp = qsetsize             # <<<<<<<<<<<<<<
@@ -41864,7 +41932,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_v_tmp = __pyx_v_qsetsize;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":547
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":549
  *         if d_first:
  *             tmp = qsetsize
  *             qsetsize = dsetsize             # <<<<<<<<<<<<<<
@@ -41873,7 +41941,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_v_qsetsize = __pyx_v_dsetsize;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":548
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":550
  *             tmp = qsetsize
  *             qsetsize = dsetsize
  *             dsetsize = tmp             # <<<<<<<<<<<<<<
@@ -41885,7 +41953,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   }
   __pyx_L7:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":550
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":552
  *             dsetsize = tmp
  * 
  *         if self.by_slack_factor * qsetsize * log(dsetsize) / log(2) > dsetsize:             # <<<<<<<<<<<<<<
@@ -41896,12 +41964,12 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   __pyx_t_6 = log(2.0);
   if (unlikely(__pyx_t_6 == 0)) {
     PyErr_Format(PyExc_ZeroDivisionError, "float division");
-    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 550; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 552; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __pyx_t_3 = ((__pyx_t_5 / __pyx_t_6) > __pyx_v_dsetsize);
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":551
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":553
  * 
  *         if self.by_slack_factor * qsetsize * log(dsetsize) / log(2) > dsetsize:
  *             free(result)             # <<<<<<<<<<<<<<
@@ -41910,7 +41978,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     free(__pyx_v_result);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":552
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":554
  *         if self.by_slack_factor * qsetsize * log(dsetsize) / log(2) > dsetsize:
  *             free(result)
  *             return self.merge_helper(low1, high1, arr1, step1, low2, high2, arr2, step2, offset_by_one, len_last, num_subpatterns, result_len)             # <<<<<<<<<<<<<<
@@ -41923,7 +41991,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   }
   __pyx_L8:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":556
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":558
  *         # binary search.    There are two flavors, depending on
  *         # whether the queryset or dataset is first
  *         if d_first:             # <<<<<<<<<<<<<<
@@ -41932,7 +42000,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   if (__pyx_v_d_first) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":557
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":559
  *         # whether the queryset or dataset is first
  *         if d_first:
  *             med2 = median(low2, high2, step2)             # <<<<<<<<<<<<<<
@@ -41941,7 +42009,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_v_med2 = __pyx_f_3_sa_median(__pyx_v_low2, __pyx_v_high2, __pyx_v_step2);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":558
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":560
  *         if d_first:
  *             med2 = median(low2, high2, step2)
  *             assign_matching(&loc2, arr2, med2, step2, self.fda.sent_id.arr)             # <<<<<<<<<<<<<<
@@ -41950,7 +42018,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_f_3_sa_assign_matching((&__pyx_v_loc2), __pyx_v_arr2, __pyx_v_med2, __pyx_v_step2, __pyx_v_self->fda->sent_id->arr);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":560
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":562
  *             assign_matching(&loc2, arr2, med2, step2, self.fda.sent_id.arr)
  * 
  *             search_low = low1             # <<<<<<<<<<<<<<
@@ -41959,7 +42027,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_v_search_low = __pyx_v_low1;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":561
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":563
  * 
  *             search_low = low1
  *             search_high = high1             # <<<<<<<<<<<<<<
@@ -41968,7 +42036,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_v_search_high = __pyx_v_high1;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":562
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":564
  *             search_low = low1
  *             search_high = high1
  *             while search_low < search_high:             # <<<<<<<<<<<<<<
@@ -41979,7 +42047,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
       __pyx_t_3 = (__pyx_v_search_low < __pyx_v_search_high);
       if (!__pyx_t_3) break;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":563
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":565
  *             search_high = high1
  *             while search_low < search_high:
  *                 med1 = median(search_low, search_high, step1)             # <<<<<<<<<<<<<<
@@ -41988,7 +42056,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
       __pyx_v_med1 = __pyx_f_3_sa_median(__pyx_v_search_low, __pyx_v_search_high, __pyx_v_step1);
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":564
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":566
  *             while search_low < search_high:
  *                 med1 = median(search_low, search_high, step1)
  *                 find_comparable_matchings(low1, high1, arr1, step1, med1, &med1_minus, &med1_plus)             # <<<<<<<<<<<<<<
@@ -41997,7 +42065,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
       __pyx_f_3_sa_find_comparable_matchings(__pyx_v_low1, __pyx_v_high1, __pyx_v_arr1, __pyx_v_step1, __pyx_v_med1, (&__pyx_v_med1_minus), (&__pyx_v_med1_plus));
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":565
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":567
  *                 med1 = median(search_low, search_high, step1)
  *                 find_comparable_matchings(low1, high1, arr1, step1, med1, &med1_minus, &med1_plus)
  *                 comparison = self.compare_matchings_set(med1_minus, med1_plus, arr1, step1, &loc2, offset_by_one, len_last)             # <<<<<<<<<<<<<<
@@ -42006,7 +42074,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
       __pyx_v_comparison = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->compare_matchings_set(__pyx_v_self, __pyx_v_med1_minus, __pyx_v_med1_plus, __pyx_v_arr1, __pyx_v_step1, (&__pyx_v_loc2), __pyx_v_offset_by_one, __pyx_v_len_last);
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":568
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":570
  *                 if comparison == -1:
  *                     search_low = med1_plus
  *                 elif comparison == 1:             # <<<<<<<<<<<<<<
@@ -42015,7 +42083,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
       switch (__pyx_v_comparison) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":566
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":568
  *                 find_comparable_matchings(low1, high1, arr1, step1, med1, &med1_minus, &med1_plus)
  *                 comparison = self.compare_matchings_set(med1_minus, med1_plus, arr1, step1, &loc2, offset_by_one, len_last)
  *                 if comparison == -1:             # <<<<<<<<<<<<<<
@@ -42024,7 +42092,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
         case -1:
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":567
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":569
  *                 comparison = self.compare_matchings_set(med1_minus, med1_plus, arr1, step1, &loc2, offset_by_one, len_last)
  *                 if comparison == -1:
  *                     search_low = med1_plus             # <<<<<<<<<<<<<<
@@ -42034,7 +42102,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
         __pyx_v_search_low = __pyx_v_med1_plus;
         break;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":568
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":570
  *                 if comparison == -1:
  *                     search_low = med1_plus
  *                 elif comparison == 1:             # <<<<<<<<<<<<<<
@@ -42043,7 +42111,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
         case 1:
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":569
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":571
  *                     search_low = med1_plus
  *                 elif comparison == 1:
  *                     search_high = med1_minus             # <<<<<<<<<<<<<<
@@ -42054,7 +42122,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
         break;
         default:
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":571
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":573
  *                     search_high = med1_minus
  *                 else:
  *                     break             # <<<<<<<<<<<<<<
@@ -42070,7 +42138,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":573
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":575
  *                     break
  *         else:
  *             med1 = median(low1, high1, step1)             # <<<<<<<<<<<<<<
@@ -42079,7 +42147,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_v_med1 = __pyx_f_3_sa_median(__pyx_v_low1, __pyx_v_high1, __pyx_v_step1);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":574
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":576
  *         else:
  *             med1 = median(low1, high1, step1)
  *             find_comparable_matchings(low1, high1, arr1, step1, med1, &med1_minus, &med1_plus)             # <<<<<<<<<<<<<<
@@ -42088,7 +42156,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_f_3_sa_find_comparable_matchings(__pyx_v_low1, __pyx_v_high1, __pyx_v_arr1, __pyx_v_step1, __pyx_v_med1, (&__pyx_v_med1_minus), (&__pyx_v_med1_plus));
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":576
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":578
  *             find_comparable_matchings(low1, high1, arr1, step1, med1, &med1_minus, &med1_plus)
  * 
  *             search_low = low2             # <<<<<<<<<<<<<<
@@ -42097,7 +42165,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_v_search_low = __pyx_v_low2;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":577
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":579
  * 
  *             search_low = low2
  *             search_high = high2             # <<<<<<<<<<<<<<
@@ -42106,7 +42174,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_v_search_high = __pyx_v_high2;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":578
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":580
  *             search_low = low2
  *             search_high = high2
  *             while search_low < search_high:             # <<<<<<<<<<<<<<
@@ -42117,7 +42185,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
       __pyx_t_3 = (__pyx_v_search_low < __pyx_v_search_high);
       if (!__pyx_t_3) break;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":579
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":581
  *             search_high = high2
  *             while search_low < search_high:
  *                 med2 = median(search_low, search_high, step2)             # <<<<<<<<<<<<<<
@@ -42126,7 +42194,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
       __pyx_v_med2 = __pyx_f_3_sa_median(__pyx_v_search_low, __pyx_v_search_high, __pyx_v_step2);
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":580
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":582
  *             while search_low < search_high:
  *                 med2 = median(search_low, search_high, step2)
  *                 assign_matching(&loc2, arr2, med2, step2, self.fda.sent_id.arr)             # <<<<<<<<<<<<<<
@@ -42135,7 +42203,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
       __pyx_f_3_sa_assign_matching((&__pyx_v_loc2), __pyx_v_arr2, __pyx_v_med2, __pyx_v_step2, __pyx_v_self->fda->sent_id->arr);
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":581
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":583
  *                 med2 = median(search_low, search_high, step2)
  *                 assign_matching(&loc2, arr2, med2, step2, self.fda.sent_id.arr)
  *                 comparison = self.compare_matchings_set(med1_minus, med1_plus, arr1, step1, &loc2, offset_by_one, len_last)             # <<<<<<<<<<<<<<
@@ -42144,7 +42212,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
       __pyx_v_comparison = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->compare_matchings_set(__pyx_v_self, __pyx_v_med1_minus, __pyx_v_med1_plus, __pyx_v_arr1, __pyx_v_step1, (&__pyx_v_loc2), __pyx_v_offset_by_one, __pyx_v_len_last);
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":584
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":586
  *                 if comparison == -1:
  *                     search_high = med2
  *                 elif comparison == 1:             # <<<<<<<<<<<<<<
@@ -42153,7 +42221,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
       switch (__pyx_v_comparison) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":582
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":584
  *                 assign_matching(&loc2, arr2, med2, step2, self.fda.sent_id.arr)
  *                 comparison = self.compare_matchings_set(med1_minus, med1_plus, arr1, step1, &loc2, offset_by_one, len_last)
  *                 if comparison == -1:             # <<<<<<<<<<<<<<
@@ -42162,7 +42230,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
         case -1:
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":583
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":585
  *                 comparison = self.compare_matchings_set(med1_minus, med1_plus, arr1, step1, &loc2, offset_by_one, len_last)
  *                 if comparison == -1:
  *                     search_high = med2             # <<<<<<<<<<<<<<
@@ -42172,7 +42240,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
         __pyx_v_search_high = __pyx_v_med2;
         break;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":584
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":586
  *                 if comparison == -1:
  *                     search_high = med2
  *                 elif comparison == 1:             # <<<<<<<<<<<<<<
@@ -42181,7 +42249,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
         case 1:
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":585
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":587
  *                     search_high = med2
  *                 elif comparison == 1:
  *                     search_low = med2 + step2             # <<<<<<<<<<<<<<
@@ -42192,7 +42260,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
         break;
         default:
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":587
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":589
  *                     search_low = med2 + step2
  *                 else:
  *                     break             # <<<<<<<<<<<<<<
@@ -42207,7 +42275,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   }
   __pyx_L9:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":589
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":591
  *                     break
  * 
  *         med_result_len = 0             # <<<<<<<<<<<<<<
@@ -42216,7 +42284,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   __pyx_v_med_result_len = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":590
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":592
  * 
  *         med_result_len = 0
  *         med_result = <int*> malloc(0*sizeof(int*))             # <<<<<<<<<<<<<<
@@ -42225,7 +42293,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   __pyx_v_med_result = ((int *)malloc((0 * (sizeof(int *)))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":591
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":593
  *         med_result_len = 0
  *         med_result = <int*> malloc(0*sizeof(int*))
  *         if search_high > search_low:             # <<<<<<<<<<<<<<
@@ -42235,7 +42303,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   __pyx_t_3 = (__pyx_v_search_high > __pyx_v_search_low);
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":597
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":599
  *             # want to store the bindings for all of those elements.    We can
  *             # subsequently throw all of them away.
  *             med2_minus = med2             # <<<<<<<<<<<<<<
@@ -42244,7 +42312,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_v_med2_minus = __pyx_v_med2;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":598
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":600
  *             # subsequently throw all of them away.
  *             med2_minus = med2
  *             med2_plus = med2 + step2             # <<<<<<<<<<<<<<
@@ -42253,7 +42321,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_v_med2_plus = (__pyx_v_med2 + __pyx_v_step2);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":599
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":601
  *             med2_minus = med2
  *             med2_plus = med2 + step2
  *             i1 = med1_minus             # <<<<<<<<<<<<<<
@@ -42262,7 +42330,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_v_i1 = __pyx_v_med1_minus;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":600
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":602
  *             med2_plus = med2 + step2
  *             i1 = med1_minus
  *             while i1 < med1_plus:             # <<<<<<<<<<<<<<
@@ -42273,7 +42341,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
       __pyx_t_3 = (__pyx_v_i1 < __pyx_v_med1_plus);
       if (!__pyx_t_3) break;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":601
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":603
  *             i1 = med1_minus
  *             while i1 < med1_plus:
  *                 assign_matching(&loc1, arr1, i1, step1, self.fda.sent_id.arr)             # <<<<<<<<<<<<<<
@@ -42282,7 +42350,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
       __pyx_f_3_sa_assign_matching((&__pyx_v_loc1), __pyx_v_arr1, __pyx_v_i1, __pyx_v_step1, __pyx_v_self->fda->sent_id->arr);
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":602
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":604
  *             while i1 < med1_plus:
  *                 assign_matching(&loc1, arr1, i1, step1, self.fda.sent_id.arr)
  *                 while med2_minus-step2 >= low2:             # <<<<<<<<<<<<<<
@@ -42293,7 +42361,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
         __pyx_t_3 = ((__pyx_v_med2_minus - __pyx_v_step2) >= __pyx_v_low2);
         if (!__pyx_t_3) break;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":603
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":605
  *                 assign_matching(&loc1, arr1, i1, step1, self.fda.sent_id.arr)
  *                 while med2_minus-step2 >= low2:
  *                     assign_matching(&loc2, arr2, med2_minus-step2, step2, self.fda.sent_id.arr)             # <<<<<<<<<<<<<<
@@ -42302,7 +42370,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
         __pyx_f_3_sa_assign_matching((&__pyx_v_loc2), __pyx_v_arr2, (__pyx_v_med2_minus - __pyx_v_step2), __pyx_v_step2, __pyx_v_self->fda->sent_id->arr);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":604
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":606
  *                 while med2_minus-step2 >= low2:
  *                     assign_matching(&loc2, arr2, med2_minus-step2, step2, self.fda.sent_id.arr)
  *                     if self.compare_matchings(&loc1, &loc2, offset_by_one, len_last) < 1:             # <<<<<<<<<<<<<<
@@ -42312,7 +42380,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
         __pyx_t_3 = (((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->compare_matchings(__pyx_v_self, (&__pyx_v_loc1), (&__pyx_v_loc2), __pyx_v_offset_by_one, __pyx_v_len_last) < 1);
         if (__pyx_t_3) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":605
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":607
  *                     assign_matching(&loc2, arr2, med2_minus-step2, step2, self.fda.sent_id.arr)
  *                     if self.compare_matchings(&loc1, &loc2, offset_by_one, len_last) < 1:
  *                         med2_minus = med2_minus - step2             # <<<<<<<<<<<<<<
@@ -42324,7 +42392,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
         }
         /*else*/ {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":607
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":609
  *                         med2_minus = med2_minus - step2
  *                     else:
  *                         break             # <<<<<<<<<<<<<<
@@ -42337,7 +42405,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
       }
       __pyx_L18_break:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":608
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":610
  *                     else:
  *                         break
  *                 i2 = med2_minus             # <<<<<<<<<<<<<<
@@ -42346,7 +42414,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
       __pyx_v_i2 = __pyx_v_med2_minus;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":609
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":611
  *                         break
  *                 i2 = med2_minus
  *                 while i2 < high2:             # <<<<<<<<<<<<<<
@@ -42357,7 +42425,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
         __pyx_t_3 = (__pyx_v_i2 < __pyx_v_high2);
         if (!__pyx_t_3) break;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":610
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":612
  *                 i2 = med2_minus
  *                 while i2 < high2:
  *                     assign_matching(&loc2, arr2, i2, step2, self.fda.sent_id.arr)             # <<<<<<<<<<<<<<
@@ -42366,7 +42434,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
         __pyx_f_3_sa_assign_matching((&__pyx_v_loc2), __pyx_v_arr2, __pyx_v_i2, __pyx_v_step2, __pyx_v_self->fda->sent_id->arr);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":611
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":613
  *                 while i2 < high2:
  *                     assign_matching(&loc2, arr2, i2, step2, self.fda.sent_id.arr)
  *                     comparison = self.compare_matchings(&loc1, &loc2, offset_by_one, len_last)             # <<<<<<<<<<<<<<
@@ -42375,7 +42443,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
         __pyx_v_comparison = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->compare_matchings(__pyx_v_self, (&__pyx_v_loc1), (&__pyx_v_loc2), __pyx_v_offset_by_one, __pyx_v_len_last);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":612
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":614
  *                     assign_matching(&loc2, arr2, i2, step2, self.fda.sent_id.arr)
  *                     comparison = self.compare_matchings(&loc1, &loc2, offset_by_one, len_last)
  *                     if comparison == 0:             # <<<<<<<<<<<<<<
@@ -42385,7 +42453,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
         __pyx_t_3 = (__pyx_v_comparison == 0);
         if (__pyx_t_3) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":614
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":616
  *                     if comparison == 0:
  *                         pass
  *                         med_result = append_combined_matching(med_result, &loc1, &loc2, offset_by_one, num_subpatterns, &med_result_len)             # <<<<<<<<<<<<<<
@@ -42397,7 +42465,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
         }
         __pyx_L22:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":615
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":617
  *                         pass
  *                         med_result = append_combined_matching(med_result, &loc1, &loc2, offset_by_one, num_subpatterns, &med_result_len)
  *                     if comparison == -1:             # <<<<<<<<<<<<<<
@@ -42407,7 +42475,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
         __pyx_t_3 = (__pyx_v_comparison == -1);
         if (__pyx_t_3) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":616
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":618
  *                         med_result = append_combined_matching(med_result, &loc1, &loc2, offset_by_one, num_subpatterns, &med_result_len)
  *                     if comparison == -1:
  *                         break             # <<<<<<<<<<<<<<
@@ -42419,7 +42487,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
         }
         __pyx_L23:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":617
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":619
  *                     if comparison == -1:
  *                         break
  *                     i2 = i2 + step2             # <<<<<<<<<<<<<<
@@ -42430,7 +42498,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
       }
       __pyx_L21_break:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":618
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":620
  *                         break
  *                     i2 = i2 + step2
  *                 if i2 > med2_plus:             # <<<<<<<<<<<<<<
@@ -42440,7 +42508,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
       __pyx_t_3 = (__pyx_v_i2 > __pyx_v_med2_plus);
       if (__pyx_t_3) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":619
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":621
  *                     i2 = i2 + step2
  *                 if i2 > med2_plus:
  *                     med2_plus = i2             # <<<<<<<<<<<<<<
@@ -42452,7 +42520,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
       }
       __pyx_L24:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":620
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":622
  *                 if i2 > med2_plus:
  *                     med2_plus = i2
  *                 i1 = i1 + step1             # <<<<<<<<<<<<<<
@@ -42462,7 +42530,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
       __pyx_v_i1 = (__pyx_v_i1 + __pyx_v_step1);
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":622
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":624
  *                 i1 = i1 + step1
  * 
  *             tmp = med1_minus             # <<<<<<<<<<<<<<
@@ -42471,7 +42539,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_v_tmp = __pyx_v_med1_minus;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":623
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":625
  * 
  *             tmp = med1_minus
  *             med1_minus = med1_plus             # <<<<<<<<<<<<<<
@@ -42480,7 +42548,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_v_med1_minus = __pyx_v_med1_plus;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":624
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":626
  *             tmp = med1_minus
  *             med1_minus = med1_plus
  *             med1_plus = tmp             # <<<<<<<<<<<<<<
@@ -42492,7 +42560,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":627
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":629
  *         else:
  *             # No match; need to figure out the point of division in D and Q
  *             med2_minus = med2             # <<<<<<<<<<<<<<
@@ -42501,7 +42569,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_v_med2_minus = __pyx_v_med2;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":628
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":630
  *             # No match; need to figure out the point of division in D and Q
  *             med2_minus = med2
  *             med2_plus = med2             # <<<<<<<<<<<<<<
@@ -42510,7 +42578,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     __pyx_v_med2_plus = __pyx_v_med2;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":629
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":631
  *             med2_minus = med2
  *             med2_plus = med2
  *             if d_first:             # <<<<<<<<<<<<<<
@@ -42519,7 +42587,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
     if (__pyx_v_d_first) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":630
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":632
  *             med2_plus = med2
  *             if d_first:
  *                 med2_minus = med2_minus + step2             # <<<<<<<<<<<<<<
@@ -42528,7 +42596,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
       __pyx_v_med2_minus = (__pyx_v_med2_minus + __pyx_v_step2);
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":631
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":633
  *             if d_first:
  *                 med2_minus = med2_minus + step2
  *                 if comparison == -1:             # <<<<<<<<<<<<<<
@@ -42538,7 +42606,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
       __pyx_t_3 = (__pyx_v_comparison == -1);
       if (__pyx_t_3) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":632
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":634
  *                 med2_minus = med2_minus + step2
  *                 if comparison == -1:
  *                     med1_minus = med1_plus             # <<<<<<<<<<<<<<
@@ -42550,7 +42618,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
       }
       __pyx_L26:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":633
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":635
  *                 if comparison == -1:
  *                     med1_minus = med1_plus
  *                 if comparison == 1:             # <<<<<<<<<<<<<<
@@ -42560,7 +42628,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
       __pyx_t_3 = (__pyx_v_comparison == 1);
       if (__pyx_t_3) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":634
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":636
  *                     med1_minus = med1_plus
  *                 if comparison == 1:
  *                     med1_plus = med1_minus             # <<<<<<<<<<<<<<
@@ -42575,7 +42643,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
     }
     /*else*/ {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":636
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":638
  *                     med1_plus = med1_minus
  *             else:
  *                 tmp = med1_minus             # <<<<<<<<<<<<<<
@@ -42584,7 +42652,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
       __pyx_v_tmp = __pyx_v_med1_minus;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":637
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":639
  *             else:
  *                 tmp = med1_minus
  *                 med1_minus = med1_plus             # <<<<<<<<<<<<<<
@@ -42593,7 +42661,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
       __pyx_v_med1_minus = __pyx_v_med1_plus;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":638
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":640
  *                 tmp = med1_minus
  *                 med1_minus = med1_plus
  *                 med1_plus = tmp             # <<<<<<<<<<<<<<
@@ -42602,7 +42670,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
       __pyx_v_med1_plus = __pyx_v_tmp;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":639
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":641
  *                 med1_minus = med1_plus
  *                 med1_plus = tmp
  *                 if comparison == 1:             # <<<<<<<<<<<<<<
@@ -42612,7 +42680,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
       __pyx_t_3 = (__pyx_v_comparison == 1);
       if (__pyx_t_3) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":640
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":642
  *                 med1_plus = tmp
  *                 if comparison == 1:
  *                     med2_minus = med2_minus + step2             # <<<<<<<<<<<<<<
@@ -42621,7 +42689,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
         __pyx_v_med2_minus = (__pyx_v_med2_minus + __pyx_v_step2);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":641
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":643
  *                 if comparison == 1:
  *                     med2_minus = med2_minus + step2
  *                     med2_plus = med2_plus + step2             # <<<<<<<<<<<<<<
@@ -42637,7 +42705,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   }
   __pyx_L14:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":643
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":645
  *                     med2_plus = med2_plus + step2
  * 
  *         low_result_len = 0             # <<<<<<<<<<<<<<
@@ -42646,7 +42714,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   __pyx_v_low_result_len = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":644
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":646
  * 
  *         low_result_len = 0
  *         low_result = self.baeza_yates_helper(low1, med1_plus, arr1, step1, low2, med2_plus, arr2, step2, offset_by_one, len_last, num_subpatterns, &low_result_len)             # <<<<<<<<<<<<<<
@@ -42655,7 +42723,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   __pyx_v_low_result = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->baeza_yates_helper(__pyx_v_self, __pyx_v_low1, __pyx_v_med1_plus, __pyx_v_arr1, __pyx_v_step1, __pyx_v_low2, __pyx_v_med2_plus, __pyx_v_arr2, __pyx_v_step2, __pyx_v_offset_by_one, __pyx_v_len_last, __pyx_v_num_subpatterns, (&__pyx_v_low_result_len));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":645
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":647
  *         low_result_len = 0
  *         low_result = self.baeza_yates_helper(low1, med1_plus, arr1, step1, low2, med2_plus, arr2, step2, offset_by_one, len_last, num_subpatterns, &low_result_len)
  *         high_result_len = 0             # <<<<<<<<<<<<<<
@@ -42664,7 +42732,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   __pyx_v_high_result_len = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":646
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":648
  *         low_result = self.baeza_yates_helper(low1, med1_plus, arr1, step1, low2, med2_plus, arr2, step2, offset_by_one, len_last, num_subpatterns, &low_result_len)
  *         high_result_len = 0
  *         high_result = self.baeza_yates_helper(med1_minus, high1, arr1, step1, med2_minus, high2, arr2, step2, offset_by_one, len_last, num_subpatterns, &high_result_len)             # <<<<<<<<<<<<<<
@@ -42673,7 +42741,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   __pyx_v_high_result = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->baeza_yates_helper(__pyx_v_self, __pyx_v_med1_minus, __pyx_v_high1, __pyx_v_arr1, __pyx_v_step1, __pyx_v_med2_minus, __pyx_v_high2, __pyx_v_arr2, __pyx_v_step2, __pyx_v_offset_by_one, __pyx_v_len_last, __pyx_v_num_subpatterns, (&__pyx_v_high_result_len));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":648
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":650
  *         high_result = self.baeza_yates_helper(med1_minus, high1, arr1, step1, med2_minus, high2, arr2, step2, offset_by_one, len_last, num_subpatterns, &high_result_len)
  * 
  *         result = extend_arr(result, result_len, low_result, low_result_len)             # <<<<<<<<<<<<<<
@@ -42682,7 +42750,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   __pyx_v_result = __pyx_f_3_sa_extend_arr(__pyx_v_result, __pyx_v_result_len, __pyx_v_low_result, __pyx_v_low_result_len);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":649
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":651
  * 
  *         result = extend_arr(result, result_len, low_result, low_result_len)
  *         result = extend_arr(result, result_len, med_result, med_result_len)             # <<<<<<<<<<<<<<
@@ -42691,7 +42759,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   __pyx_v_result = __pyx_f_3_sa_extend_arr(__pyx_v_result, __pyx_v_result_len, __pyx_v_med_result, __pyx_v_med_result_len);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":650
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":652
  *         result = extend_arr(result, result_len, low_result, low_result_len)
  *         result = extend_arr(result, result_len, med_result, med_result_len)
  *         result = extend_arr(result, result_len, high_result, high_result_len)             # <<<<<<<<<<<<<<
@@ -42700,7 +42768,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   __pyx_v_result = __pyx_f_3_sa_extend_arr(__pyx_v_result, __pyx_v_result_len, __pyx_v_high_result, __pyx_v_high_result_len);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":651
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":653
  *         result = extend_arr(result, result_len, med_result, med_result_len)
  *         result = extend_arr(result, result_len, high_result, high_result_len)
  *         free(low_result)             # <<<<<<<<<<<<<<
@@ -42709,7 +42777,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   free(__pyx_v_low_result);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":652
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":654
  *         result = extend_arr(result, result_len, high_result, high_result_len)
  *         free(low_result)
  *         free(med_result)             # <<<<<<<<<<<<<<
@@ -42718,7 +42786,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   free(__pyx_v_med_result);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":653
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":655
  *         free(low_result)
  *         free(med_result)
  *         free(high_result)             # <<<<<<<<<<<<<<
@@ -42727,7 +42795,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
  */
   free(__pyx_v_high_result);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":655
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":657
  *         free(high_result)
  * 
  *         return result             # <<<<<<<<<<<<<<
@@ -42747,7 +42815,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_baeza_yates_helper(struct __p
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":659
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":661
  * 
  * 
  *     cdef long compare_matchings_set(self, int i1_minus, int i1_plus, int* arr1, int step1,             # <<<<<<<<<<<<<<
@@ -42766,7 +42834,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
   int __pyx_t_1;
   __Pyx_RefNannySetupContext("compare_matchings_set", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":670
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":672
  *         cdef Matching* loc1
  * 
  *         loc1 = &l1_stack             # <<<<<<<<<<<<<<
@@ -42775,7 +42843,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
  */
   __pyx_v_loc1 = (&__pyx_v_l1_stack);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":672
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":674
  *         loc1 = &l1_stack
  * 
  *         i1 = i1_minus             # <<<<<<<<<<<<<<
@@ -42784,7 +42852,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
  */
   __pyx_v_i1 = __pyx_v_i1_minus;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":673
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":675
  * 
  *         i1 = i1_minus
  *         while i1 < i1_plus:             # <<<<<<<<<<<<<<
@@ -42795,7 +42863,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
     __pyx_t_1 = (__pyx_v_i1 < __pyx_v_i1_plus);
     if (!__pyx_t_1) break;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":674
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":676
  *         i1 = i1_minus
  *         while i1 < i1_plus:
  *             assign_matching(loc1, arr1, i1, step1, self.fda.sent_id.arr)             # <<<<<<<<<<<<<<
@@ -42804,7 +42872,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
  */
     __pyx_f_3_sa_assign_matching(__pyx_v_loc1, __pyx_v_arr1, __pyx_v_i1, __pyx_v_step1, __pyx_v_self->fda->sent_id->arr);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":675
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":677
  *         while i1 < i1_plus:
  *             assign_matching(loc1, arr1, i1, step1, self.fda.sent_id.arr)
  *             comparison = self.compare_matchings(loc1, loc2, offset_by_one, len_last)             # <<<<<<<<<<<<<<
@@ -42813,7 +42881,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
  */
     __pyx_v_comparison = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->compare_matchings(__pyx_v_self, __pyx_v_loc1, __pyx_v_loc2, __pyx_v_offset_by_one, __pyx_v_len_last);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":676
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":678
  *             assign_matching(loc1, arr1, i1, step1, self.fda.sent_id.arr)
  *             comparison = self.compare_matchings(loc1, loc2, offset_by_one, len_last)
  *             if comparison == 0:             # <<<<<<<<<<<<<<
@@ -42823,7 +42891,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
     __pyx_t_1 = (__pyx_v_comparison == 0);
     if (__pyx_t_1) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":677
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":679
  *             comparison = self.compare_matchings(loc1, loc2, offset_by_one, len_last)
  *             if comparison == 0:
  *                 prev_comparison = 0             # <<<<<<<<<<<<<<
@@ -42832,7 +42900,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
  */
       __pyx_v_prev_comparison = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":678
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":680
  *             if comparison == 0:
  *                 prev_comparison = 0
  *                 break             # <<<<<<<<<<<<<<
@@ -42843,7 +42911,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
       goto __pyx_L5;
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":679
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":681
  *                 prev_comparison = 0
  *                 break
  *             elif i1 == i1_minus:             # <<<<<<<<<<<<<<
@@ -42853,7 +42921,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
     __pyx_t_1 = (__pyx_v_i1 == __pyx_v_i1_minus);
     if (__pyx_t_1) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":680
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":682
  *                 break
  *             elif i1 == i1_minus:
  *                 prev_comparison = comparison             # <<<<<<<<<<<<<<
@@ -42865,7 +42933,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
     }
     /*else*/ {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":682
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":684
  *                 prev_comparison = comparison
  *             else:
  *                 if comparison != prev_comparison:             # <<<<<<<<<<<<<<
@@ -42875,7 +42943,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
       __pyx_t_1 = (__pyx_v_comparison != __pyx_v_prev_comparison);
       if (__pyx_t_1) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":683
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":685
  *             else:
  *                 if comparison != prev_comparison:
  *                     prev_comparison = 0             # <<<<<<<<<<<<<<
@@ -42884,7 +42952,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
  */
         __pyx_v_prev_comparison = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":684
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":686
  *                 if comparison != prev_comparison:
  *                     prev_comparison = 0
  *                     break             # <<<<<<<<<<<<<<
@@ -42898,7 +42966,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
     }
     __pyx_L5:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":685
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":687
  *                     prev_comparison = 0
  *                     break
  *             i1 = i1 + step1             # <<<<<<<<<<<<<<
@@ -42909,7 +42977,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
   }
   __pyx_L4_break:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":686
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":688
  *                     break
  *             i1 = i1 + step1
  *         return prev_comparison             # <<<<<<<<<<<<<<
@@ -42925,7 +42993,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings_set(struct
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":689
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":691
  * 
  * 
  *     cdef long compare_matchings(self, Matching* loc1, Matching* loc2, int offset_by_one, int len_last):             # <<<<<<<<<<<<<<
@@ -42943,7 +43011,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
   int __pyx_t_4;
   __Pyx_RefNannySetupContext("compare_matchings", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":692
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":694
  *         cdef int i
  * 
  *         if loc1.sent_id > loc2.sent_id:             # <<<<<<<<<<<<<<
@@ -42953,7 +43021,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
   __pyx_t_1 = (__pyx_v_loc1->sent_id > __pyx_v_loc2->sent_id);
   if (__pyx_t_1) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":693
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":695
  * 
  *         if loc1.sent_id > loc2.sent_id:
  *             return 1             # <<<<<<<<<<<<<<
@@ -42966,7 +43034,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":694
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":696
  *         if loc1.sent_id > loc2.sent_id:
  *             return 1
  *         if loc2.sent_id > loc1.sent_id:             # <<<<<<<<<<<<<<
@@ -42976,7 +43044,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
   __pyx_t_1 = (__pyx_v_loc2->sent_id > __pyx_v_loc1->sent_id);
   if (__pyx_t_1) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":695
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":697
  *             return 1
  *         if loc2.sent_id > loc1.sent_id:
  *             return -1             # <<<<<<<<<<<<<<
@@ -42989,7 +43057,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
   }
   __pyx_L4:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":697
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":699
  *             return -1
  * 
  *         if loc1.size == 1 and loc2.size == 1:             # <<<<<<<<<<<<<<
@@ -43005,7 +43073,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
   }
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":698
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":700
  * 
  *         if loc1.size == 1 and loc2.size == 1:
  *             if loc2.arr[loc2.start] - loc1.arr[loc1.start] <= self.train_min_gap_size:             # <<<<<<<<<<<<<<
@@ -43015,7 +43083,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
     __pyx_t_3 = (((__pyx_v_loc2->arr[__pyx_v_loc2->start]) - (__pyx_v_loc1->arr[__pyx_v_loc1->start])) <= __pyx_v_self->train_min_gap_size);
     if (__pyx_t_3) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":699
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":701
  *         if loc1.size == 1 and loc2.size == 1:
  *             if loc2.arr[loc2.start] - loc1.arr[loc1.start] <= self.train_min_gap_size:
  *                 return 1             # <<<<<<<<<<<<<<
@@ -43030,7 +43098,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
     goto __pyx_L5;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":701
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":703
  *                 return 1
  * 
  *         elif offset_by_one:             # <<<<<<<<<<<<<<
@@ -43039,7 +43107,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
  */
   if (__pyx_v_offset_by_one) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":702
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":704
  * 
  *         elif offset_by_one:
  *             for i from 1 <= i < loc1.size:             # <<<<<<<<<<<<<<
@@ -43049,7 +43117,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
     __pyx_t_4 = __pyx_v_loc1->size;
     for (__pyx_v_i = 1; __pyx_v_i < __pyx_t_4; __pyx_v_i++) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":703
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":705
  *         elif offset_by_one:
  *             for i from 1 <= i < loc1.size:
  *                 if loc1.arr[loc1.start+i] > loc2.arr[loc2.start+i-1]:             # <<<<<<<<<<<<<<
@@ -43059,7 +43127,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
       __pyx_t_3 = ((__pyx_v_loc1->arr[(__pyx_v_loc1->start + __pyx_v_i)]) > (__pyx_v_loc2->arr[((__pyx_v_loc2->start + __pyx_v_i) - 1)]));
       if (__pyx_t_3) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":704
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":706
  *             for i from 1 <= i < loc1.size:
  *                 if loc1.arr[loc1.start+i] > loc2.arr[loc2.start+i-1]:
  *                     return 1             # <<<<<<<<<<<<<<
@@ -43072,7 +43140,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
       }
       __pyx_L9:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":705
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":707
  *                 if loc1.arr[loc1.start+i] > loc2.arr[loc2.start+i-1]:
  *                     return 1
  *                 if loc1.arr[loc1.start+i] < loc2.arr[loc2.start+i-1]:             # <<<<<<<<<<<<<<
@@ -43082,7 +43150,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
       __pyx_t_3 = ((__pyx_v_loc1->arr[(__pyx_v_loc1->start + __pyx_v_i)]) < (__pyx_v_loc2->arr[((__pyx_v_loc2->start + __pyx_v_i) - 1)]));
       if (__pyx_t_3) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":706
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":708
  *                     return 1
  *                 if loc1.arr[loc1.start+i] < loc2.arr[loc2.start+i-1]:
  *                     return -1             # <<<<<<<<<<<<<<
@@ -43099,7 +43167,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":709
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":711
  * 
  *         else:
  *             if loc1.arr[loc1.start]+1 > loc2.arr[loc2.start]:             # <<<<<<<<<<<<<<
@@ -43109,7 +43177,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
     __pyx_t_3 = (((__pyx_v_loc1->arr[__pyx_v_loc1->start]) + 1) > (__pyx_v_loc2->arr[__pyx_v_loc2->start]));
     if (__pyx_t_3) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":710
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":712
  *         else:
  *             if loc1.arr[loc1.start]+1 > loc2.arr[loc2.start]:
  *                 return 1             # <<<<<<<<<<<<<<
@@ -43122,7 +43190,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
     }
     __pyx_L11:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":711
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":713
  *             if loc1.arr[loc1.start]+1 > loc2.arr[loc2.start]:
  *                 return 1
  *             if loc1.arr[loc1.start]+1 < loc2.arr[loc2.start]:             # <<<<<<<<<<<<<<
@@ -43132,7 +43200,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
     __pyx_t_3 = (((__pyx_v_loc1->arr[__pyx_v_loc1->start]) + 1) < (__pyx_v_loc2->arr[__pyx_v_loc2->start]));
     if (__pyx_t_3) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":712
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":714
  *                 return 1
  *             if loc1.arr[loc1.start]+1 < loc2.arr[loc2.start]:
  *                 return -1             # <<<<<<<<<<<<<<
@@ -43145,7 +43213,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
     }
     __pyx_L12:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":714
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":716
  *                 return -1
  * 
  *             for i from 1 <= i < loc1.size:             # <<<<<<<<<<<<<<
@@ -43155,7 +43223,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
     __pyx_t_4 = __pyx_v_loc1->size;
     for (__pyx_v_i = 1; __pyx_v_i < __pyx_t_4; __pyx_v_i++) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":715
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":717
  * 
  *             for i from 1 <= i < loc1.size:
  *                 if loc1.arr[loc1.start+i] > loc2.arr[loc2.start+i]:             # <<<<<<<<<<<<<<
@@ -43165,7 +43233,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
       __pyx_t_3 = ((__pyx_v_loc1->arr[(__pyx_v_loc1->start + __pyx_v_i)]) > (__pyx_v_loc2->arr[(__pyx_v_loc2->start + __pyx_v_i)]));
       if (__pyx_t_3) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":716
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":718
  *             for i from 1 <= i < loc1.size:
  *                 if loc1.arr[loc1.start+i] > loc2.arr[loc2.start+i]:
  *                     return 1             # <<<<<<<<<<<<<<
@@ -43178,7 +43246,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
       }
       __pyx_L15:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":717
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":719
  *                 if loc1.arr[loc1.start+i] > loc2.arr[loc2.start+i]:
  *                     return 1
  *                 if loc1.arr[loc1.start+i] < loc2.arr[loc2.start+i]:             # <<<<<<<<<<<<<<
@@ -43188,7 +43256,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
       __pyx_t_3 = ((__pyx_v_loc1->arr[(__pyx_v_loc1->start + __pyx_v_i)]) < (__pyx_v_loc2->arr[(__pyx_v_loc2->start + __pyx_v_i)]));
       if (__pyx_t_3) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":718
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":720
  *                     return 1
  *                 if loc1.arr[loc1.start+i] < loc2.arr[loc2.start+i]:
  *                     return -1             # <<<<<<<<<<<<<<
@@ -43204,7 +43272,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
   }
   __pyx_L5:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":720
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":722
  *                     return -1
  * 
  *         if loc2.arr[loc2.end-1] + len_last - loc1.arr[loc1.start] > self.train_max_initial_size:             # <<<<<<<<<<<<<<
@@ -43214,7 +43282,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
   __pyx_t_3 = ((((__pyx_v_loc2->arr[(__pyx_v_loc2->end - 1)]) + __pyx_v_len_last) - (__pyx_v_loc1->arr[__pyx_v_loc1->start])) > __pyx_v_self->train_max_initial_size);
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":721
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":723
  * 
  *         if loc2.arr[loc2.end-1] + len_last - loc1.arr[loc1.start] > self.train_max_initial_size:
  *             return -1             # <<<<<<<<<<<<<<
@@ -43227,7 +43295,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
   }
   __pyx_L17:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":722
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":724
  *         if loc2.arr[loc2.end-1] + len_last - loc1.arr[loc1.start] > self.train_max_initial_size:
  *             return -1
  *         return 0             # <<<<<<<<<<<<<<
@@ -43243,7 +43311,7 @@ static long __pyx_f_3_sa_23HieroCachingRuleFactory_compare_matchings(struct __py
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":725
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":727
  * 
  * 
  *     cdef int* merge_helper(self, int low1, int high1, int* arr1, int step1,             # <<<<<<<<<<<<<<
@@ -43267,7 +43335,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
   int __pyx_t_3;
   __Pyx_RefNannySetupContext("merge_helper", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":733
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":735
  *         cdef Matching loc1, loc2
  * 
  *         result_len[0] = 0             # <<<<<<<<<<<<<<
@@ -43276,7 +43344,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
  */
   (__pyx_v_result_len[0]) = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":734
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":736
  * 
  *         result_len[0] = 0
  *         result = <int*> malloc(0*sizeof(int))             # <<<<<<<<<<<<<<
@@ -43285,7 +43353,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
  */
   __pyx_v_result = ((int *)malloc((0 * (sizeof(int)))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":736
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":738
  *         result = <int*> malloc(0*sizeof(int))
  * 
  *         i1 = low1             # <<<<<<<<<<<<<<
@@ -43294,7 +43362,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
  */
   __pyx_v_i1 = __pyx_v_low1;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":737
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":739
  * 
  *         i1 = low1
  *         i2 = low2             # <<<<<<<<<<<<<<
@@ -43303,7 +43371,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
  */
   __pyx_v_i2 = __pyx_v_low2;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":738
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":740
  *         i1 = low1
  *         i2 = low2
  *         while i1 < high1 and i2 < high2:             # <<<<<<<<<<<<<<
@@ -43320,7 +43388,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
     }
     if (!__pyx_t_3) break;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":741
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":743
  * 
  *             # First, pop all unneeded loc2's off the stack
  *             assign_matching(&loc1, arr1, i1, step1, self.fda.sent_id.arr)             # <<<<<<<<<<<<<<
@@ -43329,7 +43397,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
  */
     __pyx_f_3_sa_assign_matching((&__pyx_v_loc1), __pyx_v_arr1, __pyx_v_i1, __pyx_v_step1, __pyx_v_self->fda->sent_id->arr);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":742
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":744
  *             # First, pop all unneeded loc2's off the stack
  *             assign_matching(&loc1, arr1, i1, step1, self.fda.sent_id.arr)
  *             while i2 < high2:             # <<<<<<<<<<<<<<
@@ -43340,7 +43408,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
       __pyx_t_3 = (__pyx_v_i2 < __pyx_v_high2);
       if (!__pyx_t_3) break;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":743
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":745
  *             assign_matching(&loc1, arr1, i1, step1, self.fda.sent_id.arr)
  *             while i2 < high2:
  *                 assign_matching(&loc2, arr2, i2, step2, self.fda.sent_id.arr)             # <<<<<<<<<<<<<<
@@ -43349,7 +43417,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
  */
       __pyx_f_3_sa_assign_matching((&__pyx_v_loc2), __pyx_v_arr2, __pyx_v_i2, __pyx_v_step2, __pyx_v_self->fda->sent_id->arr);
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":744
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":746
  *             while i2 < high2:
  *                 assign_matching(&loc2, arr2, i2, step2, self.fda.sent_id.arr)
  *                 if self.compare_matchings(&loc1, &loc2, offset_by_one, len_last) == 1:             # <<<<<<<<<<<<<<
@@ -43359,7 +43427,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
       __pyx_t_3 = (((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->compare_matchings(__pyx_v_self, (&__pyx_v_loc1), (&__pyx_v_loc2), __pyx_v_offset_by_one, __pyx_v_len_last) == 1);
       if (__pyx_t_3) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":745
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":747
  *                 assign_matching(&loc2, arr2, i2, step2, self.fda.sent_id.arr)
  *                 if self.compare_matchings(&loc1, &loc2, offset_by_one, len_last) == 1:
  *                     i2 = i2 + step2             # <<<<<<<<<<<<<<
@@ -43371,7 +43439,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
       }
       /*else*/ {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":747
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":749
  *                     i2 = i2 + step2
  *                 else:
  *                     break             # <<<<<<<<<<<<<<
@@ -43384,7 +43452,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
     }
     __pyx_L6_break:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":750
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":752
  * 
  *             # Next: process all loc1's with the same starting val
  *             j1 = i1             # <<<<<<<<<<<<<<
@@ -43393,7 +43461,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
  */
     __pyx_v_j1 = __pyx_v_i1;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":751
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":753
  *             # Next: process all loc1's with the same starting val
  *             j1 = i1
  *             while i1 < high1 and arr1[j1] == arr1[i1]:             # <<<<<<<<<<<<<<
@@ -43410,7 +43478,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
       }
       if (!__pyx_t_2) break;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":752
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":754
  *             j1 = i1
  *             while i1 < high1 and arr1[j1] == arr1[i1]:
  *                 assign_matching(&loc1, arr1, i1, step1, self.fda.sent_id.arr)             # <<<<<<<<<<<<<<
@@ -43419,7 +43487,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
  */
       __pyx_f_3_sa_assign_matching((&__pyx_v_loc1), __pyx_v_arr1, __pyx_v_i1, __pyx_v_step1, __pyx_v_self->fda->sent_id->arr);
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":753
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":755
  *             while i1 < high1 and arr1[j1] == arr1[i1]:
  *                 assign_matching(&loc1, arr1, i1, step1, self.fda.sent_id.arr)
  *                 j2 = i2             # <<<<<<<<<<<<<<
@@ -43428,7 +43496,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
  */
       __pyx_v_j2 = __pyx_v_i2;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":754
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":756
  *                 assign_matching(&loc1, arr1, i1, step1, self.fda.sent_id.arr)
  *                 j2 = i2
  *                 while j2 < high2:             # <<<<<<<<<<<<<<
@@ -43439,7 +43507,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
         __pyx_t_2 = (__pyx_v_j2 < __pyx_v_high2);
         if (!__pyx_t_2) break;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":755
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":757
  *                 j2 = i2
  *                 while j2 < high2:
  *                     assign_matching(&loc2, arr2, j2, step2, self.fda.sent_id.arr)             # <<<<<<<<<<<<<<
@@ -43448,7 +43516,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
  */
         __pyx_f_3_sa_assign_matching((&__pyx_v_loc2), __pyx_v_arr2, __pyx_v_j2, __pyx_v_step2, __pyx_v_self->fda->sent_id->arr);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":756
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":758
  *                 while j2 < high2:
  *                     assign_matching(&loc2, arr2, j2, step2, self.fda.sent_id.arr)
  *                     comparison = self.compare_matchings(&loc1, &loc2, offset_by_one, len_last)             # <<<<<<<<<<<<<<
@@ -43457,7 +43525,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
  */
         __pyx_v_comparison = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->compare_matchings(__pyx_v_self, (&__pyx_v_loc1), (&__pyx_v_loc2), __pyx_v_offset_by_one, __pyx_v_len_last);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":757
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":759
  *                     assign_matching(&loc2, arr2, j2, step2, self.fda.sent_id.arr)
  *                     comparison = self.compare_matchings(&loc1, &loc2, offset_by_one, len_last)
  *                     if comparison == 0:             # <<<<<<<<<<<<<<
@@ -43467,7 +43535,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
         __pyx_t_2 = (__pyx_v_comparison == 0);
         if (__pyx_t_2) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":758
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":760
  *                     comparison = self.compare_matchings(&loc1, &loc2, offset_by_one, len_last)
  *                     if comparison == 0:
  *                         result = append_combined_matching(result, &loc1, &loc2, offset_by_one, num_subpatterns, result_len)             # <<<<<<<<<<<<<<
@@ -43479,7 +43547,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
         }
         __pyx_L12:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":759
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":761
  *                     if comparison == 0:
  *                         result = append_combined_matching(result, &loc1, &loc2, offset_by_one, num_subpatterns, result_len)
  *                     if comparison == 1:             # <<<<<<<<<<<<<<
@@ -43492,7 +43560,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
         }
         __pyx_L13:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":761
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":763
  *                     if comparison == 1:
  *                         pass
  *                     if comparison == -1:             # <<<<<<<<<<<<<<
@@ -43502,7 +43570,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
         __pyx_t_2 = (__pyx_v_comparison == -1);
         if (__pyx_t_2) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":762
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":764
  *                         pass
  *                     if comparison == -1:
  *                         break             # <<<<<<<<<<<<<<
@@ -43514,7 +43582,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
         }
         /*else*/ {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":764
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":766
  *                         break
  *                     else:
  *                         j2 = j2 + step2             # <<<<<<<<<<<<<<
@@ -43527,7 +43595,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
       }
       __pyx_L11_break:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":765
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":767
  *                     else:
  *                         j2 = j2 + step2
  *                 i1 = i1 + step1             # <<<<<<<<<<<<<<
@@ -43538,7 +43606,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
     }
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":766
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":768
  *                         j2 = j2 + step2
  *                 i1 = i1 + step1
  *         return result             # <<<<<<<<<<<<<<
@@ -43554,7 +43622,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_merge_helper(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":769
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":771
  * 
  * 
  *     cdef void sort_phrase_loc(self, IntList arr, PhraseLocation loc, Phrase phrase):             # <<<<<<<<<<<<<<
@@ -43576,26 +43644,26 @@ static void __pyx_f_3_sa_23HieroCachingRuleFactory_sort_phrase_loc(struct __pyx_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("sort_phrase_loc", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":774
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":776
  *         cdef IntList result
  * 
  *         if phrase in self.precomputed_index:             # <<<<<<<<<<<<<<
  *             loc.arr = self.precomputed_index[phrase]
  *         else:
  */
-  __pyx_t_1 = (__Pyx_PySequence_Contains(((PyObject *)__pyx_v_phrase), __pyx_v_self->precomputed_index, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 774; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = (__Pyx_PySequence_Contains(((PyObject *)__pyx_v_phrase), __pyx_v_self->precomputed_index, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 776; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   if (__pyx_t_1) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":775
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":777
  * 
  *         if phrase in self.precomputed_index:
  *             loc.arr = self.precomputed_index[phrase]             # <<<<<<<<<<<<<<
  *         else:
  *             loc.arr = IntList(initial_len=loc.sa_high-loc.sa_low)
  */
-    __pyx_t_2 = PyObject_GetItem(__pyx_v_self->precomputed_index, ((PyObject *)__pyx_v_phrase)); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 775; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyObject_GetItem(__pyx_v_self->precomputed_index, ((PyObject *)__pyx_v_phrase)); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 777; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_3_sa_IntList))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 775; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_3_sa_IntList))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 777; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GIVEREF(__pyx_t_2);
     __Pyx_GOTREF(__pyx_v_loc->arr);
     __Pyx_DECREF(((PyObject *)__pyx_v_loc->arr));
@@ -43605,20 +43673,20 @@ static void __pyx_f_3_sa_23HieroCachingRuleFactory_sort_phrase_loc(struct __pyx_
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":777
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":779
  *             loc.arr = self.precomputed_index[phrase]
  *         else:
  *             loc.arr = IntList(initial_len=loc.sa_high-loc.sa_low)             # <<<<<<<<<<<<<<
  *             veb = VEB(arr.len)
  *             for i from loc.sa_low <= i < loc.sa_high:
  */
-    __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 777; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 779; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(((PyObject *)__pyx_t_2));
-    __pyx_t_3 = PyInt_FromLong((__pyx_v_loc->sa_high - __pyx_v_loc->sa_low)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 777; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyInt_FromLong((__pyx_v_loc->sa_high - __pyx_v_loc->sa_low)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 779; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
-    if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__initial_len), __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 777; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__initial_len), __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 779; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_2)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 777; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_2)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 779; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
     __Pyx_GIVEREF(__pyx_t_3);
@@ -43627,27 +43695,27 @@ static void __pyx_f_3_sa_23HieroCachingRuleFactory_sort_phrase_loc(struct __pyx_
     __pyx_v_loc->arr = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_3);
     __pyx_t_3 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":778
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":780
  *         else:
  *             loc.arr = IntList(initial_len=loc.sa_high-loc.sa_low)
  *             veb = VEB(arr.len)             # <<<<<<<<<<<<<<
  *             for i from loc.sa_low <= i < loc.sa_high:
  *                 veb._insert(arr.arr[i])
  */
-    __pyx_t_3 = PyInt_FromLong(__pyx_v_arr->len); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 778; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyInt_FromLong(__pyx_v_arr->len); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 780; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 778; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 780; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_3);
     __Pyx_GIVEREF(__pyx_t_3);
     __pyx_t_3 = 0;
-    __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_VEB)), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 778; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_VEB)), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 780; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
     __pyx_v_veb = ((struct __pyx_obj_3_sa_VEB *)__pyx_t_3);
     __pyx_t_3 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":779
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":781
  *             loc.arr = IntList(initial_len=loc.sa_high-loc.sa_low)
  *             veb = VEB(arr.len)
  *             for i from loc.sa_low <= i < loc.sa_high:             # <<<<<<<<<<<<<<
@@ -43657,7 +43725,7 @@ static void __pyx_f_3_sa_23HieroCachingRuleFactory_sort_phrase_loc(struct __pyx_
     __pyx_t_4 = __pyx_v_loc->sa_high;
     for (__pyx_v_i = __pyx_v_loc->sa_low; __pyx_v_i < __pyx_t_4; __pyx_v_i++) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":780
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":782
  *             veb = VEB(arr.len)
  *             for i from loc.sa_low <= i < loc.sa_high:
  *                 veb._insert(arr.arr[i])             # <<<<<<<<<<<<<<
@@ -43667,7 +43735,7 @@ static void __pyx_f_3_sa_23HieroCachingRuleFactory_sort_phrase_loc(struct __pyx_
       ((struct __pyx_vtabstruct_3_sa_VEB *)__pyx_v_veb->__pyx_vtab)->_insert(__pyx_v_veb, (__pyx_v_arr->arr[__pyx_v_i]));
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":781
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":783
  *             for i from loc.sa_low <= i < loc.sa_high:
  *                 veb._insert(arr.arr[i])
  *             i = veb.veb.min_val             # <<<<<<<<<<<<<<
@@ -43676,7 +43744,7 @@ static void __pyx_f_3_sa_23HieroCachingRuleFactory_sort_phrase_loc(struct __pyx_
  */
     __pyx_v_i = __pyx_v_veb->veb->min_val;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":782
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":784
  *                 veb._insert(arr.arr[i])
  *             i = veb.veb.min_val
  *             for j from 0 <= j < loc.sa_high-loc.sa_low:             # <<<<<<<<<<<<<<
@@ -43686,7 +43754,7 @@ static void __pyx_f_3_sa_23HieroCachingRuleFactory_sort_phrase_loc(struct __pyx_
     __pyx_t_4 = (__pyx_v_loc->sa_high - __pyx_v_loc->sa_low);
     for (__pyx_v_j = 0; __pyx_v_j < __pyx_t_4; __pyx_v_j++) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":783
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":785
  *             i = veb.veb.min_val
  *             for j from 0 <= j < loc.sa_high-loc.sa_low:
  *                 loc.arr.arr[j] = i             # <<<<<<<<<<<<<<
@@ -43695,7 +43763,7 @@ static void __pyx_f_3_sa_23HieroCachingRuleFactory_sort_phrase_loc(struct __pyx_
  */
       (__pyx_v_loc->arr->arr[__pyx_v_j]) = __pyx_v_i;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":784
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":786
  *             for j from 0 <= j < loc.sa_high-loc.sa_low:
  *                 loc.arr.arr[j] = i
  *                 i = veb._findsucc(i)             # <<<<<<<<<<<<<<
@@ -43707,7 +43775,7 @@ static void __pyx_f_3_sa_23HieroCachingRuleFactory_sort_phrase_loc(struct __pyx_
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":785
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":787
  *                 loc.arr.arr[j] = i
  *                 i = veb._findsucc(i)
  *         loc.arr_low = 0             # <<<<<<<<<<<<<<
@@ -43716,7 +43784,7 @@ static void __pyx_f_3_sa_23HieroCachingRuleFactory_sort_phrase_loc(struct __pyx_
  */
   __pyx_v_loc->arr_low = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":786
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":788
  *                 i = veb._findsucc(i)
  *         loc.arr_low = 0
  *         loc.arr_high = loc.arr.len             # <<<<<<<<<<<<<<
@@ -43735,7 +43803,7 @@ static void __pyx_f_3_sa_23HieroCachingRuleFactory_sort_phrase_loc(struct __pyx_
   __Pyx_RefNannyFinishContext();
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":789
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":791
  * 
  * 
  *     cdef intersect_helper(self, Phrase prefix, Phrase suffix,             # <<<<<<<<<<<<<<
@@ -43772,7 +43840,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("intersect_helper", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":796
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":798
  *         cdef int* result_ptr
  * 
  *         result_len = 0             # <<<<<<<<<<<<<<
@@ -43781,21 +43849,21 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
  */
   __pyx_v_result_len = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":798
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":800
  *         result_len = 0
  * 
  *         if sym_isvar(suffix[0]):             # <<<<<<<<<<<<<<
  *             offset_by_one = 1
  *         else:
  */
-  __pyx_t_1 = __Pyx_GetItemInt(((PyObject *)__pyx_v_suffix), 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetItemInt(((PyObject *)__pyx_v_suffix), 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 800; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 800; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_t_3 = __pyx_f_3_sa_sym_isvar(__pyx_t_2);
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":799
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":801
  * 
  *         if sym_isvar(suffix[0]):
  *             offset_by_one = 1             # <<<<<<<<<<<<<<
@@ -43807,7 +43875,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":801
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":803
  *             offset_by_one = 1
  *         else:
  *             offset_by_one = 0             # <<<<<<<<<<<<<<
@@ -43818,34 +43886,34 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":803
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":805
  *             offset_by_one = 0
  * 
  *         len_last = len(suffix.getchunk(suffix.arity()))             # <<<<<<<<<<<<<<
  * 
  *         if prefix_loc.arr is None:
  */
-  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_suffix), __pyx_n_s__getchunk); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_suffix), __pyx_n_s__getchunk); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 805; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_4 = PyObject_GetAttr(((PyObject *)__pyx_v_suffix), __pyx_n_s__arity); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyObject_GetAttr(((PyObject *)__pyx_v_suffix), __pyx_n_s__arity); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 805; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 805; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 805; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
   PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_5);
   __Pyx_GIVEREF(__pyx_t_5);
   __pyx_t_5 = 0;
-  __pyx_t_5 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 805; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
-  __pyx_t_6 = PyObject_Length(__pyx_t_5); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_6 = PyObject_Length(__pyx_t_5); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 805; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_v_len_last = __pyx_t_6;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":805
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":807
  *         len_last = len(suffix.getchunk(suffix.arity()))
  * 
  *         if prefix_loc.arr is None:             # <<<<<<<<<<<<<<
@@ -43855,7 +43923,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
   __pyx_t_7 = (((PyObject *)__pyx_v_prefix_loc->arr) == Py_None);
   if (__pyx_t_7) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":806
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":808
  * 
  *         if prefix_loc.arr is None:
  *             self.sort_phrase_loc(self.fsa.sa, prefix_loc, prefix)             # <<<<<<<<<<<<<<
@@ -43870,7 +43938,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
   }
   __pyx_L4:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":807
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":809
  *         if prefix_loc.arr is None:
  *             self.sort_phrase_loc(self.fsa.sa, prefix_loc, prefix)
  *         arr1 = prefix_loc.arr             # <<<<<<<<<<<<<<
@@ -43880,7 +43948,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
   __Pyx_INCREF(((PyObject *)__pyx_v_prefix_loc->arr));
   __pyx_v_arr1 = __pyx_v_prefix_loc->arr;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":808
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":810
  *             self.sort_phrase_loc(self.fsa.sa, prefix_loc, prefix)
  *         arr1 = prefix_loc.arr
  *         low1 = prefix_loc.arr_low             # <<<<<<<<<<<<<<
@@ -43889,7 +43957,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
  */
   __pyx_v_low1 = __pyx_v_prefix_loc->arr_low;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":809
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":811
  *         arr1 = prefix_loc.arr
  *         low1 = prefix_loc.arr_low
  *         high1 = prefix_loc.arr_high             # <<<<<<<<<<<<<<
@@ -43898,7 +43966,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
  */
   __pyx_v_high1 = __pyx_v_prefix_loc->arr_high;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":810
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":812
  *         low1 = prefix_loc.arr_low
  *         high1 = prefix_loc.arr_high
  *         step1 = prefix_loc.num_subpatterns             # <<<<<<<<<<<<<<
@@ -43907,7 +43975,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
  */
   __pyx_v_step1 = __pyx_v_prefix_loc->num_subpatterns;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":812
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":814
  *         step1 = prefix_loc.num_subpatterns
  * 
  *         if suffix_loc.arr is None:             # <<<<<<<<<<<<<<
@@ -43917,7 +43985,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
   __pyx_t_7 = (((PyObject *)__pyx_v_suffix_loc->arr) == Py_None);
   if (__pyx_t_7) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":813
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":815
  * 
  *         if suffix_loc.arr is None:
  *             self.sort_phrase_loc(self.fsa.sa, suffix_loc, suffix)             # <<<<<<<<<<<<<<
@@ -43932,7 +44000,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
   }
   __pyx_L5:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":814
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":816
  *         if suffix_loc.arr is None:
  *             self.sort_phrase_loc(self.fsa.sa, suffix_loc, suffix)
  *         arr2 = suffix_loc.arr             # <<<<<<<<<<<<<<
@@ -43942,7 +44010,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
   __Pyx_INCREF(((PyObject *)__pyx_v_suffix_loc->arr));
   __pyx_v_arr2 = __pyx_v_suffix_loc->arr;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":815
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":817
  *             self.sort_phrase_loc(self.fsa.sa, suffix_loc, suffix)
  *         arr2 = suffix_loc.arr
  *         low2 = suffix_loc.arr_low             # <<<<<<<<<<<<<<
@@ -43951,7 +44019,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
  */
   __pyx_v_low2 = __pyx_v_suffix_loc->arr_low;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":816
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":818
  *         arr2 = suffix_loc.arr
  *         low2 = suffix_loc.arr_low
  *         high2 = suffix_loc.arr_high             # <<<<<<<<<<<<<<
@@ -43960,7 +44028,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
  */
   __pyx_v_high2 = __pyx_v_suffix_loc->arr_high;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":817
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":819
  *         low2 = suffix_loc.arr_low
  *         high2 = suffix_loc.arr_high
  *         step2 = suffix_loc.num_subpatterns             # <<<<<<<<<<<<<<
@@ -43969,26 +44037,26 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
  */
   __pyx_v_step2 = __pyx_v_suffix_loc->num_subpatterns;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":819
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":821
  *         step2 = suffix_loc.num_subpatterns
  * 
  *         num_subpatterns = prefix.arity()+1             # <<<<<<<<<<<<<<
  * 
  *         if algorithm == MERGE:
  */
-  __pyx_t_5 = PyObject_GetAttr(((PyObject *)__pyx_v_prefix), __pyx_n_s__arity); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 819; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = PyObject_GetAttr(((PyObject *)__pyx_v_prefix), __pyx_n_s__arity); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 821; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_4 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 819; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 821; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = PyNumber_Add(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 819; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = PyNumber_Add(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 821; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_3 = __Pyx_PyInt_AsInt(__pyx_t_5); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 819; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = __Pyx_PyInt_AsInt(__pyx_t_5); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 821; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_v_num_subpatterns = __pyx_t_3;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":821
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":823
  *         num_subpatterns = prefix.arity()+1
  * 
  *         if algorithm == MERGE:             # <<<<<<<<<<<<<<
@@ -43998,7 +44066,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
   __pyx_t_7 = (__pyx_v_algorithm == __pyx_v_3_sa_MERGE);
   if (__pyx_t_7) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":824
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":826
  *             result_ptr = self.merge_helper(low1, high1, arr1.arr, step1,
  *                                     low2, high2, arr2.arr, step2,
  *                                     offset_by_one, len_last, num_subpatterns, &result_len)             # <<<<<<<<<<<<<<
@@ -44010,7 +44078,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":828
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":830
  *             result_ptr = self.baeza_yates_helper(low1, high1, arr1.arr, step1,
  *                                     low2, high2, arr2.arr, step2,
  *                                     offset_by_one, len_last, num_subpatterns, &result_len)             # <<<<<<<<<<<<<<
@@ -44021,7 +44089,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
   }
   __pyx_L6:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":830
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":832
  *                                     offset_by_one, len_last, num_subpatterns, &result_len)
  * 
  *         if result_len == 0:             # <<<<<<<<<<<<<<
@@ -44031,7 +44099,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
   __pyx_t_7 = (__pyx_v_result_len == 0);
   if (__pyx_t_7) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":831
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":833
  * 
  *         if result_len == 0:
  *             free(result_ptr)             # <<<<<<<<<<<<<<
@@ -44040,7 +44108,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
  */
     free(__pyx_v_result_ptr);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":832
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":834
  *         if result_len == 0:
  *             free(result_ptr)
  *             return None             # <<<<<<<<<<<<<<
@@ -44055,19 +44123,19 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":834
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":836
  *             return None
  *         else:
  *             result = IntList()             # <<<<<<<<<<<<<<
  *             free(result.arr)
  *             result.arr = result_ptr
  */
-    __pyx_t_5 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __pyx_v_result = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_5);
     __pyx_t_5 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":835
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":837
  *         else:
  *             result = IntList()
  *             free(result.arr)             # <<<<<<<<<<<<<<
@@ -44076,7 +44144,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
  */
     free(__pyx_v_result->arr);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":836
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":838
  *             result = IntList()
  *             free(result.arr)
  *             result.arr = result_ptr             # <<<<<<<<<<<<<<
@@ -44085,7 +44153,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
  */
     __pyx_v_result->arr = __pyx_v_result_ptr;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":837
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":839
  *             free(result.arr)
  *             result.arr = result_ptr
  *             result.len = result_len             # <<<<<<<<<<<<<<
@@ -44094,7 +44162,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
  */
     __pyx_v_result->len = __pyx_v_result_len;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":838
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":840
  *             result.arr = result_ptr
  *             result.len = result_len
  *             result.size = result_len             # <<<<<<<<<<<<<<
@@ -44103,7 +44171,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
  */
     __pyx_v_result->size = __pyx_v_result_len;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":839
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":841
  *             result.len = result_len
  *             result.size = result_len
  *             return PhraseLocation(arr_low=0, arr_high=result_len, arr=result, num_subpatterns=num_subpatterns)             # <<<<<<<<<<<<<<
@@ -44111,19 +44179,19 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
  *     cdef loc2str(self, PhraseLocation loc):
  */
     __Pyx_XDECREF(__pyx_r);
-    __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(((PyObject *)__pyx_t_5));
-    if (PyDict_SetItem(__pyx_t_5, ((PyObject *)__pyx_n_s__arr_low), __pyx_int_0) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_4 = PyInt_FromLong(__pyx_v_result_len); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyDict_SetItem(__pyx_t_5, ((PyObject *)__pyx_n_s__arr_low), __pyx_int_0) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyInt_FromLong(__pyx_v_result_len); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    if (PyDict_SetItem(__pyx_t_5, ((PyObject *)__pyx_n_s__arr_high), __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyDict_SetItem(__pyx_t_5, ((PyObject *)__pyx_n_s__arr_high), __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (PyDict_SetItem(__pyx_t_5, ((PyObject *)__pyx_n_s__arr), ((PyObject *)__pyx_v_result)) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_4 = PyInt_FromLong(__pyx_v_num_subpatterns); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyDict_SetItem(__pyx_t_5, ((PyObject *)__pyx_n_s__arr), ((PyObject *)__pyx_v_result)) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyInt_FromLong(__pyx_v_num_subpatterns); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    if (PyDict_SetItem(__pyx_t_5, ((PyObject *)__pyx_n_s__num_subpatterns), __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyDict_SetItem(__pyx_t_5, ((PyObject *)__pyx_n_s__num_subpatterns), __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_PhraseLocation)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_5)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_PhraseLocation)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_5)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
     __pyx_r = __pyx_t_4;
@@ -44149,7 +44217,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_intersect_helper(struct
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":841
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":843
  *             return PhraseLocation(arr_low=0, arr_high=result_len, arr=result, num_subpatterns=num_subpatterns)
  * 
  *     cdef loc2str(self, PhraseLocation loc):             # <<<<<<<<<<<<<<
@@ -44172,7 +44240,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_loc2str(CYTHON_UNUSED st
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("loc2str", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":843
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":845
  *     cdef loc2str(self, PhraseLocation loc):
  *         cdef int i, j
  *         result = "{"             # <<<<<<<<<<<<<<
@@ -44182,7 +44250,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_loc2str(CYTHON_UNUSED st
   __Pyx_INCREF(((PyObject *)__pyx_kp_s_116));
   __pyx_v_result = ((PyObject *)__pyx_kp_s_116);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":844
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":846
  *         cdef int i, j
  *         result = "{"
  *         i = 0             # <<<<<<<<<<<<<<
@@ -44191,7 +44259,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_loc2str(CYTHON_UNUSED st
  */
   __pyx_v_i = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":845
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":847
  *         result = "{"
  *         i = 0
  *         while i < loc.arr_high:             # <<<<<<<<<<<<<<
@@ -44202,20 +44270,20 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_loc2str(CYTHON_UNUSED st
     __pyx_t_1 = (__pyx_v_i < __pyx_v_loc->arr_high);
     if (!__pyx_t_1) break;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":846
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":848
  *         i = 0
  *         while i < loc.arr_high:
  *             result = result + "("             # <<<<<<<<<<<<<<
  *             for j from i <= j < i + loc.num_subpatterns:
  *                 result = result + ("%d " %loc.arr[j])
  */
-    __pyx_t_2 = PyNumber_Add(__pyx_v_result, ((PyObject *)__pyx_kp_s_117)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 846; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyNumber_Add(__pyx_v_result, ((PyObject *)__pyx_kp_s_117)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 848; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_v_result);
     __pyx_v_result = __pyx_t_2;
     __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":847
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":849
  *         while i < loc.arr_high:
  *             result = result + "("
  *             for j from i <= j < i + loc.num_subpatterns:             # <<<<<<<<<<<<<<
@@ -44225,19 +44293,19 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_loc2str(CYTHON_UNUSED st
     __pyx_t_3 = (__pyx_v_i + __pyx_v_loc->num_subpatterns);
     for (__pyx_v_j = __pyx_v_i; __pyx_v_j < __pyx_t_3; __pyx_v_j++) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":848
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":850
  *             result = result + "("
  *             for j from i <= j < i + loc.num_subpatterns:
  *                 result = result + ("%d " %loc.arr[j])             # <<<<<<<<<<<<<<
  *             result = result + ")"
  *             i = i + loc.num_subpatterns
  */
-      __pyx_t_2 = __Pyx_GetItemInt(((PyObject *)__pyx_v_loc->arr), __pyx_v_j, sizeof(int), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 848; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(((PyObject *)__pyx_v_loc->arr), __pyx_v_j, sizeof(int), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 850; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_4 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_21), __pyx_t_2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 848; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_21), __pyx_t_2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 850; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(((PyObject *)__pyx_t_4));
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_2 = PyNumber_Add(__pyx_v_result, ((PyObject *)__pyx_t_4)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 848; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_Add(__pyx_v_result, ((PyObject *)__pyx_t_4)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 850; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
       __Pyx_DECREF(__pyx_v_result);
@@ -44245,20 +44313,20 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_loc2str(CYTHON_UNUSED st
       __pyx_t_2 = 0;
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":849
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":851
  *             for j from i <= j < i + loc.num_subpatterns:
  *                 result = result + ("%d " %loc.arr[j])
  *             result = result + ")"             # <<<<<<<<<<<<<<
  *             i = i + loc.num_subpatterns
  *         result = result + "}"
  */
-    __pyx_t_2 = PyNumber_Add(__pyx_v_result, ((PyObject *)__pyx_kp_s_59)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 849; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyNumber_Add(__pyx_v_result, ((PyObject *)__pyx_kp_s_59)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 851; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_v_result);
     __pyx_v_result = __pyx_t_2;
     __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":850
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":852
  *                 result = result + ("%d " %loc.arr[j])
  *             result = result + ")"
  *             i = i + loc.num_subpatterns             # <<<<<<<<<<<<<<
@@ -44268,20 +44336,20 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_loc2str(CYTHON_UNUSED st
     __pyx_v_i = (__pyx_v_i + __pyx_v_loc->num_subpatterns);
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":851
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":853
  *             result = result + ")"
  *             i = i + loc.num_subpatterns
  *         result = result + "}"             # <<<<<<<<<<<<<<
  *         return result
  * 
  */
-  __pyx_t_2 = PyNumber_Add(__pyx_v_result, ((PyObject *)__pyx_kp_s_118)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 851; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyNumber_Add(__pyx_v_result, ((PyObject *)__pyx_kp_s_118)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_v_result);
   __pyx_v_result = __pyx_t_2;
   __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":852
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":854
  *             i = i + loc.num_subpatterns
  *         result = result + "}"
  *         return result             # <<<<<<<<<<<<<<
@@ -44307,7 +44375,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_loc2str(CYTHON_UNUSED st
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":854
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":856
  *         return result
  * 
  *     cdef PhraseLocation intersect(self, prefix_node, suffix_node, Phrase phrase):             # <<<<<<<<<<<<<<
@@ -44333,81 +44401,81 @@ static struct __pyx_obj_3_sa_PhraseLocation *__pyx_f_3_sa_23HieroCachingRuleFact
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("intersect", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":858
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":860
  *         cdef PhraseLocation prefix_loc, suffix_loc, result
  * 
  *         prefix = prefix_node.phrase             # <<<<<<<<<<<<<<
  *         suffix = suffix_node.phrase
  *         prefix_loc = prefix_node.phrase_location
  */
-  __pyx_t_1 = PyObject_GetAttr(__pyx_v_prefix_node, __pyx_n_s__phrase); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 858; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_GetAttr(__pyx_v_prefix_node, __pyx_n_s__phrase); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 860; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_3_sa_Phrase))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 858; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_3_sa_Phrase))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 860; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_v_prefix = ((struct __pyx_obj_3_sa_Phrase *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":859
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":861
  * 
  *         prefix = prefix_node.phrase
  *         suffix = suffix_node.phrase             # <<<<<<<<<<<<<<
  *         prefix_loc = prefix_node.phrase_location
  *         suffix_loc = suffix_node.phrase_location
  */
-  __pyx_t_1 = PyObject_GetAttr(__pyx_v_suffix_node, __pyx_n_s__phrase); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 859; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_GetAttr(__pyx_v_suffix_node, __pyx_n_s__phrase); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_3_sa_Phrase))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 859; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_3_sa_Phrase))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_v_suffix = ((struct __pyx_obj_3_sa_Phrase *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":860
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":862
  *         prefix = prefix_node.phrase
  *         suffix = suffix_node.phrase
  *         prefix_loc = prefix_node.phrase_location             # <<<<<<<<<<<<<<
  *         suffix_loc = suffix_node.phrase_location
  * 
  */
-  __pyx_t_1 = PyObject_GetAttr(__pyx_v_prefix_node, __pyx_n_s__phrase_location); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 860; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_GetAttr(__pyx_v_prefix_node, __pyx_n_s__phrase_location); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 862; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_3_sa_PhraseLocation))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 860; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_3_sa_PhraseLocation))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 862; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_v_prefix_loc = ((struct __pyx_obj_3_sa_PhraseLocation *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":861
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":863
  *         suffix = suffix_node.phrase
  *         prefix_loc = prefix_node.phrase_location
  *         suffix_loc = suffix_node.phrase_location             # <<<<<<<<<<<<<<
  * 
  *         result = self.get_precomputed_collocation(phrase)
  */
-  __pyx_t_1 = PyObject_GetAttr(__pyx_v_suffix_node, __pyx_n_s__phrase_location); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_GetAttr(__pyx_v_suffix_node, __pyx_n_s__phrase_location); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 863; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_3_sa_PhraseLocation))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_3_sa_PhraseLocation))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 863; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_v_suffix_loc = ((struct __pyx_obj_3_sa_PhraseLocation *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":863
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":865
  *         suffix_loc = suffix_node.phrase_location
  * 
  *         result = self.get_precomputed_collocation(phrase)             # <<<<<<<<<<<<<<
  *         if result is not None:
  *             intersect_method = "precomputed"
  */
-  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s_119); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 863; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s_119); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 865; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 863; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 865; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_INCREF(((PyObject *)__pyx_v_phrase));
   PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_v_phrase));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_phrase));
-  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 863; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 865; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
-  if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_3_sa_PhraseLocation))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 863; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_3_sa_PhraseLocation))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 865; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_v_result = ((struct __pyx_obj_3_sa_PhraseLocation *)__pyx_t_3);
   __pyx_t_3 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":864
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":866
  * 
  *         result = self.get_precomputed_collocation(phrase)
  *         if result is not None:             # <<<<<<<<<<<<<<
@@ -44417,7 +44485,7 @@ static struct __pyx_obj_3_sa_PhraseLocation *__pyx_f_3_sa_23HieroCachingRuleFact
   __pyx_t_4 = (((PyObject *)__pyx_v_result) != Py_None);
   if (__pyx_t_4) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":865
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":867
  *         result = self.get_precomputed_collocation(phrase)
  *         if result is not None:
  *             intersect_method = "precomputed"             # <<<<<<<<<<<<<<
@@ -44430,7 +44498,7 @@ static struct __pyx_obj_3_sa_PhraseLocation *__pyx_f_3_sa_23HieroCachingRuleFact
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":867
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":869
  *             intersect_method = "precomputed"
  * 
  *         if result is None:             # <<<<<<<<<<<<<<
@@ -44440,7 +44508,7 @@ static struct __pyx_obj_3_sa_PhraseLocation *__pyx_f_3_sa_23HieroCachingRuleFact
   __pyx_t_4 = (((PyObject *)__pyx_v_result) == Py_None);
   if (__pyx_t_4) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":868
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":870
  * 
  *         if result is None:
  *             if self.use_baeza_yates:             # <<<<<<<<<<<<<<
@@ -44449,21 +44517,21 @@ static struct __pyx_obj_3_sa_PhraseLocation *__pyx_f_3_sa_23HieroCachingRuleFact
  */
     if (__pyx_v_self->use_baeza_yates) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":869
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":871
  *         if result is None:
  *             if self.use_baeza_yates:
  *                 result = self.intersect_helper(prefix, suffix, prefix_loc, suffix_loc, BAEZA_YATES)             # <<<<<<<<<<<<<<
  *                 intersect_method="double binary"
  *             else:
  */
-      __pyx_t_3 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->intersect_helper(__pyx_v_self, __pyx_v_prefix, __pyx_v_suffix, __pyx_v_prefix_loc, __pyx_v_suffix_loc, __pyx_v_3_sa_BAEZA_YATES); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 869; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->intersect_helper(__pyx_v_self, __pyx_v_prefix, __pyx_v_suffix, __pyx_v_prefix_loc, __pyx_v_suffix_loc, __pyx_v_3_sa_BAEZA_YATES); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 871; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
-      if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_3_sa_PhraseLocation))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 869; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_3_sa_PhraseLocation))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 871; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(((PyObject *)__pyx_v_result));
       __pyx_v_result = ((struct __pyx_obj_3_sa_PhraseLocation *)__pyx_t_3);
       __pyx_t_3 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":870
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":872
  *             if self.use_baeza_yates:
  *                 result = self.intersect_helper(prefix, suffix, prefix_loc, suffix_loc, BAEZA_YATES)
  *                 intersect_method="double binary"             # <<<<<<<<<<<<<<
@@ -44477,21 +44545,21 @@ static struct __pyx_obj_3_sa_PhraseLocation *__pyx_f_3_sa_23HieroCachingRuleFact
     }
     /*else*/ {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":872
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":874
  *                 intersect_method="double binary"
  *             else:
  *                 result = self.intersect_helper(prefix, suffix, prefix_loc, suffix_loc, MERGE)             # <<<<<<<<<<<<<<
  *                 intersect_method="merge"
  *         return result
  */
-      __pyx_t_3 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->intersect_helper(__pyx_v_self, __pyx_v_prefix, __pyx_v_suffix, __pyx_v_prefix_loc, __pyx_v_suffix_loc, __pyx_v_3_sa_MERGE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 872; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->intersect_helper(__pyx_v_self, __pyx_v_prefix, __pyx_v_suffix, __pyx_v_prefix_loc, __pyx_v_suffix_loc, __pyx_v_3_sa_MERGE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
-      if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_3_sa_PhraseLocation))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 872; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_3_sa_PhraseLocation))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(((PyObject *)__pyx_v_result));
       __pyx_v_result = ((struct __pyx_obj_3_sa_PhraseLocation *)__pyx_t_3);
       __pyx_t_3 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":873
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":875
  *             else:
  *                 result = self.intersect_helper(prefix, suffix, prefix_loc, suffix_loc, MERGE)
  *                 intersect_method="merge"             # <<<<<<<<<<<<<<
@@ -44507,7 +44575,7 @@ static struct __pyx_obj_3_sa_PhraseLocation *__pyx_f_3_sa_23HieroCachingRuleFact
   }
   __pyx_L4:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":874
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":876
  *                 result = self.intersect_helper(prefix, suffix, prefix_loc, suffix_loc, MERGE)
  *                 intersect_method="merge"
  *         return result             # <<<<<<<<<<<<<<
@@ -44569,16 +44637,16 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_13advance(PyObject *__p
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__res)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("advance", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 876; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("advance", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 878; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__fwords)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("advance", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 876; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("advance", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 878; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "advance") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 876; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "advance") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 878; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
       goto __pyx_L5_argtuple_error;
@@ -44593,7 +44661,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_13advance(PyObject *__p
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("advance", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 876; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("advance", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 878; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.advance", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -44604,7 +44672,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_13advance(PyObject *__p
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":876
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":878
  *         return result
  * 
  *     def advance(self, frontier, res, fwords):             # <<<<<<<<<<<<<<
@@ -44645,19 +44713,19 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("advance", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":878
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":880
  *     def advance(self, frontier, res, fwords):
  *         cdef unsigned na
  *         nf = []             # <<<<<<<<<<<<<<
  *         for (toskip, (i, alt, pathlen)) in frontier:
  *             spanlen = fwords[i][alt][2]
  */
-  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 878; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_nf = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":879
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":881
  *         cdef unsigned na
  *         nf = []
  *         for (toskip, (i, alt, pathlen)) in frontier:             # <<<<<<<<<<<<<<
@@ -44668,7 +44736,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
     __pyx_t_1 = __pyx_v_frontier; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
     __pyx_t_3 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_frontier); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_frontier); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -44676,23 +44744,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
     if (!__pyx_t_3 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_3 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_4 = __pyx_t_3(__pyx_t_1);
       if (unlikely(!__pyx_t_4)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -44708,7 +44776,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
       if (unlikely(size != 2)) {
         if (size > 2) __Pyx_RaiseTooManyValuesError(2);
         else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       }
       #if CYTHON_COMPILING_IN_CPYTHON
       if (likely(PyTuple_CheckExact(sequence))) {
@@ -44721,14 +44789,14 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
       __Pyx_INCREF(__pyx_t_5);
       __Pyx_INCREF(__pyx_t_6);
       #else
-      __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     } else
     {
       Py_ssize_t index = -1;
-      __pyx_t_7 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __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;
@@ -44736,7 +44804,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
       __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_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_t_8 = NULL;
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       goto __pyx_L6_unpacking_done;
@@ -44744,7 +44812,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       __pyx_t_8 = NULL;
       if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_L6_unpacking_done:;
     }
     __Pyx_XDECREF(__pyx_v_toskip);
@@ -44760,7 +44828,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
       if (unlikely(size != 3)) {
         if (size > 3) __Pyx_RaiseTooManyValuesError(3);
         else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       }
       #if CYTHON_COMPILING_IN_CPYTHON
       if (likely(PyTuple_CheckExact(sequence))) {
@@ -44776,15 +44844,15 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
       __Pyx_INCREF(__pyx_t_9);
       __Pyx_INCREF(__pyx_t_10);
       #else
-      __pyx_t_7 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_9 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_10 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_9 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_10 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     } else
     {
       Py_ssize_t index = -1;
-      __pyx_t_11 = PyObject_GetIter(__pyx_t_6); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_11 = PyObject_GetIter(__pyx_t_6); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_11);
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       __pyx_t_8 = Py_TYPE(__pyx_t_11)->tp_iternext;
@@ -44794,7 +44862,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
       __Pyx_GOTREF(__pyx_t_9);
       index = 2; __pyx_t_10 = __pyx_t_8(__pyx_t_11); if (unlikely(!__pyx_t_10)) goto __pyx_L7_unpacking_failed;
       __Pyx_GOTREF(__pyx_t_10);
-      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_11), 3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_11), 3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_t_8 = NULL;
       __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
       goto __pyx_L8_unpacking_done;
@@ -44802,7 +44870,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
       __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
       __pyx_t_8 = NULL;
       if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_L8_unpacking_done:;
     }
     __Pyx_XDECREF(__pyx_v_i);
@@ -44815,45 +44883,45 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
     __pyx_v_pathlen = __pyx_t_10;
     __pyx_t_10 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":880
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":882
  *         nf = []
  *         for (toskip, (i, alt, pathlen)) in frontier:
  *             spanlen = fwords[i][alt][2]             # <<<<<<<<<<<<<<
  *             if (toskip == 0):
  *                 res.append((i, alt, pathlen))
  */
-    __pyx_t_4 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_i); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_i); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 882; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = PyObject_GetItem(__pyx_t_4, __pyx_v_alt); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyObject_GetItem(__pyx_t_4, __pyx_v_alt); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 882; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_6, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_6, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 882; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_XDECREF(__pyx_v_spanlen);
     __pyx_v_spanlen = __pyx_t_4;
     __pyx_t_4 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":881
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":883
  *         for (toskip, (i, alt, pathlen)) in frontier:
  *             spanlen = fwords[i][alt][2]
  *             if (toskip == 0):             # <<<<<<<<<<<<<<
  *                 res.append((i, alt, pathlen))
  *             ni = i + spanlen
  */
-    __pyx_t_4 = PyObject_RichCompare(__pyx_v_toskip, __pyx_int_0, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_12 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_12 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_RichCompare(__pyx_v_toskip, __pyx_int_0, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 883; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_12 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_12 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 883; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     if (__pyx_t_12) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":882
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":884
  *             spanlen = fwords[i][alt][2]
  *             if (toskip == 0):
  *                 res.append((i, alt, pathlen))             # <<<<<<<<<<<<<<
  *             ni = i + spanlen
  *             if (ni < len(fwords) and (pathlen + 1) < self.max_initial_size):
  */
-      __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 882; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 884; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_INCREF(__pyx_v_i);
       PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_i);
@@ -44864,7 +44932,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
       __Pyx_INCREF(__pyx_v_pathlen);
       PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_v_pathlen);
       __Pyx_GIVEREF(__pyx_v_pathlen);
-      __pyx_t_6 = __Pyx_PyObject_Append(__pyx_v_res, ((PyObject *)__pyx_t_4)); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 882; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyObject_Append(__pyx_v_res, ((PyObject *)__pyx_t_4)); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 884; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_6);
       __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
@@ -44872,42 +44940,42 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
     }
     __pyx_L9:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":883
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":885
  *             if (toskip == 0):
  *                 res.append((i, alt, pathlen))
  *             ni = i + spanlen             # <<<<<<<<<<<<<<
  *             if (ni < len(fwords) and (pathlen + 1) < self.max_initial_size):
  *                 for na in range(len(fwords[ni])):
  */
-    __pyx_t_6 = PyNumber_Add(__pyx_v_i, __pyx_v_spanlen); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 883; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyNumber_Add(__pyx_v_i, __pyx_v_spanlen); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_XDECREF(__pyx_v_ni);
     __pyx_v_ni = __pyx_t_6;
     __pyx_t_6 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":884
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":886
  *                 res.append((i, alt, pathlen))
  *             ni = i + spanlen
  *             if (ni < len(fwords) and (pathlen + 1) < self.max_initial_size):             # <<<<<<<<<<<<<<
  *                 for na in range(len(fwords[ni])):
  *                     nf.append((toskip - 1, (ni, na, pathlen + 1)))
  */
-    __pyx_t_13 = PyObject_Length(__pyx_v_fwords); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 884; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_6 = PyInt_FromSsize_t(__pyx_t_13); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 884; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_13 = PyObject_Length(__pyx_v_fwords); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyInt_FromSsize_t(__pyx_t_13); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_4 = PyObject_RichCompare(__pyx_v_ni, __pyx_t_6, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 884; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_RichCompare(__pyx_v_ni, __pyx_t_6, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_12 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_12 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 884; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_12 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_12 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     if (__pyx_t_12) {
-      __pyx_t_4 = PyNumber_Add(__pyx_v_pathlen, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 884; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyNumber_Add(__pyx_v_pathlen, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_6 = PyInt_FromLong(__pyx_v_self->max_initial_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 884; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PyInt_FromLong(__pyx_v_self->max_initial_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_6);
-      __pyx_t_5 = PyObject_RichCompare(__pyx_t_4, __pyx_t_6, Py_LT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 884; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyObject_RichCompare(__pyx_t_4, __pyx_t_6, Py_LT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-      __pyx_t_14 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_14 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 884; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_14 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_14 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       __pyx_t_15 = __pyx_t_14;
     } else {
@@ -44915,34 +44983,34 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
     }
     if (__pyx_t_15) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":885
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":887
  *             ni = i + spanlen
  *             if (ni < len(fwords) and (pathlen + 1) < self.max_initial_size):
  *                 for na in range(len(fwords[ni])):             # <<<<<<<<<<<<<<
  *                     nf.append((toskip - 1, (ni, na, pathlen + 1)))
  *         if (len(nf) > 0):
  */
-      __pyx_t_5 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ni); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ni); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 887; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_13 = PyObject_Length(__pyx_t_5); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_13 = PyObject_Length(__pyx_t_5); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 887; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       for (__pyx_t_16 = 0; __pyx_t_16 < __pyx_t_13; __pyx_t_16+=1) {
         __pyx_v_na = __pyx_t_16;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":886
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":888
  *             if (ni < len(fwords) and (pathlen + 1) < self.max_initial_size):
  *                 for na in range(len(fwords[ni])):
  *                     nf.append((toskip - 1, (ni, na, pathlen + 1)))             # <<<<<<<<<<<<<<
  *         if (len(nf) > 0):
  *             return self.advance(nf, res, fwords)
  */
-        __pyx_t_5 = PyNumber_Subtract(__pyx_v_toskip, __pyx_int_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = PyNumber_Subtract(__pyx_v_toskip, __pyx_int_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_5);
-        __pyx_t_6 = PyLong_FromUnsignedLong(__pyx_v_na); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_6 = PyLong_FromUnsignedLong(__pyx_v_na); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_6);
-        __pyx_t_4 = PyNumber_Add(__pyx_v_pathlen, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyNumber_Add(__pyx_v_pathlen, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_4);
-        __pyx_t_10 = PyTuple_New(3); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_10 = PyTuple_New(3); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_10);
         __Pyx_INCREF(__pyx_v_ni);
         PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_v_ni);
@@ -44953,7 +45021,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
         __Pyx_GIVEREF(__pyx_t_4);
         __pyx_t_6 = 0;
         __pyx_t_4 = 0;
-        __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_4);
         PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_5);
         __Pyx_GIVEREF(__pyx_t_5);
@@ -44961,7 +45029,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
         __Pyx_GIVEREF(((PyObject *)__pyx_t_10));
         __pyx_t_5 = 0;
         __pyx_t_10 = 0;
-        __pyx_t_17 = PyList_Append(__pyx_v_nf, ((PyObject *)__pyx_t_4)); if (unlikely(__pyx_t_17 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_17 = PyList_Append(__pyx_v_nf, ((PyObject *)__pyx_t_4)); if (unlikely(__pyx_t_17 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
       }
       goto __pyx_L10;
@@ -44970,18 +45038,18 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":887
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":889
  *                 for na in range(len(fwords[ni])):
  *                     nf.append((toskip - 1, (ni, na, pathlen + 1)))
  *         if (len(nf) > 0):             # <<<<<<<<<<<<<<
  *             return self.advance(nf, res, fwords)
  *         else:
  */
-  __pyx_t_2 = PyList_GET_SIZE(((PyObject *)__pyx_v_nf)); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 887; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyList_GET_SIZE(((PyObject *)__pyx_v_nf)); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 889; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_t_15 = (__pyx_t_2 > 0);
   if (__pyx_t_15) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":888
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":890
  *                     nf.append((toskip - 1, (ni, na, pathlen + 1)))
  *         if (len(nf) > 0):
  *             return self.advance(nf, res, fwords)             # <<<<<<<<<<<<<<
@@ -44989,9 +45057,9 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
  *             return res
  */
     __Pyx_XDECREF(__pyx_r);
-    __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__advance); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__advance); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 890; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 890; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_INCREF(((PyObject *)__pyx_v_nf));
     PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_v_nf));
@@ -45002,7 +45070,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
     __Pyx_INCREF(__pyx_v_fwords);
     PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_v_fwords);
     __Pyx_GIVEREF(__pyx_v_fwords);
-    __pyx_t_10 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 890; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_10);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
@@ -45013,7 +45081,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12advance(struct __pyx_
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":890
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":892
  *             return self.advance(nf, res, fwords)
  *         else:
  *             return res             # <<<<<<<<<<<<<<
@@ -45091,36 +45159,36 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_15get_all_nodes_isteps_
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__i)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("get_all_nodes_isteps_away", 1, 7, 7, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 892; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("get_all_nodes_isteps_away", 1, 7, 7, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 894; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__spanlen)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("get_all_nodes_isteps_away", 1, 7, 7, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 892; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("get_all_nodes_isteps_away", 1, 7, 7, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 894; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  3:
         if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__pathlen)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("get_all_nodes_isteps_away", 1, 7, 7, 3); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 892; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("get_all_nodes_isteps_away", 1, 7, 7, 3); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 894; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  4:
         if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__fwords)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("get_all_nodes_isteps_away", 1, 7, 7, 4); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 892; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("get_all_nodes_isteps_away", 1, 7, 7, 4); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 894; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  5:
         if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__next_states)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("get_all_nodes_isteps_away", 1, 7, 7, 5); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 892; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("get_all_nodes_isteps_away", 1, 7, 7, 5); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 894; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  6:
         if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__reachable_buffer)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("get_all_nodes_isteps_away", 1, 7, 7, 6); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 892; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("get_all_nodes_isteps_away", 1, 7, 7, 6); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 894; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "get_all_nodes_isteps_away") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 892; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "get_all_nodes_isteps_away") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 894; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 7) {
       goto __pyx_L5_argtuple_error;
@@ -45143,7 +45211,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_15get_all_nodes_isteps_
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("get_all_nodes_isteps_away", 1, 7, 7, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 892; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("get_all_nodes_isteps_away", 1, 7, 7, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 894; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.get_all_nodes_isteps_away", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -45154,7 +45222,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_15get_all_nodes_isteps_
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":892
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":894
  *             return res
  * 
  *     def get_all_nodes_isteps_away(self, skip, i, spanlen, pathlen, fwords, next_states, reachable_buffer):             # <<<<<<<<<<<<<<
@@ -45192,41 +45260,41 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_all_nodes_isteps_away", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":894
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":896
  *     def get_all_nodes_isteps_away(self, skip, i, spanlen, pathlen, fwords, next_states, reachable_buffer):
  *         cdef unsigned alt_it
  *         frontier = []             # <<<<<<<<<<<<<<
  *         if (i+spanlen+skip >= len(next_states)):
  *             return frontier
  */
-  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 896; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_frontier = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":895
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":897
  *         cdef unsigned alt_it
  *         frontier = []
  *         if (i+spanlen+skip >= len(next_states)):             # <<<<<<<<<<<<<<
  *             return frontier
  *         key = tuple([i,spanlen])
  */
-  __pyx_t_1 = PyNumber_Add(__pyx_v_i, __pyx_v_spanlen); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyNumber_Add(__pyx_v_i, __pyx_v_spanlen); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_v_skip); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_v_skip); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_3 = PyObject_Length(__pyx_v_next_states); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Length(__pyx_v_next_states); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_4 = PyObject_RichCompare(__pyx_t_2, __pyx_t_1, Py_GE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyObject_RichCompare(__pyx_t_2, __pyx_t_1, Py_GE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   if (__pyx_t_5) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":896
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":898
  *         frontier = []
  *         if (i+spanlen+skip >= len(next_states)):
  *             return frontier             # <<<<<<<<<<<<<<
@@ -45241,14 +45309,14 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":897
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":899
  *         if (i+spanlen+skip >= len(next_states)):
  *             return frontier
  *         key = tuple([i,spanlen])             # <<<<<<<<<<<<<<
  *         reachable = []
  *         if (key in reachable_buffer):
  */
-  __pyx_t_4 = PyList_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyList_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_INCREF(__pyx_v_i);
   PyList_SET_ITEM(__pyx_t_4, 0, __pyx_v_i);
@@ -45256,42 +45324,42 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
   __Pyx_INCREF(__pyx_v_spanlen);
   PyList_SET_ITEM(__pyx_t_4, 1, __pyx_v_spanlen);
   __Pyx_GIVEREF(__pyx_v_spanlen);
-  __pyx_t_1 = ((PyObject *)PyList_AsTuple(__pyx_t_4)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = ((PyObject *)PyList_AsTuple(__pyx_t_4)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
   __pyx_v_key = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":898
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":900
  *             return frontier
  *         key = tuple([i,spanlen])
  *         reachable = []             # <<<<<<<<<<<<<<
  *         if (key in reachable_buffer):
  *             reachable = reachable_buffer[key]
  */
-  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 898; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 900; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_reachable = ((PyObject *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":899
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":901
  *         key = tuple([i,spanlen])
  *         reachable = []
  *         if (key in reachable_buffer):             # <<<<<<<<<<<<<<
  *             reachable = reachable_buffer[key]
  *         else:
  */
-  __pyx_t_5 = (__Pyx_PySequence_Contains(((PyObject *)__pyx_v_key), __pyx_v_reachable_buffer, Py_EQ)); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = (__Pyx_PySequence_Contains(((PyObject *)__pyx_v_key), __pyx_v_reachable_buffer, Py_EQ)); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 901; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   if (__pyx_t_5) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":900
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":902
  *         reachable = []
  *         if (key in reachable_buffer):
  *             reachable = reachable_buffer[key]             # <<<<<<<<<<<<<<
  *         else:
  *             reachable = self.reachable(fwords, i, spanlen)
  */
-    __pyx_t_1 = PyObject_GetItem(__pyx_v_reachable_buffer, ((PyObject *)__pyx_v_key)); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 900; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_GetItem(__pyx_v_reachable_buffer, ((PyObject *)__pyx_v_key)); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 902; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_v_reachable);
     __pyx_v_reachable = __pyx_t_1;
@@ -45300,16 +45368,16 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":902
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":904
  *             reachable = reachable_buffer[key]
  *         else:
  *             reachable = self.reachable(fwords, i, spanlen)             # <<<<<<<<<<<<<<
  *             reachable_buffer[key] = reachable
  *         for nextreachable in reachable:
  */
-    __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__reachable); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 902; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__reachable); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 902; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_INCREF(__pyx_v_fwords);
     PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_fwords);
@@ -45320,7 +45388,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
     __Pyx_INCREF(__pyx_v_spanlen);
     PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_v_spanlen);
     __Pyx_GIVEREF(__pyx_v_spanlen);
-    __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 902; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
@@ -45328,18 +45396,18 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
     __pyx_v_reachable = __pyx_t_2;
     __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":903
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":905
  *         else:
  *             reachable = self.reachable(fwords, i, spanlen)
  *             reachable_buffer[key] = reachable             # <<<<<<<<<<<<<<
  *         for nextreachable in reachable:
  *             for next_id in next_states[nextreachable]:
  */
-    if (PyObject_SetItem(__pyx_v_reachable_buffer, ((PyObject *)__pyx_v_key), __pyx_v_reachable) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 903; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyObject_SetItem(__pyx_v_reachable_buffer, ((PyObject *)__pyx_v_key), __pyx_v_reachable) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __pyx_L4:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":904
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":906
  *             reachable = self.reachable(fwords, i, spanlen)
  *             reachable_buffer[key] = reachable
  *         for nextreachable in reachable:             # <<<<<<<<<<<<<<
@@ -45350,7 +45418,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
     __pyx_t_2 = __pyx_v_reachable; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0;
     __pyx_t_6 = NULL;
   } else {
-    __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_reachable); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_reachable); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_6 = Py_TYPE(__pyx_t_2)->tp_iternext;
   }
@@ -45358,23 +45426,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
     if (!__pyx_t_6 && PyList_CheckExact(__pyx_t_2)) {
       if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_2)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_4 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_4); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_4); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_6 && PyTuple_CheckExact(__pyx_t_2)) {
       if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_4); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_4); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_4 = __pyx_t_6(__pyx_t_2);
       if (unlikely(!__pyx_t_4)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -45384,20 +45452,20 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
     __pyx_v_nextreachable = __pyx_t_4;
     __pyx_t_4 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":905
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":907
  *             reachable_buffer[key] = reachable
  *         for nextreachable in reachable:
  *             for next_id in next_states[nextreachable]:             # <<<<<<<<<<<<<<
  *                 jump = self.shortest(fwords,i,next_id)
  *                 if jump < skip:
  */
-    __pyx_t_4 = PyObject_GetItem(__pyx_v_next_states, __pyx_v_nextreachable); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_GetItem(__pyx_v_next_states, __pyx_v_nextreachable); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 907; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     if (PyList_CheckExact(__pyx_t_4) || PyTuple_CheckExact(__pyx_t_4)) {
       __pyx_t_1 = __pyx_t_4; __Pyx_INCREF(__pyx_t_1); __pyx_t_7 = 0;
       __pyx_t_8 = NULL;
     } else {
-      __pyx_t_7 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 907; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __pyx_t_8 = Py_TYPE(__pyx_t_1)->tp_iternext;
     }
@@ -45406,23 +45474,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
       if (!__pyx_t_8 && PyList_CheckExact(__pyx_t_1)) {
         if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_1)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_7); __Pyx_INCREF(__pyx_t_4); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_7); __Pyx_INCREF(__pyx_t_4); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 907; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 907; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else if (!__pyx_t_8 && PyTuple_CheckExact(__pyx_t_1)) {
         if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_7); __Pyx_INCREF(__pyx_t_4); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_7); __Pyx_INCREF(__pyx_t_4); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 907; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 907; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else {
         __pyx_t_4 = __pyx_t_8(__pyx_t_1);
         if (unlikely(!__pyx_t_4)) {
           if (PyErr_Occurred()) {
             if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 907; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           }
           break;
         }
@@ -45432,16 +45500,16 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
       __pyx_v_next_id = __pyx_t_4;
       __pyx_t_4 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":906
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":908
  *         for nextreachable in reachable:
  *             for next_id in next_states[nextreachable]:
  *                 jump = self.shortest(fwords,i,next_id)             # <<<<<<<<<<<<<<
  *                 if jump < skip:
  *                     continue
  */
-      __pyx_t_4 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__shortest); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__shortest); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 908; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_9 = PyTuple_New(3); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_9 = PyTuple_New(3); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 908; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_9);
       __Pyx_INCREF(__pyx_v_fwords);
       PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_v_fwords);
@@ -45452,7 +45520,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
       __Pyx_INCREF(__pyx_v_next_id);
       PyTuple_SET_ITEM(__pyx_t_9, 2, __pyx_v_next_id);
       __Pyx_GIVEREF(__pyx_v_next_id);
-      __pyx_t_10 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_10 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 908; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_10);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
@@ -45460,19 +45528,19 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
       __pyx_v_jump = __pyx_t_10;
       __pyx_t_10 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":907
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":909
  *             for next_id in next_states[nextreachable]:
  *                 jump = self.shortest(fwords,i,next_id)
  *                 if jump < skip:             # <<<<<<<<<<<<<<
  *                     continue
  *                 if pathlen+jump <= self.max_initial_size:
  */
-      __pyx_t_10 = PyObject_RichCompare(__pyx_v_jump, __pyx_v_skip, Py_LT); __Pyx_XGOTREF(__pyx_t_10); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 907; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 907; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_10 = PyObject_RichCompare(__pyx_v_jump, __pyx_v_skip, Py_LT); __Pyx_XGOTREF(__pyx_t_10); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 909; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 909; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
       if (__pyx_t_5) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":908
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":910
  *                 jump = self.shortest(fwords,i,next_id)
  *                 if jump < skip:
  *                     continue             # <<<<<<<<<<<<<<
@@ -45484,50 +45552,50 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
       }
       __pyx_L9:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":909
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":911
  *                 if jump < skip:
  *                     continue
  *                 if pathlen+jump <= self.max_initial_size:             # <<<<<<<<<<<<<<
  *                     for alt_id in range(len(fwords[next_id])):
  *                         if (fwords[next_id][alt_id][0] != EPSILON):
  */
-      __pyx_t_10 = PyNumber_Add(__pyx_v_pathlen, __pyx_v_jump); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 909; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_10 = PyNumber_Add(__pyx_v_pathlen, __pyx_v_jump); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_10);
-      __pyx_t_9 = PyInt_FromLong(__pyx_v_self->max_initial_size); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 909; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_9 = PyInt_FromLong(__pyx_v_self->max_initial_size); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_9);
-      __pyx_t_4 = PyObject_RichCompare(__pyx_t_10, __pyx_t_9, Py_LE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 909; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_RichCompare(__pyx_t_10, __pyx_t_9, Py_LE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
       __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 909; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       if (__pyx_t_5) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":910
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":912
  *                     continue
  *                 if pathlen+jump <= self.max_initial_size:
  *                     for alt_id in range(len(fwords[next_id])):             # <<<<<<<<<<<<<<
  *                         if (fwords[next_id][alt_id][0] != EPSILON):
  *                             newel = (next_id,alt_id,pathlen+jump)
  */
-        __pyx_t_4 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_next_id); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_next_id); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 912; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_4);
-        __pyx_t_11 = PyObject_Length(__pyx_t_4); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_11 = PyObject_Length(__pyx_t_4); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 912; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        __pyx_t_4 = PyInt_FromSsize_t(__pyx_t_11); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyInt_FromSsize_t(__pyx_t_11); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 912; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_4);
-        __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 912; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_9);
         PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_4);
         __Pyx_GIVEREF(__pyx_t_4);
         __pyx_t_4 = 0;
-        __pyx_t_4 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 912; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
         if (PyList_CheckExact(__pyx_t_4) || PyTuple_CheckExact(__pyx_t_4)) {
           __pyx_t_9 = __pyx_t_4; __Pyx_INCREF(__pyx_t_9); __pyx_t_11 = 0;
           __pyx_t_12 = NULL;
         } else {
-          __pyx_t_11 = -1; __pyx_t_9 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = -1; __pyx_t_9 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 912; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
           __pyx_t_12 = Py_TYPE(__pyx_t_9)->tp_iternext;
         }
@@ -45536,23 +45604,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
           if (!__pyx_t_12 && PyList_CheckExact(__pyx_t_9)) {
             if (__pyx_t_11 >= PyList_GET_SIZE(__pyx_t_9)) break;
             #if CYTHON_COMPILING_IN_CPYTHON
-            __pyx_t_4 = PyList_GET_ITEM(__pyx_t_9, __pyx_t_11); __Pyx_INCREF(__pyx_t_4); __pyx_t_11++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_4 = PyList_GET_ITEM(__pyx_t_9, __pyx_t_11); __Pyx_INCREF(__pyx_t_4); __pyx_t_11++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 912; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             #else
-            __pyx_t_4 = PySequence_ITEM(__pyx_t_9, __pyx_t_11); __pyx_t_11++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_4 = PySequence_ITEM(__pyx_t_9, __pyx_t_11); __pyx_t_11++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 912; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             #endif
           } else if (!__pyx_t_12 && PyTuple_CheckExact(__pyx_t_9)) {
             if (__pyx_t_11 >= PyTuple_GET_SIZE(__pyx_t_9)) break;
             #if CYTHON_COMPILING_IN_CPYTHON
-            __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_9, __pyx_t_11); __Pyx_INCREF(__pyx_t_4); __pyx_t_11++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_9, __pyx_t_11); __Pyx_INCREF(__pyx_t_4); __pyx_t_11++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 912; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             #else
-            __pyx_t_4 = PySequence_ITEM(__pyx_t_9, __pyx_t_11); __pyx_t_11++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_4 = PySequence_ITEM(__pyx_t_9, __pyx_t_11); __pyx_t_11++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 912; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             #endif
           } else {
             __pyx_t_4 = __pyx_t_12(__pyx_t_9);
             if (unlikely(!__pyx_t_4)) {
               if (PyErr_Occurred()) {
                 if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-                else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 912; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               }
               break;
             }
@@ -45562,40 +45630,40 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
           __pyx_v_alt_id = __pyx_t_4;
           __pyx_t_4 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":911
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":913
  *                 if pathlen+jump <= self.max_initial_size:
  *                     for alt_id in range(len(fwords[next_id])):
  *                         if (fwords[next_id][alt_id][0] != EPSILON):             # <<<<<<<<<<<<<<
  *                             newel = (next_id,alt_id,pathlen+jump)
  *                             if newel not in frontier:
  */
-          __pyx_t_4 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_next_id); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_4 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_next_id); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_4);
-          __pyx_t_10 = PyObject_GetItem(__pyx_t_4, __pyx_v_alt_id); if (!__pyx_t_10) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_10 = PyObject_GetItem(__pyx_t_4, __pyx_v_alt_id); if (!__pyx_t_10) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_10);
           __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-          __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_10, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_10, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_4);
           __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-          __pyx_t_10 = PyInt_FromLong(__pyx_v_3_sa_EPSILON); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_10 = PyInt_FromLong(__pyx_v_3_sa_EPSILON); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_10);
-          __pyx_t_13 = PyObject_RichCompare(__pyx_t_4, __pyx_t_10, Py_NE); __Pyx_XGOTREF(__pyx_t_13); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_13 = PyObject_RichCompare(__pyx_t_4, __pyx_t_10, Py_NE); __Pyx_XGOTREF(__pyx_t_13); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
           __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-          __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_13); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_13); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
           if (__pyx_t_5) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":912
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":914
  *                     for alt_id in range(len(fwords[next_id])):
  *                         if (fwords[next_id][alt_id][0] != EPSILON):
  *                             newel = (next_id,alt_id,pathlen+jump)             # <<<<<<<<<<<<<<
  *                             if newel not in frontier:
  *                                 frontier.append((next_id,alt_id,pathlen+jump))
  */
-            __pyx_t_13 = PyNumber_Add(__pyx_v_pathlen, __pyx_v_jump); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 912; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_13 = PyNumber_Add(__pyx_v_pathlen, __pyx_v_jump); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_13);
-            __pyx_t_10 = PyTuple_New(3); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 912; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_10 = PyTuple_New(3); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_10);
             __Pyx_INCREF(__pyx_v_next_id);
             PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_v_next_id);
@@ -45610,26 +45678,26 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
             __pyx_v_newel = __pyx_t_10;
             __pyx_t_10 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":913
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":915
  *                         if (fwords[next_id][alt_id][0] != EPSILON):
  *                             newel = (next_id,alt_id,pathlen+jump)
  *                             if newel not in frontier:             # <<<<<<<<<<<<<<
  *                                 frontier.append((next_id,alt_id,pathlen+jump))
  *         return frontier
  */
-            __pyx_t_5 = (__Pyx_PySequence_Contains(((PyObject *)__pyx_v_newel), ((PyObject *)__pyx_v_frontier), Py_NE)); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_5 = (__Pyx_PySequence_Contains(((PyObject *)__pyx_v_newel), ((PyObject *)__pyx_v_frontier), Py_NE)); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 915; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             if (__pyx_t_5) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":914
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":916
  *                             newel = (next_id,alt_id,pathlen+jump)
  *                             if newel not in frontier:
  *                                 frontier.append((next_id,alt_id,pathlen+jump))             # <<<<<<<<<<<<<<
  *         return frontier
  * 
  */
-              __pyx_t_10 = PyNumber_Add(__pyx_v_pathlen, __pyx_v_jump); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_10 = PyNumber_Add(__pyx_v_pathlen, __pyx_v_jump); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 916; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_10);
-              __pyx_t_13 = PyTuple_New(3); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_13 = PyTuple_New(3); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 916; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_13);
               __Pyx_INCREF(__pyx_v_next_id);
               PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_v_next_id);
@@ -45640,7 +45708,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
               PyTuple_SET_ITEM(__pyx_t_13, 2, __pyx_t_10);
               __Pyx_GIVEREF(__pyx_t_10);
               __pyx_t_10 = 0;
-              __pyx_t_14 = PyList_Append(__pyx_v_frontier, ((PyObject *)__pyx_t_13)); if (unlikely(__pyx_t_14 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_14 = PyList_Append(__pyx_v_frontier, ((PyObject *)__pyx_t_13)); if (unlikely(__pyx_t_14 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 916; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_DECREF(((PyObject *)__pyx_t_13)); __pyx_t_13 = 0;
               goto __pyx_L14;
             }
@@ -45659,7 +45727,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_14get_all_nodes_isteps_
   }
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":915
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":917
  *                             if newel not in frontier:
  *                                 frontier.append((next_id,alt_id,pathlen+jump))
  *         return frontier             # <<<<<<<<<<<<<<
@@ -45726,16 +45794,16 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_17reachable(PyObject *_
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__ifrom)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("reachable", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 917; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("reachable", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 919; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__dist)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("reachable", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 917; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("reachable", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 919; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reachable") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 917; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reachable") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 919; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
       goto __pyx_L5_argtuple_error;
@@ -45750,7 +45818,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_17reachable(PyObject *_
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("reachable", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 917; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("reachable", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 919; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.reachable", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -45761,7 +45829,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_17reachable(PyObject *_
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":917
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":919
  *         return frontier
  * 
  *     def reachable(self, fwords, ifrom, dist):             # <<<<<<<<<<<<<<
@@ -45791,35 +45859,35 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_16reachable(struct __py
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("reachable", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":918
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":920
  * 
  *     def reachable(self, fwords, ifrom, dist):
  *         ret = []             # <<<<<<<<<<<<<<
  *         if (ifrom >= len(fwords)):
  *             return ret
  */
-  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 920; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_ret = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":919
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":921
  *     def reachable(self, fwords, ifrom, dist):
  *         ret = []
  *         if (ifrom >= len(fwords)):             # <<<<<<<<<<<<<<
  *             return ret
  *         for alt_id in range(len(fwords[ifrom])):
  */
-  __pyx_t_2 = PyObject_Length(__pyx_v_fwords); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 919; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 919; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Length(__pyx_v_fwords); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyObject_RichCompare(__pyx_v_ifrom, __pyx_t_1, Py_GE); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 919; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_RichCompare(__pyx_v_ifrom, __pyx_t_1, Py_GE); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 919; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   if (__pyx_t_4) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":920
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":922
  *         ret = []
  *         if (ifrom >= len(fwords)):
  *             return ret             # <<<<<<<<<<<<<<
@@ -45834,32 +45902,32 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_16reachable(struct __py
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":921
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":923
  *         if (ifrom >= len(fwords)):
  *             return ret
  *         for alt_id in range(len(fwords[ifrom])):             # <<<<<<<<<<<<<<
  *             if (fwords[ifrom][alt_id][0] == EPSILON):
  *                 ret.extend(self.reachable(fwords,ifrom+fwords[ifrom][alt_id][2],dist))
  */
-  __pyx_t_3 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ifrom); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ifrom); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_2 = PyObject_Length(__pyx_t_3); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Length(__pyx_t_3); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_3 = PyInt_FromSsize_t(__pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyInt_FromSsize_t(__pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_3);
   __Pyx_GIVEREF(__pyx_t_3);
   __pyx_t_3 = 0;
-  __pyx_t_3 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
   if (PyList_CheckExact(__pyx_t_3) || PyTuple_CheckExact(__pyx_t_3)) {
     __pyx_t_1 = __pyx_t_3; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
     __pyx_t_5 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_5 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -45868,23 +45936,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_16reachable(struct __py
     if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_3 = __pyx_t_5(__pyx_t_1);
       if (unlikely(!__pyx_t_3)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -45894,53 +45962,53 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_16reachable(struct __py
     __pyx_v_alt_id = __pyx_t_3;
     __pyx_t_3 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":922
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":924
  *             return ret
  *         for alt_id in range(len(fwords[ifrom])):
  *             if (fwords[ifrom][alt_id][0] == EPSILON):             # <<<<<<<<<<<<<<
  *                 ret.extend(self.reachable(fwords,ifrom+fwords[ifrom][alt_id][2],dist))
  *             else:
  */
-    __pyx_t_3 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ifrom); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ifrom); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_6 = PyObject_GetItem(__pyx_t_3, __pyx_v_alt_id); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyObject_GetItem(__pyx_t_3, __pyx_v_alt_id); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_6, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_6, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = PyInt_FromLong(__pyx_v_3_sa_EPSILON); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyInt_FromLong(__pyx_v_3_sa_EPSILON); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_7 = PyObject_RichCompare(__pyx_t_3, __pyx_t_6, Py_EQ); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyObject_RichCompare(__pyx_t_3, __pyx_t_6, Py_EQ); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     if (__pyx_t_4) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":923
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":925
  *         for alt_id in range(len(fwords[ifrom])):
  *             if (fwords[ifrom][alt_id][0] == EPSILON):
  *                 ret.extend(self.reachable(fwords,ifrom+fwords[ifrom][alt_id][2],dist))             # <<<<<<<<<<<<<<
  *             else:
  *                 if (dist==0):
  */
-      __pyx_t_7 = PyObject_GetAttr(((PyObject *)__pyx_v_ret), __pyx_n_s__extend); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyObject_GetAttr(((PyObject *)__pyx_v_ret), __pyx_n_s__extend); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_7);
-      __pyx_t_6 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__reachable); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__reachable); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_6);
-      __pyx_t_3 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ifrom); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ifrom); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_8 = PyObject_GetItem(__pyx_t_3, __pyx_v_alt_id); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyObject_GetItem(__pyx_t_3, __pyx_v_alt_id); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_8, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_8, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-      __pyx_t_8 = PyNumber_Add(__pyx_v_ifrom, __pyx_t_3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyNumber_Add(__pyx_v_ifrom, __pyx_t_3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_INCREF(__pyx_v_fwords);
       PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_fwords);
@@ -45951,16 +46019,16 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_16reachable(struct __py
       PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_v_dist);
       __Pyx_GIVEREF(__pyx_v_dist);
       __pyx_t_8 = 0;
-      __pyx_t_8 = PyObject_Call(__pyx_t_6, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyObject_Call(__pyx_t_6, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
-      __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_8);
       __Pyx_GIVEREF(__pyx_t_8);
       __pyx_t_8 = 0;
-      __pyx_t_8 = PyObject_Call(__pyx_t_7, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyObject_Call(__pyx_t_7, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
@@ -45969,36 +46037,36 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_16reachable(struct __py
     }
     /*else*/ {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":925
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":927
  *                 ret.extend(self.reachable(fwords,ifrom+fwords[ifrom][alt_id][2],dist))
  *             else:
  *                 if (dist==0):             # <<<<<<<<<<<<<<
  *                     if (ifrom not in ret):
  *                         ret.append(ifrom)
  */
-      __pyx_t_8 = PyObject_RichCompare(__pyx_v_dist, __pyx_int_0, Py_EQ); __Pyx_XGOTREF(__pyx_t_8); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyObject_RichCompare(__pyx_v_dist, __pyx_int_0, Py_EQ); __Pyx_XGOTREF(__pyx_t_8); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 927; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 927; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       if (__pyx_t_4) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":926
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":928
  *             else:
  *                 if (dist==0):
  *                     if (ifrom not in ret):             # <<<<<<<<<<<<<<
  *                         ret.append(ifrom)
  *                 else:
  */
-        __pyx_t_4 = (__Pyx_PySequence_Contains(__pyx_v_ifrom, ((PyObject *)__pyx_v_ret), Py_NE)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 926; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = (__Pyx_PySequence_Contains(__pyx_v_ifrom, ((PyObject *)__pyx_v_ret), Py_NE)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 928; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         if (__pyx_t_4) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":927
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":929
  *                 if (dist==0):
  *                     if (ifrom not in ret):
  *                         ret.append(ifrom)             # <<<<<<<<<<<<<<
  *                 else:
  *                     for ifromchild in self.reachable(fwords,ifrom+fwords[ifrom][alt_id][2],dist-1):
  */
-          __pyx_t_9 = PyList_Append(__pyx_v_ret, __pyx_v_ifrom); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 927; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyList_Append(__pyx_v_ret, __pyx_v_ifrom); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           goto __pyx_L8;
         }
         __pyx_L8:;
@@ -46006,29 +46074,29 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_16reachable(struct __py
       }
       /*else*/ {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":929
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":931
  *                         ret.append(ifrom)
  *                 else:
  *                     for ifromchild in self.reachable(fwords,ifrom+fwords[ifrom][alt_id][2],dist-1):             # <<<<<<<<<<<<<<
  *                         if (ifromchild not in ret):
  *                             ret.append(ifromchild)
  */
-        __pyx_t_8 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__reachable); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_8 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__reachable); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_8);
-        __pyx_t_3 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ifrom); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ifrom); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_3);
-        __pyx_t_7 = PyObject_GetItem(__pyx_t_3, __pyx_v_alt_id); if (!__pyx_t_7) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PyObject_GetItem(__pyx_t_3, __pyx_v_alt_id); if (!__pyx_t_7) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_7);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_7, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_7, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-        __pyx_t_7 = PyNumber_Add(__pyx_v_ifrom, __pyx_t_3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PyNumber_Add(__pyx_v_ifrom, __pyx_t_3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_7);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_3 = PyNumber_Subtract(__pyx_v_dist, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = PyNumber_Subtract(__pyx_v_dist, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_3);
-        __pyx_t_6 = PyTuple_New(3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_6 = PyTuple_New(3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_6);
         __Pyx_INCREF(__pyx_v_fwords);
         PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_v_fwords);
@@ -46039,7 +46107,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_16reachable(struct __py
         __Pyx_GIVEREF(__pyx_t_3);
         __pyx_t_7 = 0;
         __pyx_t_3 = 0;
-        __pyx_t_3 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
         __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
@@ -46047,7 +46115,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_16reachable(struct __py
           __pyx_t_6 = __pyx_t_3; __Pyx_INCREF(__pyx_t_6); __pyx_t_10 = 0;
           __pyx_t_11 = NULL;
         } else {
-          __pyx_t_10 = -1; __pyx_t_6 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_10 = -1; __pyx_t_6 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_6);
           __pyx_t_11 = Py_TYPE(__pyx_t_6)->tp_iternext;
         }
@@ -46056,23 +46124,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_16reachable(struct __py
           if (!__pyx_t_11 && PyList_CheckExact(__pyx_t_6)) {
             if (__pyx_t_10 >= PyList_GET_SIZE(__pyx_t_6)) break;
             #if CYTHON_COMPILING_IN_CPYTHON
-            __pyx_t_3 = PyList_GET_ITEM(__pyx_t_6, __pyx_t_10); __Pyx_INCREF(__pyx_t_3); __pyx_t_10++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = PyList_GET_ITEM(__pyx_t_6, __pyx_t_10); __Pyx_INCREF(__pyx_t_3); __pyx_t_10++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             #else
-            __pyx_t_3 = PySequence_ITEM(__pyx_t_6, __pyx_t_10); __pyx_t_10++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = PySequence_ITEM(__pyx_t_6, __pyx_t_10); __pyx_t_10++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             #endif
           } else if (!__pyx_t_11 && PyTuple_CheckExact(__pyx_t_6)) {
             if (__pyx_t_10 >= PyTuple_GET_SIZE(__pyx_t_6)) break;
             #if CYTHON_COMPILING_IN_CPYTHON
-            __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_6, __pyx_t_10); __Pyx_INCREF(__pyx_t_3); __pyx_t_10++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_6, __pyx_t_10); __Pyx_INCREF(__pyx_t_3); __pyx_t_10++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             #else
-            __pyx_t_3 = PySequence_ITEM(__pyx_t_6, __pyx_t_10); __pyx_t_10++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = PySequence_ITEM(__pyx_t_6, __pyx_t_10); __pyx_t_10++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             #endif
           } else {
             __pyx_t_3 = __pyx_t_11(__pyx_t_6);
             if (unlikely(!__pyx_t_3)) {
               if (PyErr_Occurred()) {
                 if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-                else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               }
               break;
             }
@@ -46082,24 +46150,24 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_16reachable(struct __py
           __pyx_v_ifromchild = __pyx_t_3;
           __pyx_t_3 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":930
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":932
  *                 else:
  *                     for ifromchild in self.reachable(fwords,ifrom+fwords[ifrom][alt_id][2],dist-1):
  *                         if (ifromchild not in ret):             # <<<<<<<<<<<<<<
  *                             ret.append(ifromchild)
  * 
  */
-          __pyx_t_4 = (__Pyx_PySequence_Contains(__pyx_v_ifromchild, ((PyObject *)__pyx_v_ret), Py_NE)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 930; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_4 = (__Pyx_PySequence_Contains(__pyx_v_ifromchild, ((PyObject *)__pyx_v_ret), Py_NE)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 932; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           if (__pyx_t_4) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":931
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":933
  *                     for ifromchild in self.reachable(fwords,ifrom+fwords[ifrom][alt_id][2],dist-1):
  *                         if (ifromchild not in ret):
  *                             ret.append(ifromchild)             # <<<<<<<<<<<<<<
  * 
  *         return ret
  */
-            __pyx_t_9 = PyList_Append(__pyx_v_ret, __pyx_v_ifromchild); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_9 = PyList_Append(__pyx_v_ret, __pyx_v_ifromchild); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 933; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             goto __pyx_L11;
           }
           __pyx_L11:;
@@ -46112,7 +46180,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_16reachable(struct __py
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":933
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":935
  *                             ret.append(ifromchild)
  * 
  *         return ret             # <<<<<<<<<<<<<<
@@ -46173,16 +46241,16 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_19shortest(PyObject *__
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__ifrom)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("shortest", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 935; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("shortest", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 937; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__ito)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("shortest", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 935; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("shortest", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 937; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "shortest") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 935; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "shortest") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 937; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
       goto __pyx_L5_argtuple_error;
@@ -46197,7 +46265,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_19shortest(PyObject *__
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("shortest", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 935; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("shortest", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 937; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.shortest", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -46208,7 +46276,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_19shortest(PyObject *__
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":935
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":937
  *         return ret
  * 
  *     def shortest(self, fwords, ifrom, ito):             # <<<<<<<<<<<<<<
@@ -46233,7 +46301,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_18shortest(struct __pyx
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("shortest", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":937
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":939
  *     def shortest(self, fwords, ifrom, ito):
  *         cdef unsigned alt_id
  *         min = 1000             # <<<<<<<<<<<<<<
@@ -46243,19 +46311,19 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_18shortest(struct __pyx
   __Pyx_INCREF(__pyx_int_1000);
   __pyx_v_min = __pyx_int_1000;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":938
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":940
  *         cdef unsigned alt_id
  *         min = 1000
  *         if (ifrom > ito):             # <<<<<<<<<<<<<<
  *             return min
  *         if (ifrom == ito):
  */
-  __pyx_t_1 = PyObject_RichCompare(__pyx_v_ifrom, __pyx_v_ito, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_RichCompare(__pyx_v_ifrom, __pyx_v_ito, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   if (__pyx_t_2) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":939
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":941
  *         min = 1000
  *         if (ifrom > ito):
  *             return min             # <<<<<<<<<<<<<<
@@ -46270,19 +46338,19 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_18shortest(struct __pyx
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":940
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":942
  *         if (ifrom > ito):
  *             return min
  *         if (ifrom == ito):             # <<<<<<<<<<<<<<
  *             return 0
  *         for alt_id in range(len(fwords[ifrom])):
  */
-  __pyx_t_1 = PyObject_RichCompare(__pyx_v_ifrom, __pyx_v_ito, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_RichCompare(__pyx_v_ifrom, __pyx_v_ito, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 942; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 942; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   if (__pyx_t_2) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":941
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":943
  *             return min
  *         if (ifrom == ito):
  *             return 0             # <<<<<<<<<<<<<<
@@ -46297,41 +46365,41 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_18shortest(struct __pyx
   }
   __pyx_L4:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":942
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":944
  *         if (ifrom == ito):
  *             return 0
  *         for alt_id in range(len(fwords[ifrom])):             # <<<<<<<<<<<<<<
  *             currmin = self.shortest(fwords,ifrom+fwords[ifrom][alt_id][2],ito)
  *             if (fwords[ifrom][alt_id][0] != EPSILON):
  */
-  __pyx_t_1 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ifrom); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 942; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ifrom); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 942; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
     __pyx_v_alt_id = __pyx_t_4;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":943
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":945
  *             return 0
  *         for alt_id in range(len(fwords[ifrom])):
  *             currmin = self.shortest(fwords,ifrom+fwords[ifrom][alt_id][2],ito)             # <<<<<<<<<<<<<<
  *             if (fwords[ifrom][alt_id][0] != EPSILON):
  *                 currmin += 1
  */
-    __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__shortest); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__shortest); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_5 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ifrom); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ifrom); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_6 = __Pyx_GetItemInt(__pyx_t_5, __pyx_v_alt_id, sizeof(unsigned int)+1, PyLong_FromUnsignedLong); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = __Pyx_GetItemInt(__pyx_t_5, __pyx_v_alt_id, sizeof(unsigned int)+1, PyLong_FromUnsignedLong); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __pyx_t_5 = __Pyx_GetItemInt(__pyx_t_6, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_GetItemInt(__pyx_t_6, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = PyNumber_Add(__pyx_v_ifrom, __pyx_t_5); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyNumber_Add(__pyx_v_ifrom, __pyx_t_5); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_INCREF(__pyx_v_fwords);
     PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_fwords);
@@ -46342,7 +46410,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_18shortest(struct __pyx
     PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_v_ito);
     __Pyx_GIVEREF(__pyx_v_ito);
     __pyx_t_6 = 0;
-    __pyx_t_6 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
@@ -46350,38 +46418,38 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_18shortest(struct __pyx
     __pyx_v_currmin = __pyx_t_6;
     __pyx_t_6 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":944
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":946
  *         for alt_id in range(len(fwords[ifrom])):
  *             currmin = self.shortest(fwords,ifrom+fwords[ifrom][alt_id][2],ito)
  *             if (fwords[ifrom][alt_id][0] != EPSILON):             # <<<<<<<<<<<<<<
  *                 currmin += 1
  *             if (currmin<min):
  */
-    __pyx_t_6 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ifrom); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyObject_GetItem(__pyx_v_fwords, __pyx_v_ifrom); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_5 = __Pyx_GetItemInt(__pyx_t_6, __pyx_v_alt_id, sizeof(unsigned int)+1, PyLong_FromUnsignedLong); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_GetItemInt(__pyx_t_6, __pyx_v_alt_id, sizeof(unsigned int)+1, PyLong_FromUnsignedLong); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = __Pyx_GetItemInt(__pyx_t_5, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = __Pyx_GetItemInt(__pyx_t_5, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __pyx_t_5 = PyInt_FromLong(__pyx_v_3_sa_EPSILON); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyInt_FromLong(__pyx_v_3_sa_EPSILON); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_1 = PyObject_RichCompare(__pyx_t_6, __pyx_t_5, Py_NE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_RichCompare(__pyx_t_6, __pyx_t_5, Py_NE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     if (__pyx_t_2) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":945
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":947
  *             currmin = self.shortest(fwords,ifrom+fwords[ifrom][alt_id][2],ito)
  *             if (fwords[ifrom][alt_id][0] != EPSILON):
  *                 currmin += 1             # <<<<<<<<<<<<<<
  *             if (currmin<min):
  *                 min = currmin
  */
-      __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_currmin, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_currmin, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_v_currmin);
       __pyx_v_currmin = __pyx_t_1;
@@ -46390,19 +46458,19 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_18shortest(struct __pyx
     }
     __pyx_L7:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":946
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":948
  *             if (fwords[ifrom][alt_id][0] != EPSILON):
  *                 currmin += 1
  *             if (currmin<min):             # <<<<<<<<<<<<<<
  *                 min = currmin
  *         return min
  */
-    __pyx_t_1 = PyObject_RichCompare(__pyx_v_currmin, __pyx_v_min, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_RichCompare(__pyx_v_currmin, __pyx_v_min, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 948; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 948; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     if (__pyx_t_2) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":947
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":949
  *                 currmin += 1
  *             if (currmin<min):
  *                 min = currmin             # <<<<<<<<<<<<<<
@@ -46417,7 +46485,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_18shortest(struct __pyx
     __pyx_L8:;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":948
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":950
  *             if (currmin<min):
  *                 min = currmin
  *         return min             # <<<<<<<<<<<<<<
@@ -46476,7 +46544,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_21get_next_states(PyObj
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__curr_idx)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("get_next_states", 0, 2, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 950; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("get_next_states", 0, 2, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 952; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (kw_args > 0) {
@@ -46485,7 +46553,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_21get_next_states(PyObj
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "get_next_states") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 950; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "get_next_states") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 952; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -46502,7 +46570,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_21get_next_states(PyObj
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("get_next_states", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 950; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("get_next_states", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 952; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.get_next_states", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -46513,7 +46581,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_21get_next_states(PyObj
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":950
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":952
  *         return min
  * 
  *     def get_next_states(self, _columns, curr_idx, min_dist=2):             # <<<<<<<<<<<<<<
@@ -46546,26 +46614,26 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_next_states", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":951
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":953
  * 
  *     def get_next_states(self, _columns, curr_idx, min_dist=2):
  *         result = []             # <<<<<<<<<<<<<<
  *         candidate = [[curr_idx,0]]
  * 
  */
-  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 951; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_result = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":952
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":954
  *     def get_next_states(self, _columns, curr_idx, min_dist=2):
  *         result = []
  *         candidate = [[curr_idx,0]]             # <<<<<<<<<<<<<<
  * 
  *         while len(candidate) > 0:
  */
-  __pyx_t_1 = PyList_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 952; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyList_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 954; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(__pyx_v_curr_idx);
   PyList_SET_ITEM(__pyx_t_1, 0, __pyx_v_curr_idx);
@@ -46573,7 +46641,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
   __Pyx_INCREF(__pyx_int_0);
   PyList_SET_ITEM(__pyx_t_1, 1, __pyx_int_0);
   __Pyx_GIVEREF(__pyx_int_0);
-  __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 952; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 954; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   PyList_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_t_1));
   __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
@@ -46581,7 +46649,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
   __pyx_v_candidate = __pyx_t_2;
   __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":954
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":956
  *         candidate = [[curr_idx,0]]
  * 
  *         while len(candidate) > 0:             # <<<<<<<<<<<<<<
@@ -46589,43 +46657,43 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
  *             if curr[0] >= len(_columns):
  */
   while (1) {
-    __pyx_t_3 = PyList_GET_SIZE(((PyObject *)__pyx_v_candidate)); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 954; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyList_GET_SIZE(((PyObject *)__pyx_v_candidate)); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __pyx_t_4 = (__pyx_t_3 > 0);
     if (!__pyx_t_4) break;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":955
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":957
  * 
  *         while len(candidate) > 0:
  *             curr = candidate.pop()             # <<<<<<<<<<<<<<
  *             if curr[0] >= len(_columns):
  *                 continue
  */
-    __pyx_t_2 = __Pyx_PyObject_Pop(((PyObject *)__pyx_v_candidate)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 955; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_PyObject_Pop(((PyObject *)__pyx_v_candidate)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_XDECREF(__pyx_v_curr);
     __pyx_v_curr = __pyx_t_2;
     __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":956
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":958
  *         while len(candidate) > 0:
  *             curr = candidate.pop()
  *             if curr[0] >= len(_columns):             # <<<<<<<<<<<<<<
  *                 continue
  *             if curr[0] not in result and min_dist <= curr[1] <= self.max_initial_size:
  */
-    __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_curr, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_curr, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 958; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_3 = PyObject_Length(__pyx_v__columns); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_Length(__pyx_v__columns); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 958; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 958; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_5 = PyObject_RichCompare(__pyx_t_2, __pyx_t_1, Py_GE); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyObject_RichCompare(__pyx_t_2, __pyx_t_1, Py_GE); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 958; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 958; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     if (__pyx_t_4) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":957
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":959
  *             curr = candidate.pop()
  *             if curr[0] >= len(_columns):
  *                 continue             # <<<<<<<<<<<<<<
@@ -46637,30 +46705,30 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
     }
     __pyx_L5:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":958
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":960
  *             if curr[0] >= len(_columns):
  *                 continue
  *             if curr[0] not in result and min_dist <= curr[1] <= self.max_initial_size:             # <<<<<<<<<<<<<<
  *                 result.append(curr[0]);
  *             curr_col = _columns[curr[0]]
  */
-    __pyx_t_5 = __Pyx_GetItemInt(__pyx_v_curr, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 958; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_GetItemInt(__pyx_v_curr, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 960; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_4 = (__Pyx_PySequence_Contains(__pyx_t_5, ((PyObject *)__pyx_v_result), Py_NE)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 958; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = (__Pyx_PySequence_Contains(__pyx_t_5, ((PyObject *)__pyx_v_result), Py_NE)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 960; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     if (__pyx_t_4) {
-      __pyx_t_5 = __Pyx_GetItemInt(__pyx_v_curr, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 958; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = __Pyx_GetItemInt(__pyx_v_curr, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 960; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_1 = PyObject_RichCompare(__pyx_v_min_dist, __pyx_t_5, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 958; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_RichCompare(__pyx_v_min_dist, __pyx_t_5, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 960; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       if (__Pyx_PyObject_IsTrue(__pyx_t_1)) {
         __Pyx_DECREF(__pyx_t_1);
-        __pyx_t_2 = PyInt_FromLong(__pyx_v_self->max_initial_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 958; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_2 = PyInt_FromLong(__pyx_v_self->max_initial_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 960; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
-        __pyx_t_1 = PyObject_RichCompare(__pyx_t_5, __pyx_t_2, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 958; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyObject_RichCompare(__pyx_t_5, __pyx_t_2, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 960; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       }
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 958; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 960; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       __pyx_t_7 = __pyx_t_6;
     } else {
@@ -46668,38 +46736,38 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
     }
     if (__pyx_t_7) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":959
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":961
  *                 continue
  *             if curr[0] not in result and min_dist <= curr[1] <= self.max_initial_size:
  *                 result.append(curr[0]);             # <<<<<<<<<<<<<<
  *             curr_col = _columns[curr[0]]
  *             for alt in curr_col:
  */
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_curr, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 959; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_curr, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_8 = PyList_Append(__pyx_v_result, __pyx_t_1); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 959; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyList_Append(__pyx_v_result, __pyx_t_1); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       goto __pyx_L6;
     }
     __pyx_L6:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":960
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":962
  *             if curr[0] not in result and min_dist <= curr[1] <= self.max_initial_size:
  *                 result.append(curr[0]);
  *             curr_col = _columns[curr[0]]             # <<<<<<<<<<<<<<
  *             for alt in curr_col:
  *                 next_id = curr[0]+alt[2]
  */
-    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_curr, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 960; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_curr, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 962; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_5 = PyObject_GetItem(__pyx_v__columns, __pyx_t_1); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 960; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyObject_GetItem(__pyx_v__columns, __pyx_t_1); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 962; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_XDECREF(__pyx_v_curr_col);
     __pyx_v_curr_col = __pyx_t_5;
     __pyx_t_5 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":961
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":963
  *                 result.append(curr[0]);
  *             curr_col = _columns[curr[0]]
  *             for alt in curr_col:             # <<<<<<<<<<<<<<
@@ -46710,7 +46778,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
       __pyx_t_5 = __pyx_v_curr_col; __Pyx_INCREF(__pyx_t_5); __pyx_t_3 = 0;
       __pyx_t_9 = NULL;
     } else {
-      __pyx_t_3 = -1; __pyx_t_5 = PyObject_GetIter(__pyx_v_curr_col); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = -1; __pyx_t_5 = PyObject_GetIter(__pyx_v_curr_col); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 963; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
       __pyx_t_9 = Py_TYPE(__pyx_t_5)->tp_iternext;
     }
@@ -46718,23 +46786,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
       if (!__pyx_t_9 && PyList_CheckExact(__pyx_t_5)) {
         if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_5)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_1 = PyList_GET_ITEM(__pyx_t_5, __pyx_t_3); __Pyx_INCREF(__pyx_t_1); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyList_GET_ITEM(__pyx_t_5, __pyx_t_3); __Pyx_INCREF(__pyx_t_1); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 963; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_1 = PySequence_ITEM(__pyx_t_5, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PySequence_ITEM(__pyx_t_5, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 963; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else if (!__pyx_t_9 && PyTuple_CheckExact(__pyx_t_5)) {
         if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_5)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_5, __pyx_t_3); __Pyx_INCREF(__pyx_t_1); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_5, __pyx_t_3); __Pyx_INCREF(__pyx_t_1); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 963; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_1 = PySequence_ITEM(__pyx_t_5, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PySequence_ITEM(__pyx_t_5, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 963; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else {
         __pyx_t_1 = __pyx_t_9(__pyx_t_5);
         if (unlikely(!__pyx_t_1)) {
           if (PyErr_Occurred()) {
             if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 963; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           }
           break;
         }
@@ -46744,18 +46812,18 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
       __pyx_v_alt = __pyx_t_1;
       __pyx_t_1 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":962
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":964
  *             curr_col = _columns[curr[0]]
  *             for alt in curr_col:
  *                 next_id = curr[0]+alt[2]             # <<<<<<<<<<<<<<
  *                 jump = 1
  *                 if (alt[0] == EPSILON):
  */
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_curr, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 962; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_curr, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 964; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_alt, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 962; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_alt, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 964; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_10 = PyNumber_Add(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 962; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_10 = PyNumber_Add(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 964; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_10);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -46763,7 +46831,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
       __pyx_v_next_id = __pyx_t_10;
       __pyx_t_10 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":963
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":965
  *             for alt in curr_col:
  *                 next_id = curr[0]+alt[2]
  *                 jump = 1             # <<<<<<<<<<<<<<
@@ -46774,25 +46842,25 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
       __Pyx_XDECREF(__pyx_v_jump);
       __pyx_v_jump = __pyx_int_1;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":964
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":966
  *                 next_id = curr[0]+alt[2]
  *                 jump = 1
  *                 if (alt[0] == EPSILON):             # <<<<<<<<<<<<<<
  *                     jump = 0
  *                 if next_id not in result and min_dist <= curr[1]+jump <= self.max_initial_size+1:
  */
-      __pyx_t_10 = __Pyx_GetItemInt(__pyx_v_alt, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_10) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 964; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_10 = __Pyx_GetItemInt(__pyx_v_alt, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_10) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_10);
-      __pyx_t_2 = PyInt_FromLong(__pyx_v_3_sa_EPSILON); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 964; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyInt_FromLong(__pyx_v_3_sa_EPSILON); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_1 = PyObject_RichCompare(__pyx_t_10, __pyx_t_2, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 964; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_RichCompare(__pyx_t_10, __pyx_t_2, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 964; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       if (__pyx_t_7) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":965
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":967
  *                 jump = 1
  *                 if (alt[0] == EPSILON):
  *                     jump = 0             # <<<<<<<<<<<<<<
@@ -46806,30 +46874,30 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
       }
       __pyx_L9:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":966
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":968
  *                 if (alt[0] == EPSILON):
  *                     jump = 0
  *                 if next_id not in result and min_dist <= curr[1]+jump <= self.max_initial_size+1:             # <<<<<<<<<<<<<<
  *                     candidate.append([next_id,curr[1]+jump])
  *         return sorted(result);
  */
-      __pyx_t_7 = (__Pyx_PySequence_Contains(__pyx_v_next_id, ((PyObject *)__pyx_v_result), Py_NE)); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = (__Pyx_PySequence_Contains(__pyx_v_next_id, ((PyObject *)__pyx_v_result), Py_NE)); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       if (__pyx_t_7) {
-        __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_curr, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_curr, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
-        __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_v_jump); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_v_jump); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-        __pyx_t_1 = PyObject_RichCompare(__pyx_v_min_dist, __pyx_t_2, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyObject_RichCompare(__pyx_v_min_dist, __pyx_t_2, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         if (__Pyx_PyObject_IsTrue(__pyx_t_1)) {
           __Pyx_DECREF(__pyx_t_1);
-          __pyx_t_10 = PyInt_FromLong((__pyx_v_self->max_initial_size + 1)); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_10 = PyInt_FromLong((__pyx_v_self->max_initial_size + 1)); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_10);
-          __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_10, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_10, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
         }
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-        __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
         __pyx_t_6 = __pyx_t_4;
       } else {
@@ -46837,19 +46905,19 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
       }
       if (__pyx_t_6) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":967
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":969
  *                     jump = 0
  *                 if next_id not in result and min_dist <= curr[1]+jump <= self.max_initial_size+1:
  *                     candidate.append([next_id,curr[1]+jump])             # <<<<<<<<<<<<<<
  *         return sorted(result);
  * 
  */
-        __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_curr, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_curr, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
-        __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_v_jump); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_v_jump); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-        __pyx_t_1 = PyList_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyList_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
         __Pyx_INCREF(__pyx_v_next_id);
         PyList_SET_ITEM(__pyx_t_1, 0, __pyx_v_next_id);
@@ -46857,7 +46925,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
         PyList_SET_ITEM(__pyx_t_1, 1, __pyx_t_2);
         __Pyx_GIVEREF(__pyx_t_2);
         __pyx_t_2 = 0;
-        __pyx_t_8 = PyList_Append(__pyx_v_candidate, ((PyObject *)__pyx_t_1)); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_8 = PyList_Append(__pyx_v_candidate, ((PyObject *)__pyx_t_1)); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
         goto __pyx_L10;
       }
@@ -46867,7 +46935,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
     __pyx_L3_continue:;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":968
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":970
  *                 if next_id not in result and min_dist <= curr[1]+jump <= self.max_initial_size+1:
  *                     candidate.append([next_id,curr[1]+jump])
  *         return sorted(result);             # <<<<<<<<<<<<<<
@@ -46875,12 +46943,12 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_20get_next_states(struc
  *     def input(self, fwords, meta):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 970; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_INCREF(((PyObject *)__pyx_v_result));
   PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)__pyx_v_result));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_result));
-  __pyx_t_1 = PyObject_Call(__pyx_builtin_sorted, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(__pyx_builtin_sorted, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 970; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
   __pyx_r = __pyx_t_1;
@@ -46939,11 +47007,11 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_23input(PyObject *__pyx
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__meta)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("input", 1, 2, 2, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 970; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("input", 1, 2, 2, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "input") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 970; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "input") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -46956,7 +47024,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_23input(PyObject *__pyx
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("input", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 970; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("input", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.input", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -46991,7 +47059,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_5input_7lambda4_lambda5
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1135
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1137
  *                         if len(extracts) > 0:
  *                             fcount = Counter()
  *                             fphrases = defaultdict(lambda: defaultdict(lambda: defaultdict(list)))             # <<<<<<<<<<<<<<
@@ -47010,14 +47078,14 @@ static PyObject *__pyx_lambda_funcdef_lambda5(CYTHON_UNUSED PyObject *__pyx_self
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("lambda5", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_INCREF(((PyObject *)((PyObject*)(&PyList_Type))));
   PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)((PyObject*)(&PyList_Type))));
   __Pyx_GIVEREF(((PyObject *)((PyObject*)(&PyList_Type))));
-  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
@@ -47050,16 +47118,16 @@ static PyObject *__pyx_lambda_funcdef_lambda4(CYTHON_UNUSED PyObject *__pyx_self
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("lambda4", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_5input_7lambda4_lambda5, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_5input_7lambda4_lambda5, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
   __Pyx_GIVEREF(__pyx_t_2);
   __pyx_t_2 = 0;
-  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
@@ -47093,7 +47161,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_5input_1lambda6(PyObjec
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1141
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1143
  *                             for f, elist in fphrases.iteritems():
  *                                 for e, alslist in elist.iteritems():
  *                                     alignment, max_locs = max(alslist.iteritems(), key=lambda x: len(x[1]))             # <<<<<<<<<<<<<<
@@ -47111,11 +47179,11 @@ static PyObject *__pyx_lambda_funcdef_lambda6(CYTHON_UNUSED PyObject *__pyx_self
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("lambda6", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_x, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_x, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -47134,7 +47202,7 @@ static PyObject *__pyx_lambda_funcdef_lambda6(CYTHON_UNUSED PyObject *__pyx_self
 }
 static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_5input_4generator14(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value); /* proto */
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1180
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1182
  *         # Online rule extraction and scoring
  *         if self.online:
  *             f_syms = tuple(word[0][0] for word in fwords)             # <<<<<<<<<<<<<<
@@ -47160,7 +47228,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_5input_2genexpr(PyObjec
   __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_outer_scope));
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_outer_scope);
   {
-    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_23HieroCachingRuleFactory_5input_4generator14, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_23HieroCachingRuleFactory_5input_4generator14, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_cur_scope);
     __Pyx_RefNannyFinishContext();
     return (PyObject *) gen;
@@ -47197,13 +47265,13 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_5input_4generator14(__p
     return NULL;
   }
   __pyx_L3_first_run:;
-  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_fwords)) { __Pyx_RaiseClosureNameError("fwords"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_fwords)) { __Pyx_RaiseClosureNameError("fwords"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
   if (PyList_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_fwords) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_fwords)) {
     __pyx_t_1 = __pyx_cur_scope->__pyx_outer_scope->__pyx_v_fwords; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
     __pyx_t_3 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_fwords); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_fwords); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -47211,23 +47279,23 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_5input_4generator14(__p
     if (!__pyx_t_3 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_3 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_4 = __pyx_t_3(__pyx_t_1);
       if (unlikely(!__pyx_t_4)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -47238,9 +47306,9 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_5input_4generator14(__p
     __Pyx_GIVEREF(__pyx_t_4);
     __pyx_cur_scope->__pyx_v_word = __pyx_t_4;
     __pyx_t_4 = 0;
-    __pyx_t_4 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_word, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_word, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = __Pyx_GetItemInt(__pyx_t_4, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_GetItemInt(__pyx_t_4, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __pyx_r = __pyx_t_5;
@@ -47260,7 +47328,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_5input_4generator14(__p
     __Pyx_XGOTREF(__pyx_t_1);
     __pyx_t_2 = __pyx_cur_scope->__pyx_t_1;
     __pyx_t_3 = __pyx_cur_scope->__pyx_t_2;
-    if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyErr_SetNone(PyExc_StopIteration);
@@ -47278,7 +47346,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_5input_4generator14(__p
   return NULL;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":970
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":972
  *         return sorted(result);
  * 
  *     def input(self, fwords, meta):             # <<<<<<<<<<<<<<
@@ -47310,7 +47378,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_22input(struct __pyx_ob
   __Pyx_INCREF(__pyx_cur_scope->__pyx_v_meta);
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_meta);
   {
-    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 970; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_cur_scope);
     __Pyx_RefNannyFinishContext();
     return (PyObject *) gen;
@@ -47372,9 +47440,9 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
     return NULL;
   }
   __pyx_L3_first_run:;
-  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 970; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":981
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":983
  *         cdef Phrase hiero_phrase
  * 
  *         flen = len(fwords)             # <<<<<<<<<<<<<<
@@ -47383,11 +47451,11 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
   __pyx_t_1 = __pyx_cur_scope->__pyx_v_fwords;
   __Pyx_INCREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 983; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_cur_scope->__pyx_v_flen = __pyx_t_2;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":982
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":984
  * 
  *         flen = len(fwords)
  *         start_time = monitor_cpu()             # <<<<<<<<<<<<<<
@@ -47396,7 +47464,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
   __pyx_cur_scope->__pyx_v_start_time = __pyx_f_3_sa_monitor_cpu();
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":983
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":985
  *         flen = len(fwords)
  *         start_time = monitor_cpu()
  *         self.extract_time = 0.0             # <<<<<<<<<<<<<<
@@ -47405,20 +47473,20 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
   __pyx_cur_scope->__pyx_v_self->extract_time = 0.0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":984
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":986
  *         start_time = monitor_cpu()
  *         self.extract_time = 0.0
  *         nodes_isteps_away_buffer = {}             # <<<<<<<<<<<<<<
  *         hit = 0
  *         reachable_buffer = {}
  */
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 986; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
   __pyx_cur_scope->__pyx_v_nodes_isteps_away_buffer = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":985
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":987
  *         self.extract_time = 0.0
  *         nodes_isteps_away_buffer = {}
  *         hit = 0             # <<<<<<<<<<<<<<
@@ -47427,46 +47495,46 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
   __pyx_cur_scope->__pyx_v_hit = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":986
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":988
  *         nodes_isteps_away_buffer = {}
  *         hit = 0
  *         reachable_buffer = {}             # <<<<<<<<<<<<<<
  * 
  *         # Phrase pairs processed by suffix array extractor.  Do not re-extract
  */
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 986; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 988; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
   __pyx_cur_scope->__pyx_v_reachable_buffer = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":991
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":993
  *         # during online extraction.  This is probably the hackiest part of
  *         # online grammar extraction.
  *         seen_phrases = set()             # <<<<<<<<<<<<<<
  * 
  *         # Do not cache between sentences
  */
-  __pyx_t_1 = PySet_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PySet_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
   __pyx_cur_scope->__pyx_v_seen_phrases = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":994
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":996
  * 
  *         # Do not cache between sentences
  *         self.rules.root = ExtendedTrieNode(phrase_location=PhraseLocation())             # <<<<<<<<<<<<<<
  * 
  *         frontier = []
  */
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_PhraseLocation)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_PhraseLocation)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__phrase_location), __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__phrase_location), __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_ExtendedTrieNode)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_ExtendedTrieNode)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
   __Pyx_GIVEREF(__pyx_t_3);
@@ -47475,20 +47543,20 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
   __pyx_cur_scope->__pyx_v_self->rules->root = __pyx_t_3;
   __pyx_t_3 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":996
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":998
  *         self.rules.root = ExtendedTrieNode(phrase_location=PhraseLocation())
  * 
  *         frontier = []             # <<<<<<<<<<<<<<
  *         for i in range(len(fwords)):
  *             for alt in range(0, len(fwords[i])):
  */
-  __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_GIVEREF(((PyObject *)__pyx_t_3));
   __pyx_cur_scope->__pyx_v_frontier = __pyx_t_3;
   __pyx_t_3 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":997
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":999
  * 
  *         frontier = []
  *         for i in range(len(fwords)):             # <<<<<<<<<<<<<<
@@ -47497,72 +47565,72 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
   __pyx_t_3 = __pyx_cur_scope->__pyx_v_fwords;
   __Pyx_INCREF(__pyx_t_3);
-  __pyx_t_2 = PyObject_Length(__pyx_t_3); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 997; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Length(__pyx_t_3); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_2; __pyx_t_4+=1) {
     __pyx_cur_scope->__pyx_v_i = __pyx_t_4;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":998
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1000
  *         frontier = []
  *         for i in range(len(fwords)):
  *             for alt in range(0, len(fwords[i])):             # <<<<<<<<<<<<<<
  *                 if fwords[i][alt][0] != EPSILON:
  *                     frontier.append((i, i, (i,), alt, 0, self.rules.root, (), False))
  */
-    __pyx_t_3 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_fwords, __pyx_cur_scope->__pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_fwords, __pyx_cur_scope->__pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1000; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_5 = PyObject_Length(__pyx_t_3); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyObject_Length(__pyx_t_3); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1000; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
       __pyx_cur_scope->__pyx_v_alt = __pyx_t_6;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":999
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1001
  *         for i in range(len(fwords)):
  *             for alt in range(0, len(fwords[i])):
  *                 if fwords[i][alt][0] != EPSILON:             # <<<<<<<<<<<<<<
  *                     frontier.append((i, i, (i,), alt, 0, self.rules.root, (), False))
  * 
  */
-      __pyx_t_3 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_fwords, __pyx_cur_scope->__pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_fwords, __pyx_cur_scope->__pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_3, __pyx_cur_scope->__pyx_v_alt, sizeof(int), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_3, __pyx_cur_scope->__pyx_v_alt, sizeof(int), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_1 = PyInt_FromLong(__pyx_v_3_sa_EPSILON); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyInt_FromLong(__pyx_v_3_sa_EPSILON); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_7 = PyObject_RichCompare(__pyx_t_3, __pyx_t_1, Py_NE); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyObject_RichCompare(__pyx_t_3, __pyx_t_1, Py_NE); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       if (__pyx_t_8) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1000
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1002
  *             for alt in range(0, len(fwords[i])):
  *                 if fwords[i][alt][0] != EPSILON:
  *                     frontier.append((i, i, (i,), alt, 0, self.rules.root, (), False))             # <<<<<<<<<<<<<<
  * 
  *         xroot = None
  */
-        __pyx_t_7 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1000; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1002; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_7);
-        __pyx_t_1 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1000; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1002; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
-        __pyx_t_3 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1000; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1002; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_3);
-        __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1000; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1002; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_9);
         PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_3);
         __Pyx_GIVEREF(__pyx_t_3);
         __pyx_t_3 = 0;
-        __pyx_t_3 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_alt); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1000; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_alt); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1002; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_3);
-        __pyx_t_10 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1000; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_10 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1002; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_10);
-        __pyx_t_11 = PyTuple_New(8); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1000; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_11 = PyTuple_New(8); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1002; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_11);
         PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_7);
         __Pyx_GIVEREF(__pyx_t_7);
@@ -47588,7 +47656,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         __pyx_t_9 = 0;
         __pyx_t_3 = 0;
         __pyx_t_10 = 0;
-        __pyx_t_12 = PyList_Append(__pyx_cur_scope->__pyx_v_frontier, ((PyObject *)__pyx_t_11)); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1000; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_12 = PyList_Append(__pyx_cur_scope->__pyx_v_frontier, ((PyObject *)__pyx_t_11)); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1002; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(((PyObject *)__pyx_t_11)); __pyx_t_11 = 0;
         goto __pyx_L8;
       }
@@ -47596,7 +47664,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
     }
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1002
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1004
  *                     frontier.append((i, i, (i,), alt, 0, self.rules.root, (), False))
  * 
  *         xroot = None             # <<<<<<<<<<<<<<
@@ -47607,7 +47675,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
   __Pyx_GIVEREF(Py_None);
   __pyx_cur_scope->__pyx_v_xroot = Py_None;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1003
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1005
  * 
  *         xroot = None
  *         x1 = sym_setindex(self.category, 1)             # <<<<<<<<<<<<<<
@@ -47616,32 +47684,32 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
   __pyx_cur_scope->__pyx_v_x1 = __pyx_f_3_sa_sym_setindex(__pyx_cur_scope->__pyx_v_self->category, 1);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1004
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1006
  *         xroot = None
  *         x1 = sym_setindex(self.category, 1)
  *         if x1 in self.rules.root.children:             # <<<<<<<<<<<<<<
  *             xroot = self.rules.root.children[x1]
  *         else:
  */
-  __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_x1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1004; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_x1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1006; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_11);
-  __pyx_t_10 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_self->rules->root, __pyx_n_s__children); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1004; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_10 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_self->rules->root, __pyx_n_s__children); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1006; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_10);
-  __pyx_t_8 = (__Pyx_PySequence_Contains(__pyx_t_11, __pyx_t_10, Py_EQ)); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1004; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_8 = (__Pyx_PySequence_Contains(__pyx_t_11, __pyx_t_10, Py_EQ)); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1006; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
   __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
   if (__pyx_t_8) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1005
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1007
  *         x1 = sym_setindex(self.category, 1)
  *         if x1 in self.rules.root.children:
  *             xroot = self.rules.root.children[x1]             # <<<<<<<<<<<<<<
  *         else:
  *             xroot = ExtendedTrieNode(suffix_link=self.rules.root, phrase_location=PhraseLocation())
  */
-    __pyx_t_10 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_self->rules->root, __pyx_n_s__children); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1005; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_self->rules->root, __pyx_n_s__children); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_10);
-    __pyx_t_11 = __Pyx_GetItemInt(__pyx_t_10, __pyx_cur_scope->__pyx_v_x1, sizeof(int), PyInt_FromLong); if (!__pyx_t_11) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1005; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_11 = __Pyx_GetItemInt(__pyx_t_10, __pyx_cur_scope->__pyx_v_x1, sizeof(int), PyInt_FromLong); if (!__pyx_t_11) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_11);
     __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
     __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_xroot);
@@ -47653,21 +47721,21 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1007
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1009
  *             xroot = self.rules.root.children[x1]
  *         else:
  *             xroot = ExtendedTrieNode(suffix_link=self.rules.root, phrase_location=PhraseLocation())             # <<<<<<<<<<<<<<
  *             self.rules.root.children[x1] = xroot
  * 
  */
-    __pyx_t_11 = PyDict_New(); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_11 = PyDict_New(); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1009; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(((PyObject *)__pyx_t_11));
-    if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__suffix_link), __pyx_cur_scope->__pyx_v_self->rules->root) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_10 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_PhraseLocation)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__suffix_link), __pyx_cur_scope->__pyx_v_self->rules->root) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1009; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_PhraseLocation)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1009; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_10);
-    if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__phrase_location), __pyx_t_10) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__phrase_location), __pyx_t_10) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1009; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-    __pyx_t_10 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_ExtendedTrieNode)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_11)); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_ExtendedTrieNode)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_11)); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1009; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_10);
     __Pyx_DECREF(((PyObject *)__pyx_t_11)); __pyx_t_11 = 0;
     __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_xroot);
@@ -47676,21 +47744,21 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
     __pyx_cur_scope->__pyx_v_xroot = __pyx_t_10;
     __pyx_t_10 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1008
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1010
  *         else:
  *             xroot = ExtendedTrieNode(suffix_link=self.rules.root, phrase_location=PhraseLocation())
  *             self.rules.root.children[x1] = xroot             # <<<<<<<<<<<<<<
  * 
  *         for i in range(self.min_gap_size, len(fwords)):
  */
-    __pyx_t_10 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_self->rules->root, __pyx_n_s__children); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1008; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_self->rules->root, __pyx_n_s__children); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_10);
-    if (__Pyx_SetItemInt(__pyx_t_10, __pyx_cur_scope->__pyx_v_x1, __pyx_cur_scope->__pyx_v_xroot, sizeof(int), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1008; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (__Pyx_SetItemInt(__pyx_t_10, __pyx_cur_scope->__pyx_v_x1, __pyx_cur_scope->__pyx_v_xroot, sizeof(int), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
   }
   __pyx_L9:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1010
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1012
  *             self.rules.root.children[x1] = xroot
  * 
  *         for i in range(self.min_gap_size, len(fwords)):             # <<<<<<<<<<<<<<
@@ -47699,81 +47767,81 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
   __pyx_t_10 = __pyx_cur_scope->__pyx_v_fwords;
   __Pyx_INCREF(__pyx_t_10);
-  __pyx_t_2 = PyObject_Length(__pyx_t_10); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Length(__pyx_t_10); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
   for (__pyx_t_4 = __pyx_cur_scope->__pyx_v_self->min_gap_size; __pyx_t_4 < __pyx_t_2; __pyx_t_4+=1) {
     __pyx_cur_scope->__pyx_v_i = __pyx_t_4;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1011
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1013
  * 
  *         for i in range(self.min_gap_size, len(fwords)):
  *             for alt in range(0, len(fwords[i])):             # <<<<<<<<<<<<<<
  *                 if fwords[i][alt][0] != EPSILON:
  *                     frontier.append((i-self.min_gap_size, i, (i,), alt, self.min_gap_size, xroot, (x1,), True))
  */
-    __pyx_t_10 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_fwords, __pyx_cur_scope->__pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_10) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_fwords, __pyx_cur_scope->__pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_10) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_10);
-    __pyx_t_5 = PyObject_Length(__pyx_t_10); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyObject_Length(__pyx_t_10); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
     for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
       __pyx_cur_scope->__pyx_v_alt = __pyx_t_6;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1012
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1014
  *         for i in range(self.min_gap_size, len(fwords)):
  *             for alt in range(0, len(fwords[i])):
  *                 if fwords[i][alt][0] != EPSILON:             # <<<<<<<<<<<<<<
  *                     frontier.append((i-self.min_gap_size, i, (i,), alt, self.min_gap_size, xroot, (x1,), True))
  * 
  */
-      __pyx_t_10 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_fwords, __pyx_cur_scope->__pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_10) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_10 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_fwords, __pyx_cur_scope->__pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_10) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1014; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_10);
-      __pyx_t_11 = __Pyx_GetItemInt(__pyx_t_10, __pyx_cur_scope->__pyx_v_alt, sizeof(int), PyInt_FromLong); if (!__pyx_t_11) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_11 = __Pyx_GetItemInt(__pyx_t_10, __pyx_cur_scope->__pyx_v_alt, sizeof(int), PyInt_FromLong); if (!__pyx_t_11) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1014; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_11);
       __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-      __pyx_t_10 = __Pyx_GetItemInt(__pyx_t_11, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_10) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_10 = __Pyx_GetItemInt(__pyx_t_11, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_10) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1014; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_10);
       __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-      __pyx_t_11 = PyInt_FromLong(__pyx_v_3_sa_EPSILON); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_11 = PyInt_FromLong(__pyx_v_3_sa_EPSILON); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1014; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_11);
-      __pyx_t_3 = PyObject_RichCompare(__pyx_t_10, __pyx_t_11, Py_NE); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyObject_RichCompare(__pyx_t_10, __pyx_t_11, Py_NE); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1014; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
       __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-      __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1014; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
       if (__pyx_t_8) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1013
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1015
  *             for alt in range(0, len(fwords[i])):
  *                 if fwords[i][alt][0] != EPSILON:
  *                     frontier.append((i-self.min_gap_size, i, (i,), alt, self.min_gap_size, xroot, (x1,), True))             # <<<<<<<<<<<<<<
  * 
  *         next_states = []
  */
-        __pyx_t_3 = PyInt_FromLong((__pyx_cur_scope->__pyx_v_i - __pyx_cur_scope->__pyx_v_self->min_gap_size)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = PyInt_FromLong((__pyx_cur_scope->__pyx_v_i - __pyx_cur_scope->__pyx_v_self->min_gap_size)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1015; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_3);
-        __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1015; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_11);
-        __pyx_t_10 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_10 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1015; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_10);
-        __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1015; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_9);
         PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_10);
         __Pyx_GIVEREF(__pyx_t_10);
         __pyx_t_10 = 0;
-        __pyx_t_10 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_alt); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_10 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_alt); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1015; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_10);
-        __pyx_t_1 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->min_gap_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->min_gap_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1015; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
-        __pyx_t_7 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_x1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_x1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1015; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_7);
-        __pyx_t_13 = PyTuple_New(1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_13 = PyTuple_New(1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1015; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_13);
         PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_7);
         __Pyx_GIVEREF(__pyx_t_7);
         __pyx_t_7 = 0;
-        __pyx_t_7 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1015; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_7);
-        __pyx_t_14 = PyTuple_New(8); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_14 = PyTuple_New(8); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1015; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_14);
         PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_t_3);
         __Pyx_GIVEREF(__pyx_t_3);
@@ -47799,7 +47867,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         __pyx_t_1 = 0;
         __pyx_t_13 = 0;
         __pyx_t_7 = 0;
-        __pyx_t_12 = PyList_Append(__pyx_cur_scope->__pyx_v_frontier, ((PyObject *)__pyx_t_14)); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_12 = PyList_Append(__pyx_cur_scope->__pyx_v_frontier, ((PyObject *)__pyx_t_14)); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1015; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
         goto __pyx_L14;
       }
@@ -47807,20 +47875,20 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
     }
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1015
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1017
  *                     frontier.append((i-self.min_gap_size, i, (i,), alt, self.min_gap_size, xroot, (x1,), True))
  * 
  *         next_states = []             # <<<<<<<<<<<<<<
  *         for i in range(len(fwords)):
  *             next_states.append(self.get_next_states(fwords,i,self.min_gap_size))
  */
-  __pyx_t_14 = PyList_New(0); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1015; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_14 = PyList_New(0); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1017; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_14);
   __Pyx_GIVEREF(((PyObject *)__pyx_t_14));
   __pyx_cur_scope->__pyx_v_next_states = __pyx_t_14;
   __pyx_t_14 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1016
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1018
  * 
  *         next_states = []
  *         for i in range(len(fwords)):             # <<<<<<<<<<<<<<
@@ -47829,25 +47897,25 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
   __pyx_t_14 = __pyx_cur_scope->__pyx_v_fwords;
   __Pyx_INCREF(__pyx_t_14);
-  __pyx_t_2 = PyObject_Length(__pyx_t_14); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1016; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Length(__pyx_t_14); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1018; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
   for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_2; __pyx_t_4+=1) {
     __pyx_cur_scope->__pyx_v_i = __pyx_t_4;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1017
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1019
  *         next_states = []
  *         for i in range(len(fwords)):
  *             next_states.append(self.get_next_states(fwords,i,self.min_gap_size))             # <<<<<<<<<<<<<<
  * 
  *         while len(frontier) > 0:
  */
-    __pyx_t_14 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__get_next_states); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1017; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_14 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__get_next_states); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1019; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_14);
-    __pyx_t_7 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1017; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1019; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_7);
-    __pyx_t_13 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->min_gap_size); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1017; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_13 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->min_gap_size); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1019; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_13);
-    __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1017; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1019; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_INCREF(__pyx_cur_scope->__pyx_v_fwords);
     PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_cur_scope->__pyx_v_fwords);
@@ -47858,15 +47926,15 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
     __Pyx_GIVEREF(__pyx_t_13);
     __pyx_t_7 = 0;
     __pyx_t_13 = 0;
-    __pyx_t_13 = PyObject_Call(__pyx_t_14, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1017; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_13 = PyObject_Call(__pyx_t_14, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1019; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_13);
     __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-    __pyx_t_12 = PyList_Append(__pyx_cur_scope->__pyx_v_next_states, __pyx_t_13); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1017; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_12 = PyList_Append(__pyx_cur_scope->__pyx_v_next_states, __pyx_t_13); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1019; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1019
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1021
  *             next_states.append(self.get_next_states(fwords,i,self.min_gap_size))
  * 
  *         while len(frontier) > 0:             # <<<<<<<<<<<<<<
@@ -47874,18 +47942,18 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  *             for k, i, input_match, alt, pathlen, node, prefix, is_shadow_path in frontier:
  */
   while (1) {
-    __pyx_t_2 = PyList_GET_SIZE(((PyObject *)__pyx_cur_scope->__pyx_v_frontier)); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1019; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyList_GET_SIZE(((PyObject *)__pyx_cur_scope->__pyx_v_frontier)); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __pyx_t_8 = (__pyx_t_2 > 0);
     if (!__pyx_t_8) break;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1020
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1022
  * 
  *         while len(frontier) > 0:
  *             new_frontier = []             # <<<<<<<<<<<<<<
  *             for k, i, input_match, alt, pathlen, node, prefix, is_shadow_path in frontier:
  *                 word_id = fwords[i][alt][0]
  */
-    __pyx_t_13 = PyList_New(0); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1020; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_13 = PyList_New(0); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1022; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_13);
     __Pyx_XGOTREF(((PyObject *)__pyx_cur_scope->__pyx_v_new_frontier));
     __Pyx_XDECREF(((PyObject *)__pyx_cur_scope->__pyx_v_new_frontier));
@@ -47893,7 +47961,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
     __pyx_cur_scope->__pyx_v_new_frontier = __pyx_t_13;
     __pyx_t_13 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1021
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1023
  *         while len(frontier) > 0:
  *             new_frontier = []
  *             for k, i, input_match, alt, pathlen, node, prefix, is_shadow_path in frontier:             # <<<<<<<<<<<<<<
@@ -47904,9 +47972,9 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
     for (;;) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_13)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_1 = PyList_GET_ITEM(__pyx_t_13, __pyx_t_2); __Pyx_INCREF(__pyx_t_1); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyList_GET_ITEM(__pyx_t_13, __pyx_t_2); __Pyx_INCREF(__pyx_t_1); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_1 = PySequence_ITEM(__pyx_t_13, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PySequence_ITEM(__pyx_t_13, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
       if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) {
         PyObject* sequence = __pyx_t_1;
@@ -47918,7 +47986,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         if (unlikely(size != 8)) {
           if (size > 8) __Pyx_RaiseTooManyValuesError(8);
           else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-          {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         #if CYTHON_COMPILING_IN_CPYTHON
         if (likely(PyTuple_CheckExact(sequence))) {
@@ -47952,7 +48020,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         Py_ssize_t i;
         PyObject** temps[8] = {&__pyx_t_14,&__pyx_t_7,&__pyx_t_10,&__pyx_t_9,&__pyx_t_11,&__pyx_t_3,&__pyx_t_15,&__pyx_t_16};
         for (i=0; i < 8; i++) {
-          PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           *(temps[i]) = item;
         }
         #endif
@@ -47961,7 +48029,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       {
         Py_ssize_t index = -1;
         PyObject** temps[8] = {&__pyx_t_14,&__pyx_t_7,&__pyx_t_10,&__pyx_t_9,&__pyx_t_11,&__pyx_t_3,&__pyx_t_15,&__pyx_t_16};
-        __pyx_t_17 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_17)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_17 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_17)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_17);
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
         __pyx_t_18 = Py_TYPE(__pyx_t_17)->tp_iternext;
@@ -47970,7 +48038,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __Pyx_GOTREF(item);
           *(temps[index]) = item;
         }
-        if (__Pyx_IternextUnpackEndCheck(__pyx_t_18(__pyx_t_17), 8) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (__Pyx_IternextUnpackEndCheck(__pyx_t_18(__pyx_t_17), 8) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __pyx_t_18 = NULL;
         __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0;
         goto __pyx_L22_unpacking_done;
@@ -47978,14 +48046,14 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0;
         __pyx_t_18 = NULL;
         if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __pyx_L22_unpacking_done:;
       }
-      __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_t_14); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_t_14); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
-      __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_t_7); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_t_7); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-      __pyx_t_19 = __Pyx_PyInt_AsInt(__pyx_t_9); if (unlikely((__pyx_t_19 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_19 = __Pyx_PyInt_AsInt(__pyx_t_9); if (unlikely((__pyx_t_19 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
       __pyx_cur_scope->__pyx_v_k = __pyx_t_4;
       __pyx_cur_scope->__pyx_v_i = __pyx_t_6;
@@ -48016,19 +48084,19 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       __pyx_cur_scope->__pyx_v_is_shadow_path = __pyx_t_16;
       __pyx_t_16 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1022
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1024
  *             new_frontier = []
  *             for k, i, input_match, alt, pathlen, node, prefix, is_shadow_path in frontier:
  *                 word_id = fwords[i][alt][0]             # <<<<<<<<<<<<<<
  *                 spanlen = fwords[i][alt][2]
  *                 # TODO get rid of k -- pathlen is replacing it
  */
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_fwords, __pyx_cur_scope->__pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1022; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_fwords, __pyx_cur_scope->__pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1024; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_16 = __Pyx_GetItemInt(__pyx_t_1, __pyx_cur_scope->__pyx_v_alt, sizeof(int), PyInt_FromLong); if (!__pyx_t_16) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1022; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_16 = __Pyx_GetItemInt(__pyx_t_1, __pyx_cur_scope->__pyx_v_alt, sizeof(int), PyInt_FromLong); if (!__pyx_t_16) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1024; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_16);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_16, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1022; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_16, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1024; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
       __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_word_id);
@@ -48037,19 +48105,19 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       __pyx_cur_scope->__pyx_v_word_id = __pyx_t_1;
       __pyx_t_1 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1023
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1025
  *             for k, i, input_match, alt, pathlen, node, prefix, is_shadow_path in frontier:
  *                 word_id = fwords[i][alt][0]
  *                 spanlen = fwords[i][alt][2]             # <<<<<<<<<<<<<<
  *                 # TODO get rid of k -- pathlen is replacing it
  *                 if word_id == EPSILON:
  */
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_fwords, __pyx_cur_scope->__pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_fwords, __pyx_cur_scope->__pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1025; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_16 = __Pyx_GetItemInt(__pyx_t_1, __pyx_cur_scope->__pyx_v_alt, sizeof(int), PyInt_FromLong); if (!__pyx_t_16) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_16 = __Pyx_GetItemInt(__pyx_t_1, __pyx_cur_scope->__pyx_v_alt, sizeof(int), PyInt_FromLong); if (!__pyx_t_16) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1025; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_16);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_16, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_16, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1025; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
       __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_spanlen);
@@ -48058,47 +48126,47 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       __pyx_cur_scope->__pyx_v_spanlen = __pyx_t_1;
       __pyx_t_1 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1025
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1027
  *                 spanlen = fwords[i][alt][2]
  *                 # TODO get rid of k -- pathlen is replacing it
  *                 if word_id == EPSILON:             # <<<<<<<<<<<<<<
  *                     # skipping because word_id is epsilon
  *                     if i+spanlen >= len(fwords):
  */
-      __pyx_t_1 = PyInt_FromLong(__pyx_v_3_sa_EPSILON); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1025; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyInt_FromLong(__pyx_v_3_sa_EPSILON); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1027; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_16 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_word_id, __pyx_t_1, Py_EQ); __Pyx_XGOTREF(__pyx_t_16); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1025; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_16 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_word_id, __pyx_t_1, Py_EQ); __Pyx_XGOTREF(__pyx_t_16); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1027; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_16); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1025; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_16); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1027; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
       if (__pyx_t_8) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1027
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1029
  *                 if word_id == EPSILON:
  *                     # skipping because word_id is epsilon
  *                     if i+spanlen >= len(fwords):             # <<<<<<<<<<<<<<
  *                         continue
  *                     for nualt in range(0,len(fwords[i+spanlen])):
  */
-        __pyx_t_16 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1027; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_16 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1029; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_16);
-        __pyx_t_1 = PyNumber_Add(__pyx_t_16, __pyx_cur_scope->__pyx_v_spanlen); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1027; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyNumber_Add(__pyx_t_16, __pyx_cur_scope->__pyx_v_spanlen); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1029; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
         __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
         __pyx_t_16 = __pyx_cur_scope->__pyx_v_fwords;
         __Pyx_INCREF(__pyx_t_16);
-        __pyx_t_5 = PyObject_Length(__pyx_t_16); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1027; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = PyObject_Length(__pyx_t_16); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1029; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
-        __pyx_t_16 = PyInt_FromSsize_t(__pyx_t_5); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1027; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_16 = PyInt_FromSsize_t(__pyx_t_5); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1029; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_16);
-        __pyx_t_15 = PyObject_RichCompare(__pyx_t_1, __pyx_t_16, Py_GE); __Pyx_XGOTREF(__pyx_t_15); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1027; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_15 = PyObject_RichCompare(__pyx_t_1, __pyx_t_16, Py_GE); __Pyx_XGOTREF(__pyx_t_15); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1029; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
         __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
-        __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_15); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1027; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_15); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1029; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
         if (__pyx_t_8) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1028
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1030
  *                     # skipping because word_id is epsilon
  *                     if i+spanlen >= len(fwords):
  *                         continue             # <<<<<<<<<<<<<<
@@ -48110,43 +48178,43 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         }
         __pyx_L24:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1029
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1031
  *                     if i+spanlen >= len(fwords):
  *                         continue
  *                     for nualt in range(0,len(fwords[i+spanlen])):             # <<<<<<<<<<<<<<
  *                         frontier.append((k, i+spanlen, input_match, nualt, pathlen, node, prefix, is_shadow_path))
  *                     continue
  */
-        __pyx_t_15 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1029; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_15 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1031; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_15);
-        __pyx_t_16 = PyNumber_Add(__pyx_t_15, __pyx_cur_scope->__pyx_v_spanlen); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1029; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_16 = PyNumber_Add(__pyx_t_15, __pyx_cur_scope->__pyx_v_spanlen); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1031; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_16);
         __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
-        __pyx_t_15 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fwords, __pyx_t_16); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1029; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_15 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fwords, __pyx_t_16); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1031; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_15);
         __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
-        __pyx_t_5 = PyObject_Length(__pyx_t_15); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1029; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = PyObject_Length(__pyx_t_15); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1031; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
         for (__pyx_t_19 = 0; __pyx_t_19 < __pyx_t_5; __pyx_t_19+=1) {
           __pyx_cur_scope->__pyx_v_nualt = __pyx_t_19;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1030
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1032
  *                         continue
  *                     for nualt in range(0,len(fwords[i+spanlen])):
  *                         frontier.append((k, i+spanlen, input_match, nualt, pathlen, node, prefix, is_shadow_path))             # <<<<<<<<<<<<<<
  *                     continue
  * 
  */
-          __pyx_t_15 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_k); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_15 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_k); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1032; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_15);
-          __pyx_t_16 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_16 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1032; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_16);
-          __pyx_t_1 = PyNumber_Add(__pyx_t_16, __pyx_cur_scope->__pyx_v_spanlen); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_1 = PyNumber_Add(__pyx_t_16, __pyx_cur_scope->__pyx_v_spanlen); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1032; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_1);
           __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
-          __pyx_t_16 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_nualt); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_16 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_nualt); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1032; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_16);
-          __pyx_t_3 = PyTuple_New(8); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_3 = PyTuple_New(8); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1032; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_3);
           PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_15);
           __Pyx_GIVEREF(__pyx_t_15);
@@ -48172,11 +48240,11 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __pyx_t_15 = 0;
           __pyx_t_1 = 0;
           __pyx_t_16 = 0;
-          __pyx_t_12 = PyList_Append(__pyx_cur_scope->__pyx_v_frontier, ((PyObject *)__pyx_t_3)); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_12 = PyList_Append(__pyx_cur_scope->__pyx_v_frontier, ((PyObject *)__pyx_t_3)); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1032; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
         }
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1031
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1033
  *                     for nualt in range(0,len(fwords[i+spanlen])):
  *                         frontier.append((k, i+spanlen, input_match, nualt, pathlen, node, prefix, is_shadow_path))
  *                     continue             # <<<<<<<<<<<<<<
@@ -48188,19 +48256,19 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       }
       __pyx_L23:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1033
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1035
  *                     continue
  * 
  *                 phrase = prefix + (word_id,)             # <<<<<<<<<<<<<<
  *                 hiero_phrase = Phrase(phrase)
  *                 arity = hiero_phrase.arity()
  */
-      __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_INCREF(__pyx_cur_scope->__pyx_v_word_id);
       PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_cur_scope->__pyx_v_word_id);
       __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_word_id);
-      __pyx_t_16 = PyNumber_Add(__pyx_cur_scope->__pyx_v_prefix, ((PyObject *)__pyx_t_3)); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_16 = PyNumber_Add(__pyx_cur_scope->__pyx_v_prefix, ((PyObject *)__pyx_t_3)); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_16);
       __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
       __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_phrase);
@@ -48209,19 +48277,19 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       __pyx_cur_scope->__pyx_v_phrase = __pyx_t_16;
       __pyx_t_16 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1034
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1036
  * 
  *                 phrase = prefix + (word_id,)
  *                 hiero_phrase = Phrase(phrase)             # <<<<<<<<<<<<<<
  *                 arity = hiero_phrase.arity()
  * 
  */
-      __pyx_t_16 = PyTuple_New(1); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1034; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_16 = PyTuple_New(1); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1036; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_16);
       __Pyx_INCREF(__pyx_cur_scope->__pyx_v_phrase);
       PyTuple_SET_ITEM(__pyx_t_16, 0, __pyx_cur_scope->__pyx_v_phrase);
       __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_phrase);
-      __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_16), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1034; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_16), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1036; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(((PyObject *)__pyx_t_16)); __pyx_t_16 = 0;
       __Pyx_XGOTREF(((PyObject *)__pyx_cur_scope->__pyx_v_hiero_phrase));
@@ -48230,23 +48298,23 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       __pyx_cur_scope->__pyx_v_hiero_phrase = ((struct __pyx_obj_3_sa_Phrase *)__pyx_t_3);
       __pyx_t_3 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1035
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1037
  *                 phrase = prefix + (word_id,)
  *                 hiero_phrase = Phrase(phrase)
  *                 arity = hiero_phrase.arity()             # <<<<<<<<<<<<<<
  * 
  *                 lookup_required = False
  */
-      __pyx_t_3 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_hiero_phrase), __pyx_n_s__arity); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_hiero_phrase), __pyx_n_s__arity); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_16 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_16 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_16);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_19 = __Pyx_PyInt_AsInt(__pyx_t_16); if (unlikely((__pyx_t_19 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_19 = __Pyx_PyInt_AsInt(__pyx_t_16); if (unlikely((__pyx_t_19 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
       __pyx_cur_scope->__pyx_v_arity = __pyx_t_19;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1037
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1039
  *                 arity = hiero_phrase.arity()
  * 
  *                 lookup_required = False             # <<<<<<<<<<<<<<
@@ -48255,36 +48323,36 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
       __pyx_cur_scope->__pyx_v_lookup_required = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1038
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1040
  * 
  *                 lookup_required = False
  *                 if word_id in node.children:             # <<<<<<<<<<<<<<
  *                     if node.children[word_id] is None:
  *                         # Path dead-ends at this node
  */
-      __pyx_t_16 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1038; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_16 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1040; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_16);
-      __pyx_t_8 = (__Pyx_PySequence_Contains(__pyx_cur_scope->__pyx_v_word_id, __pyx_t_16, Py_EQ)); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1038; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = (__Pyx_PySequence_Contains(__pyx_cur_scope->__pyx_v_word_id, __pyx_t_16, Py_EQ)); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1040; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
       if (__pyx_t_8) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1039
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1041
  *                 lookup_required = False
  *                 if word_id in node.children:
  *                     if node.children[word_id] is None:             # <<<<<<<<<<<<<<
  *                         # Path dead-ends at this node
  *                         continue
  */
-        __pyx_t_16 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_16 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1041; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_16);
-        __pyx_t_3 = PyObject_GetItem(__pyx_t_16, __pyx_cur_scope->__pyx_v_word_id); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = PyObject_GetItem(__pyx_t_16, __pyx_cur_scope->__pyx_v_word_id); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1041; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
         __pyx_t_8 = (__pyx_t_3 == Py_None);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         if (__pyx_t_8) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1041
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1043
  *                     if node.children[word_id] is None:
  *                         # Path dead-ends at this node
  *                         continue             # <<<<<<<<<<<<<<
@@ -48296,16 +48364,16 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         }
         /*else*/ {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1044
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1046
  *                     else:
  *                         # Path continues at this node
  *                         node = node.children[word_id]             # <<<<<<<<<<<<<<
  *                 else:
  *                     if node.suffix_link is None:
  */
-          __pyx_t_3 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1044; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_3 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1046; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_3);
-          __pyx_t_16 = PyObject_GetItem(__pyx_t_3, __pyx_cur_scope->__pyx_v_word_id); if (!__pyx_t_16) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1044; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_16 = PyObject_GetItem(__pyx_t_3, __pyx_cur_scope->__pyx_v_word_id); if (!__pyx_t_16) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1046; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_16);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
           __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_node);
@@ -48319,20 +48387,20 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       }
       /*else*/ {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1046
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1048
  *                         node = node.children[word_id]
  *                 else:
  *                     if node.suffix_link is None:             # <<<<<<<<<<<<<<
  *                         # Current node is root; lookup required
  *                         lookup_required = True
  */
-        __pyx_t_16 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1046; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_16 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1048; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_16);
         __pyx_t_8 = (__pyx_t_16 == Py_None);
         __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
         if (__pyx_t_8) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1048
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1050
  *                     if node.suffix_link is None:
  *                         # Current node is root; lookup required
  *                         lookup_required = True             # <<<<<<<<<<<<<<
@@ -48344,54 +48412,54 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         }
         /*else*/ {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1050
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1052
  *                         lookup_required = True
  *                     else:
  *                         if word_id in node.suffix_link.children:             # <<<<<<<<<<<<<<
  *                             if node.suffix_link.children[word_id] is None:
  *                                 # Suffix link reports path is dead end
  */
-          __pyx_t_16 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_16 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1052; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_16);
-          __pyx_t_3 = PyObject_GetAttr(__pyx_t_16, __pyx_n_s__children); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_3 = PyObject_GetAttr(__pyx_t_16, __pyx_n_s__children); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1052; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_3);
           __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
-          __pyx_t_8 = (__Pyx_PySequence_Contains(__pyx_cur_scope->__pyx_v_word_id, __pyx_t_3, Py_EQ)); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_8 = (__Pyx_PySequence_Contains(__pyx_cur_scope->__pyx_v_word_id, __pyx_t_3, Py_EQ)); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1052; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
           if (__pyx_t_8) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1051
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1053
  *                     else:
  *                         if word_id in node.suffix_link.children:
  *                             if node.suffix_link.children[word_id] is None:             # <<<<<<<<<<<<<<
  *                                 # Suffix link reports path is dead end
  *                                 node.children[word_id] = None
  */
-            __pyx_t_3 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1051; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_3);
-            __pyx_t_16 = PyObject_GetAttr(__pyx_t_3, __pyx_n_s__children); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1051; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_16 = PyObject_GetAttr(__pyx_t_3, __pyx_n_s__children); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_16);
             __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-            __pyx_t_3 = PyObject_GetItem(__pyx_t_16, __pyx_cur_scope->__pyx_v_word_id); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1051; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = PyObject_GetItem(__pyx_t_16, __pyx_cur_scope->__pyx_v_word_id); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_3);
             __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
             __pyx_t_8 = (__pyx_t_3 == Py_None);
             __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
             if (__pyx_t_8) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1053
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1055
  *                             if node.suffix_link.children[word_id] is None:
  *                                 # Suffix link reports path is dead end
  *                                 node.children[word_id] = None             # <<<<<<<<<<<<<<
  *                                 continue
  *                             else:
  */
-              __pyx_t_3 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_3 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1055; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_3);
-              if (PyObject_SetItem(__pyx_t_3, __pyx_cur_scope->__pyx_v_word_id, Py_None) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              if (PyObject_SetItem(__pyx_t_3, __pyx_cur_scope->__pyx_v_word_id, Py_None) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1055; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1054
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1056
  *                                 # Suffix link reports path is dead end
  *                                 node.children[word_id] = None
  *                                 continue             # <<<<<<<<<<<<<<
@@ -48403,7 +48471,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             }
             /*else*/ {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1057
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1059
  *                             else:
  *                                 # Suffix link indicates lookup is reqired
  *                                 lookup_required = True             # <<<<<<<<<<<<<<
@@ -48417,18 +48485,18 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           }
           /*else*/ {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1060
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1062
  *                         else:
  *                             #ERROR: We never get here
  *                             raise Exception("Keyword trie error")             # <<<<<<<<<<<<<<
  *                 # checking whether lookup_required
  *                 if lookup_required:
  */
-            __pyx_t_3 = PyObject_Call(__pyx_builtin_Exception, ((PyObject *)__pyx_k_tuple_122), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1060; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = PyObject_Call(__pyx_builtin_Exception, ((PyObject *)__pyx_k_tuple_122), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1062; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 1060; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1062; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           }
           __pyx_L30:;
         }
@@ -48436,7 +48504,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       }
       __pyx_L27:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1062
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1064
  *                             raise Exception("Keyword trie error")
  *                 # checking whether lookup_required
  *                 if lookup_required:             # <<<<<<<<<<<<<<
@@ -48445,7 +48513,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
       if (__pyx_cur_scope->__pyx_v_lookup_required) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1063
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1065
  *                 # checking whether lookup_required
  *                 if lookup_required:
  *                     new_node = None             # <<<<<<<<<<<<<<
@@ -48458,66 +48526,66 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         __Pyx_GIVEREF(Py_None);
         __pyx_cur_scope->__pyx_v_new_node = Py_None;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1064
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1066
  *                 if lookup_required:
  *                     new_node = None
  *                     if is_shadow_path:             # <<<<<<<<<<<<<<
  *                         # Extending shadow path
  *                         # on the shadow path we don't do any search, we just use info from suffix link
  */
-        __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_cur_scope->__pyx_v_is_shadow_path); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1064; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_cur_scope->__pyx_v_is_shadow_path); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1066; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         if (__pyx_t_8) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1067
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1069
  *                         # Extending shadow path
  *                         # on the shadow path we don't do any search, we just use info from suffix link
  *                         new_node = ExtendedTrieNode(phrase_location=node.suffix_link.children[word_id].phrase_location,             # <<<<<<<<<<<<<<
  *                                 suffix_link=node.suffix_link.children[word_id],
  *                                 phrase=hiero_phrase)
  */
-          __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(((PyObject *)__pyx_t_3));
-          __pyx_t_16 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_16 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_16);
-          __pyx_t_1 = PyObject_GetAttr(__pyx_t_16, __pyx_n_s__children); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_1 = PyObject_GetAttr(__pyx_t_16, __pyx_n_s__children); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_1);
           __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
-          __pyx_t_16 = PyObject_GetItem(__pyx_t_1, __pyx_cur_scope->__pyx_v_word_id); if (!__pyx_t_16) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_16 = PyObject_GetItem(__pyx_t_1, __pyx_cur_scope->__pyx_v_word_id); if (!__pyx_t_16) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_16);
           __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-          __pyx_t_1 = PyObject_GetAttr(__pyx_t_16, __pyx_n_s__phrase_location); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_1 = PyObject_GetAttr(__pyx_t_16, __pyx_n_s__phrase_location); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_1);
           __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
-          if (PyDict_SetItem(__pyx_t_3, ((PyObject *)__pyx_n_s__phrase_location), __pyx_t_1) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          if (PyDict_SetItem(__pyx_t_3, ((PyObject *)__pyx_n_s__phrase_location), __pyx_t_1) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1068
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1070
  *                         # on the shadow path we don't do any search, we just use info from suffix link
  *                         new_node = ExtendedTrieNode(phrase_location=node.suffix_link.children[word_id].phrase_location,
  *                                 suffix_link=node.suffix_link.children[word_id],             # <<<<<<<<<<<<<<
  *                                 phrase=hiero_phrase)
  *                     else:
  */
-          __pyx_t_1 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1068; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_1 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1070; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_1);
-          __pyx_t_16 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__children); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1068; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_16 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__children); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1070; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_16);
           __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-          __pyx_t_1 = PyObject_GetItem(__pyx_t_16, __pyx_cur_scope->__pyx_v_word_id); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1068; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_1 = PyObject_GetItem(__pyx_t_16, __pyx_cur_scope->__pyx_v_word_id); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1070; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_1);
           __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
-          if (PyDict_SetItem(__pyx_t_3, ((PyObject *)__pyx_n_s__suffix_link), __pyx_t_1) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          if (PyDict_SetItem(__pyx_t_3, ((PyObject *)__pyx_n_s__suffix_link), __pyx_t_1) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1069
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1071
  *                         new_node = ExtendedTrieNode(phrase_location=node.suffix_link.children[word_id].phrase_location,
  *                                 suffix_link=node.suffix_link.children[word_id],
  *                                 phrase=hiero_phrase)             # <<<<<<<<<<<<<<
  *                     else:
  *                         if arity > 0:
  */
-          if (PyDict_SetItem(__pyx_t_3, ((PyObject *)__pyx_n_s__phrase), ((PyObject *)__pyx_cur_scope->__pyx_v_hiero_phrase)) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-          __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_ExtendedTrieNode)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_3)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          if (PyDict_SetItem(__pyx_t_3, ((PyObject *)__pyx_n_s__phrase), ((PyObject *)__pyx_cur_scope->__pyx_v_hiero_phrase)) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_ExtendedTrieNode)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_3)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_1);
           __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
           __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_new_node);
@@ -48529,7 +48597,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         }
         /*else*/ {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1071
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1073
  *                                 phrase=hiero_phrase)
  *                     else:
  *                         if arity > 0:             # <<<<<<<<<<<<<<
@@ -48539,22 +48607,22 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __pyx_t_8 = (__pyx_cur_scope->__pyx_v_arity > 0);
           if (__pyx_t_8) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1073
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1075
  *                         if arity > 0:
  *                             # Intersecting because of arity > 0
  *                             phrase_location = self.intersect(node, node.suffix_link.children[word_id], hiero_phrase)             # <<<<<<<<<<<<<<
  *                         else:
  *                             # Suffix array search
  */
-            __pyx_t_1 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_1 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1075; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_1);
-            __pyx_t_3 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__children); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__children); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1075; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_3);
             __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-            __pyx_t_1 = PyObject_GetItem(__pyx_t_3, __pyx_cur_scope->__pyx_v_word_id); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_1 = PyObject_GetItem(__pyx_t_3, __pyx_cur_scope->__pyx_v_word_id); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1075; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_1);
             __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-            __pyx_t_3 = ((PyObject *)((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_cur_scope->__pyx_v_self->__pyx_vtab)->intersect(__pyx_cur_scope->__pyx_v_self, __pyx_cur_scope->__pyx_v_node, __pyx_t_1, __pyx_cur_scope->__pyx_v_hiero_phrase)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = ((PyObject *)((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_cur_scope->__pyx_v_self->__pyx_vtab)->intersect(__pyx_cur_scope->__pyx_v_self, __pyx_cur_scope->__pyx_v_node, __pyx_t_1, __pyx_cur_scope->__pyx_v_hiero_phrase)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1075; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_3);
             __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
             __Pyx_XGOTREF(((PyObject *)__pyx_cur_scope->__pyx_v_phrase_location));
@@ -48566,45 +48634,45 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           }
           /*else*/ {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1076
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1078
  *                         else:
  *                             # Suffix array search
  *                             phrase_location = node.phrase_location             # <<<<<<<<<<<<<<
  *                             sa_range = self.fsa.lookup(sym_tostring(phrase[-1]), len(phrase)-1, phrase_location.sa_low, phrase_location.sa_high)
  *                             if sa_range is not None:
  */
-            __pyx_t_3 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__phrase_location); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1076; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__phrase_location); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1078; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_3);
-            if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_3_sa_PhraseLocation))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1076; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_3_sa_PhraseLocation))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1078; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_XGOTREF(((PyObject *)__pyx_cur_scope->__pyx_v_phrase_location));
             __Pyx_XDECREF(((PyObject *)__pyx_cur_scope->__pyx_v_phrase_location));
             __Pyx_GIVEREF(__pyx_t_3);
             __pyx_cur_scope->__pyx_v_phrase_location = ((struct __pyx_obj_3_sa_PhraseLocation *)__pyx_t_3);
             __pyx_t_3 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1077
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1079
  *                             # Suffix array search
  *                             phrase_location = node.phrase_location
  *                             sa_range = self.fsa.lookup(sym_tostring(phrase[-1]), len(phrase)-1, phrase_location.sa_low, phrase_location.sa_high)             # <<<<<<<<<<<<<<
  *                             if sa_range is not None:
  *                                 phrase_location = PhraseLocation(sa_low=sa_range[0], sa_high=sa_range[1])
  */
-            __pyx_t_3 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self->fsa), __pyx_n_s__lookup); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self->fsa), __pyx_n_s__lookup); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1079; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_3);
-            __pyx_t_1 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_phrase, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_1 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_phrase, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1079; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_1);
-            __pyx_t_19 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_19 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_19 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_19 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1079; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-            __pyx_t_1 = PyBytes_FromString(__pyx_f_3_sa_sym_tostring(__pyx_t_19)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_1 = PyBytes_FromString(__pyx_f_3_sa_sym_tostring(__pyx_t_19)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1079; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-            __pyx_t_5 = PyObject_Length(__pyx_cur_scope->__pyx_v_phrase); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-            __pyx_t_16 = PyInt_FromSsize_t((__pyx_t_5 - 1)); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_5 = PyObject_Length(__pyx_cur_scope->__pyx_v_phrase); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1079; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_16 = PyInt_FromSsize_t((__pyx_t_5 - 1)); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1079; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_16);
-            __pyx_t_15 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_phrase_location->sa_low); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_15 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_phrase_location->sa_low); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1079; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_15);
-            __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_phrase_location->sa_high); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_phrase_location->sa_high); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1079; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_11);
-            __pyx_t_9 = PyTuple_New(4); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_9 = PyTuple_New(4); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1079; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_9);
             PyTuple_SET_ITEM(__pyx_t_9, 0, ((PyObject *)__pyx_t_1));
             __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
@@ -48618,7 +48686,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __pyx_t_16 = 0;
             __pyx_t_15 = 0;
             __pyx_t_11 = 0;
-            __pyx_t_11 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_11 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1079; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_11);
             __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
             __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
@@ -48628,7 +48696,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __pyx_cur_scope->__pyx_v_sa_range = __pyx_t_11;
             __pyx_t_11 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1078
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1080
  *                             phrase_location = node.phrase_location
  *                             sa_range = self.fsa.lookup(sym_tostring(phrase[-1]), len(phrase)-1, phrase_location.sa_low, phrase_location.sa_high)
  *                             if sa_range is not None:             # <<<<<<<<<<<<<<
@@ -48638,24 +48706,24 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __pyx_t_8 = (__pyx_cur_scope->__pyx_v_sa_range != Py_None);
             if (__pyx_t_8) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1079
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1081
  *                             sa_range = self.fsa.lookup(sym_tostring(phrase[-1]), len(phrase)-1, phrase_location.sa_low, phrase_location.sa_high)
  *                             if sa_range is not None:
  *                                 phrase_location = PhraseLocation(sa_low=sa_range[0], sa_high=sa_range[1])             # <<<<<<<<<<<<<<
  *                             else:
  *                                 phrase_location = None
  */
-              __pyx_t_11 = PyDict_New(); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1079; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_11 = PyDict_New(); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(((PyObject *)__pyx_t_11));
-              __pyx_t_9 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_sa_range, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1079; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_9 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_sa_range, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_9);
-              if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__sa_low), __pyx_t_9) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1079; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__sa_low), __pyx_t_9) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-              __pyx_t_9 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_sa_range, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1079; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_9 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_sa_range, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_9);
-              if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__sa_high), __pyx_t_9) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1079; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__sa_high), __pyx_t_9) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-              __pyx_t_9 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_PhraseLocation)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_11)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1079; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_9 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_PhraseLocation)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_11)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_9);
               __Pyx_DECREF(((PyObject *)__pyx_t_11)); __pyx_t_11 = 0;
               __Pyx_GOTREF(((PyObject *)__pyx_cur_scope->__pyx_v_phrase_location));
@@ -48667,7 +48735,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             }
             /*else*/ {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1081
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1083
  *                                 phrase_location = PhraseLocation(sa_low=sa_range[0], sa_high=sa_range[1])
  *                             else:
  *                                 phrase_location = None             # <<<<<<<<<<<<<<
@@ -48684,7 +48752,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           }
           __pyx_L34:;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1083
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1085
  *                                 phrase_location = None
  * 
  *                         if phrase_location is None:             # <<<<<<<<<<<<<<
@@ -48694,19 +48762,19 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __pyx_t_8 = (((PyObject *)__pyx_cur_scope->__pyx_v_phrase_location) == Py_None);
           if (__pyx_t_8) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1084
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1086
  * 
  *                         if phrase_location is None:
  *                             node.children[word_id] = None             # <<<<<<<<<<<<<<
  *                             # Search failed
  *                             continue
  */
-            __pyx_t_9 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1084; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_9 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1086; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_9);
-            if (PyObject_SetItem(__pyx_t_9, __pyx_cur_scope->__pyx_v_word_id, Py_None) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1084; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            if (PyObject_SetItem(__pyx_t_9, __pyx_cur_scope->__pyx_v_word_id, Py_None) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1086; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1086
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1088
  *                             node.children[word_id] = None
  *                             # Search failed
  *                             continue             # <<<<<<<<<<<<<<
@@ -48718,7 +48786,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           }
           __pyx_L36:;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1088
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1090
  *                             continue
  *                         # Search succeeded
  *                         suffix_link = self.rules.root             # <<<<<<<<<<<<<<
@@ -48731,32 +48799,32 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_self->rules->root);
           __pyx_cur_scope->__pyx_v_suffix_link = __pyx_cur_scope->__pyx_v_self->rules->root;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1089
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1091
  *                         # Search succeeded
  *                         suffix_link = self.rules.root
  *                         if node.suffix_link is not None:             # <<<<<<<<<<<<<<
  *                             suffix_link = node.suffix_link.children[word_id]
  *                         new_node = ExtendedTrieNode(phrase_location=phrase_location,
  */
-          __pyx_t_9 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1089; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1091; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
           __pyx_t_8 = (__pyx_t_9 != Py_None);
           __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
           if (__pyx_t_8) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1090
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1092
  *                         suffix_link = self.rules.root
  *                         if node.suffix_link is not None:
  *                             suffix_link = node.suffix_link.children[word_id]             # <<<<<<<<<<<<<<
  *                         new_node = ExtendedTrieNode(phrase_location=phrase_location,
  *                                 suffix_link=suffix_link,
  */
-            __pyx_t_9 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1090; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_9 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1092; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_9);
-            __pyx_t_11 = PyObject_GetAttr(__pyx_t_9, __pyx_n_s__children); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1090; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_11 = PyObject_GetAttr(__pyx_t_9, __pyx_n_s__children); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1092; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_11);
             __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-            __pyx_t_9 = PyObject_GetItem(__pyx_t_11, __pyx_cur_scope->__pyx_v_word_id); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1090; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_9 = PyObject_GetItem(__pyx_t_11, __pyx_cur_scope->__pyx_v_word_id); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1092; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_9);
             __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
             __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_suffix_link);
@@ -48768,35 +48836,35 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           }
           __pyx_L37:;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1091
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1093
  *                         if node.suffix_link is not None:
  *                             suffix_link = node.suffix_link.children[word_id]
  *                         new_node = ExtendedTrieNode(phrase_location=phrase_location,             # <<<<<<<<<<<<<<
  *                                 suffix_link=suffix_link,
  *                                 phrase=hiero_phrase)
  */
-          __pyx_t_9 = PyDict_New(); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1091; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyDict_New(); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(((PyObject *)__pyx_t_9));
-          if (PyDict_SetItem(__pyx_t_9, ((PyObject *)__pyx_n_s__phrase_location), ((PyObject *)__pyx_cur_scope->__pyx_v_phrase_location)) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1091; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          if (PyDict_SetItem(__pyx_t_9, ((PyObject *)__pyx_n_s__phrase_location), ((PyObject *)__pyx_cur_scope->__pyx_v_phrase_location)) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1092
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1094
  *                             suffix_link = node.suffix_link.children[word_id]
  *                         new_node = ExtendedTrieNode(phrase_location=phrase_location,
  *                                 suffix_link=suffix_link,             # <<<<<<<<<<<<<<
  *                                 phrase=hiero_phrase)
  *                     node.children[word_id] = new_node
  */
-          if (PyDict_SetItem(__pyx_t_9, ((PyObject *)__pyx_n_s__suffix_link), __pyx_cur_scope->__pyx_v_suffix_link) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1091; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          if (PyDict_SetItem(__pyx_t_9, ((PyObject *)__pyx_n_s__suffix_link), __pyx_cur_scope->__pyx_v_suffix_link) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1093
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1095
  *                         new_node = ExtendedTrieNode(phrase_location=phrase_location,
  *                                 suffix_link=suffix_link,
  *                                 phrase=hiero_phrase)             # <<<<<<<<<<<<<<
  *                     node.children[word_id] = new_node
  *                     node = new_node
  */
-          if (PyDict_SetItem(__pyx_t_9, ((PyObject *)__pyx_n_s__phrase), ((PyObject *)__pyx_cur_scope->__pyx_v_hiero_phrase)) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1091; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-          __pyx_t_11 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_ExtendedTrieNode)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_9)); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1091; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          if (PyDict_SetItem(__pyx_t_9, ((PyObject *)__pyx_n_s__phrase), ((PyObject *)__pyx_cur_scope->__pyx_v_hiero_phrase)) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_ExtendedTrieNode)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_9)); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
           __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
           __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_new_node);
@@ -48807,19 +48875,19 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         }
         __pyx_L33:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1094
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1096
  *                                 suffix_link=suffix_link,
  *                                 phrase=hiero_phrase)
  *                     node.children[word_id] = new_node             # <<<<<<<<<<<<<<
  *                     node = new_node
  * 
  */
-        __pyx_t_11 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1094; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_11 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1096; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_11);
-        if (PyObject_SetItem(__pyx_t_11, __pyx_cur_scope->__pyx_v_word_id, __pyx_cur_scope->__pyx_v_new_node) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1094; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (PyObject_SetItem(__pyx_t_11, __pyx_cur_scope->__pyx_v_word_id, __pyx_cur_scope->__pyx_v_new_node) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1096; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1095
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1097
  *                                 phrase=hiero_phrase)
  *                     node.children[word_id] = new_node
  *                     node = new_node             # <<<<<<<<<<<<<<
@@ -48832,7 +48900,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_new_node);
         __pyx_cur_scope->__pyx_v_node = __pyx_cur_scope->__pyx_v_new_node;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1100
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1102
  *                     This should happen before we get to extraction (so that
  *                     the node will exist if needed)'''
  *                     if arity < self.max_nonterminals:             # <<<<<<<<<<<<<<
@@ -48842,14 +48910,14 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         __pyx_t_8 = (__pyx_cur_scope->__pyx_v_arity < __pyx_cur_scope->__pyx_v_self->max_nonterminals);
         if (__pyx_t_8) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1101
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1103
  *                     the node will exist if needed)'''
  *                     if arity < self.max_nonterminals:
  *                         xcat_index = arity+1             # <<<<<<<<<<<<<<
  *                         xcat = sym_setindex(self.category, xcat_index)
  *                         suffix_link_xcat_index = xcat_index
  */
-          __pyx_t_11 = PyInt_FromLong((__pyx_cur_scope->__pyx_v_arity + 1)); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyInt_FromLong((__pyx_cur_scope->__pyx_v_arity + 1)); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
           __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_xcat_index);
           __Pyx_XDECREF(__pyx_cur_scope->__pyx_v_xcat_index);
@@ -48857,17 +48925,17 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __pyx_cur_scope->__pyx_v_xcat_index = __pyx_t_11;
           __pyx_t_11 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1102
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1104
  *                     if arity < self.max_nonterminals:
  *                         xcat_index = arity+1
  *                         xcat = sym_setindex(self.category, xcat_index)             # <<<<<<<<<<<<<<
  *                         suffix_link_xcat_index = xcat_index
  *                         if is_shadow_path:
  */
-          __pyx_t_19 = __Pyx_PyInt_AsInt(__pyx_cur_scope->__pyx_v_xcat_index); if (unlikely((__pyx_t_19 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_19 = __Pyx_PyInt_AsInt(__pyx_cur_scope->__pyx_v_xcat_index); if (unlikely((__pyx_t_19 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __pyx_cur_scope->__pyx_v_xcat = __pyx_f_3_sa_sym_setindex(__pyx_cur_scope->__pyx_v_self->category, __pyx_t_19);
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1103
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1105
  *                         xcat_index = arity+1
  *                         xcat = sym_setindex(self.category, xcat_index)
  *                         suffix_link_xcat_index = xcat_index             # <<<<<<<<<<<<<<
@@ -48880,24 +48948,24 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_xcat_index);
           __pyx_cur_scope->__pyx_v_suffix_link_xcat_index = __pyx_cur_scope->__pyx_v_xcat_index;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1104
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1106
  *                         xcat = sym_setindex(self.category, xcat_index)
  *                         suffix_link_xcat_index = xcat_index
  *                         if is_shadow_path:             # <<<<<<<<<<<<<<
  *                             suffix_link_xcat_index = xcat_index-1
  *                         suffix_link_xcat = sym_setindex(self.category, suffix_link_xcat_index)
  */
-          __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_cur_scope->__pyx_v_is_shadow_path); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_cur_scope->__pyx_v_is_shadow_path); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           if (__pyx_t_8) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1105
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1107
  *                         suffix_link_xcat_index = xcat_index
  *                         if is_shadow_path:
  *                             suffix_link_xcat_index = xcat_index-1             # <<<<<<<<<<<<<<
  *                         suffix_link_xcat = sym_setindex(self.category, suffix_link_xcat_index)
  *                         node.children[xcat] = ExtendedTrieNode(phrase_location=node.phrase_location,
  */
-            __pyx_t_11 = PyNumber_Subtract(__pyx_cur_scope->__pyx_v_xcat_index, __pyx_int_1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_11 = PyNumber_Subtract(__pyx_cur_scope->__pyx_v_xcat_index, __pyx_int_1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_11);
             __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_suffix_link_xcat_index);
             __Pyx_DECREF(__pyx_cur_scope->__pyx_v_suffix_link_xcat_index);
@@ -48908,159 +48976,159 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           }
           __pyx_L39:;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1106
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1108
  *                         if is_shadow_path:
  *                             suffix_link_xcat_index = xcat_index-1
  *                         suffix_link_xcat = sym_setindex(self.category, suffix_link_xcat_index)             # <<<<<<<<<<<<<<
  *                         node.children[xcat] = ExtendedTrieNode(phrase_location=node.phrase_location,
  *                                 suffix_link=node.suffix_link.children[suffix_link_xcat],
  */
-          __pyx_t_19 = __Pyx_PyInt_AsInt(__pyx_cur_scope->__pyx_v_suffix_link_xcat_index); if (unlikely((__pyx_t_19 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_19 = __Pyx_PyInt_AsInt(__pyx_cur_scope->__pyx_v_suffix_link_xcat_index); if (unlikely((__pyx_t_19 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __pyx_cur_scope->__pyx_v_suffix_link_xcat = __pyx_f_3_sa_sym_setindex(__pyx_cur_scope->__pyx_v_self->category, __pyx_t_19);
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1107
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1109
  *                             suffix_link_xcat_index = xcat_index-1
  *                         suffix_link_xcat = sym_setindex(self.category, suffix_link_xcat_index)
  *                         node.children[xcat] = ExtendedTrieNode(phrase_location=node.phrase_location,             # <<<<<<<<<<<<<<
  *                                 suffix_link=node.suffix_link.children[suffix_link_xcat],
  *                                 phrase= Phrase(phrase + (xcat,)))
  */
-          __pyx_t_11 = PyDict_New(); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyDict_New(); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(((PyObject *)__pyx_t_11));
-          __pyx_t_9 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__phrase_location); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__phrase_location); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
-          if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__phrase_location), __pyx_t_9) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__phrase_location), __pyx_t_9) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1108
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1110
  *                         suffix_link_xcat = sym_setindex(self.category, suffix_link_xcat_index)
  *                         node.children[xcat] = ExtendedTrieNode(phrase_location=node.phrase_location,
  *                                 suffix_link=node.suffix_link.children[suffix_link_xcat],             # <<<<<<<<<<<<<<
  *                                 phrase= Phrase(phrase + (xcat,)))
  * 
  */
-          __pyx_t_9 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__suffix_link); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
-          __pyx_t_3 = PyObject_GetAttr(__pyx_t_9, __pyx_n_s__children); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_3 = PyObject_GetAttr(__pyx_t_9, __pyx_n_s__children); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_3);
           __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-          __pyx_t_9 = __Pyx_GetItemInt(__pyx_t_3, __pyx_cur_scope->__pyx_v_suffix_link_xcat, sizeof(int), PyInt_FromLong); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = __Pyx_GetItemInt(__pyx_t_3, __pyx_cur_scope->__pyx_v_suffix_link_xcat, sizeof(int), PyInt_FromLong); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-          if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__suffix_link), __pyx_t_9) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__suffix_link), __pyx_t_9) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1109
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1111
  *                         node.children[xcat] = ExtendedTrieNode(phrase_location=node.phrase_location,
  *                                 suffix_link=node.suffix_link.children[suffix_link_xcat],
  *                                 phrase= Phrase(phrase + (xcat,)))             # <<<<<<<<<<<<<<
  * 
  *                     # sample from range
  */
-          __pyx_t_9 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_xcat); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_xcat); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
-          __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_3);
           PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_9);
           __Pyx_GIVEREF(__pyx_t_9);
           __pyx_t_9 = 0;
-          __pyx_t_9 = PyNumber_Add(__pyx_cur_scope->__pyx_v_phrase, ((PyObject *)__pyx_t_3)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyNumber_Add(__pyx_cur_scope->__pyx_v_phrase, ((PyObject *)__pyx_t_3)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
           __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
-          __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_3);
           PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_9);
           __Pyx_GIVEREF(__pyx_t_9);
           __pyx_t_9 = 0;
-          __pyx_t_9 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
           __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
-          if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__phrase), __pyx_t_9) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__phrase), __pyx_t_9) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-          __pyx_t_9 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_ExtendedTrieNode)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_11)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_ExtendedTrieNode)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_11)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
           __Pyx_DECREF(((PyObject *)__pyx_t_11)); __pyx_t_11 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1107
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1109
  *                             suffix_link_xcat_index = xcat_index-1
  *                         suffix_link_xcat = sym_setindex(self.category, suffix_link_xcat_index)
  *                         node.children[xcat] = ExtendedTrieNode(phrase_location=node.phrase_location,             # <<<<<<<<<<<<<<
  *                                 suffix_link=node.suffix_link.children[suffix_link_xcat],
  *                                 phrase= Phrase(phrase + (xcat,)))
  */
-          __pyx_t_11 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
-          if (__Pyx_SetItemInt(__pyx_t_11, __pyx_cur_scope->__pyx_v_xcat, __pyx_t_9, sizeof(int), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          if (__Pyx_SetItemInt(__pyx_t_11, __pyx_cur_scope->__pyx_v_xcat, __pyx_t_9, sizeof(int), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
           __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
           goto __pyx_L38;
         }
         __pyx_L38:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1112
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1114
  * 
  *                     # sample from range
  *                     if not is_shadow_path:             # <<<<<<<<<<<<<<
  *                         sample = self.sampler.sample(node.phrase_location)
  *                         num_subpatterns = (<PhraseLocation> node.phrase_location).num_subpatterns
  */
-        __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_cur_scope->__pyx_v_is_shadow_path); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_cur_scope->__pyx_v_is_shadow_path); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __pyx_t_20 = (!__pyx_t_8);
         if (__pyx_t_20) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1113
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1115
  *                     # sample from range
  *                     if not is_shadow_path:
  *                         sample = self.sampler.sample(node.phrase_location)             # <<<<<<<<<<<<<<
  *                         num_subpatterns = (<PhraseLocation> node.phrase_location).num_subpatterns
  *                         chunklen = IntList(initial_len=num_subpatterns)
  */
-          __pyx_t_9 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self->sampler), __pyx_n_s__sample); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self->sampler), __pyx_n_s__sample); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
-          __pyx_t_11 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__phrase_location); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__phrase_location); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
-          __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_3);
           PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_11);
           __Pyx_GIVEREF(__pyx_t_11);
           __pyx_t_11 = 0;
-          __pyx_t_11 = PyObject_Call(__pyx_t_9, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyObject_Call(__pyx_t_9, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
           __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
           __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
-          if (!(likely(((__pyx_t_11) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_11, __pyx_ptype_3_sa_IntList))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          if (!(likely(((__pyx_t_11) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_11, __pyx_ptype_3_sa_IntList))))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_XGOTREF(((PyObject *)__pyx_cur_scope->__pyx_v_sample));
           __Pyx_XDECREF(((PyObject *)__pyx_cur_scope->__pyx_v_sample));
           __Pyx_GIVEREF(__pyx_t_11);
           __pyx_cur_scope->__pyx_v_sample = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_11);
           __pyx_t_11 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1114
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1116
  *                     if not is_shadow_path:
  *                         sample = self.sampler.sample(node.phrase_location)
  *                         num_subpatterns = (<PhraseLocation> node.phrase_location).num_subpatterns             # <<<<<<<<<<<<<<
  *                         chunklen = IntList(initial_len=num_subpatterns)
  *                         for j from 0 <= j < num_subpatterns:
  */
-          __pyx_t_11 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__phrase_location); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__phrase_location); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
           __pyx_cur_scope->__pyx_v_num_subpatterns = ((struct __pyx_obj_3_sa_PhraseLocation *)__pyx_t_11)->num_subpatterns;
           __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1115
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1117
  *                         sample = self.sampler.sample(node.phrase_location)
  *                         num_subpatterns = (<PhraseLocation> node.phrase_location).num_subpatterns
  *                         chunklen = IntList(initial_len=num_subpatterns)             # <<<<<<<<<<<<<<
  *                         for j from 0 <= j < num_subpatterns:
  *                             chunklen.arr[j] = hiero_phrase.chunklen(j)
  */
-          __pyx_t_11 = PyDict_New(); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyDict_New(); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(((PyObject *)__pyx_t_11));
-          __pyx_t_3 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_num_subpatterns); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_3 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_num_subpatterns); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_3);
-          if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__initial_len), __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          if (PyDict_SetItem(__pyx_t_11, ((PyObject *)__pyx_n_s__initial_len), __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-          __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_11)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_11)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_3);
           __Pyx_DECREF(((PyObject *)__pyx_t_11)); __pyx_t_11 = 0;
           __Pyx_XGOTREF(((PyObject *)__pyx_cur_scope->__pyx_v_chunklen));
@@ -49069,7 +49137,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __pyx_cur_scope->__pyx_v_chunklen = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_3);
           __pyx_t_3 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1116
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1118
  *                         num_subpatterns = (<PhraseLocation> node.phrase_location).num_subpatterns
  *                         chunklen = IntList(initial_len=num_subpatterns)
  *                         for j from 0 <= j < num_subpatterns:             # <<<<<<<<<<<<<<
@@ -49079,7 +49147,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __pyx_t_19 = __pyx_cur_scope->__pyx_v_num_subpatterns;
           for (__pyx_cur_scope->__pyx_v_j = 0; __pyx_cur_scope->__pyx_v_j < __pyx_t_19; __pyx_cur_scope->__pyx_v_j++) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1117
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1119
  *                         chunklen = IntList(initial_len=num_subpatterns)
  *                         for j from 0 <= j < num_subpatterns:
  *                             chunklen.arr[j] = hiero_phrase.chunklen(j)             # <<<<<<<<<<<<<<
@@ -49089,14 +49157,14 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             (__pyx_cur_scope->__pyx_v_chunklen->arr[__pyx_cur_scope->__pyx_v_j]) = ((struct __pyx_vtabstruct_3_sa_Phrase *)__pyx_cur_scope->__pyx_v_hiero_phrase->__pyx_vtab)->chunklen(__pyx_cur_scope->__pyx_v_hiero_phrase, __pyx_cur_scope->__pyx_v_j);
           }
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1118
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1120
  *                         for j from 0 <= j < num_subpatterns:
  *                             chunklen.arr[j] = hiero_phrase.chunklen(j)
  *                         extracts = []             # <<<<<<<<<<<<<<
  *                         j = 0
  *                         extract_start = monitor_cpu()
  */
-          __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_3);
           __Pyx_XGOTREF(((PyObject *)__pyx_cur_scope->__pyx_v_extracts));
           __Pyx_XDECREF(((PyObject *)__pyx_cur_scope->__pyx_v_extracts));
@@ -49104,7 +49172,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __pyx_cur_scope->__pyx_v_extracts = __pyx_t_3;
           __pyx_t_3 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1119
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1121
  *                             chunklen.arr[j] = hiero_phrase.chunklen(j)
  *                         extracts = []
  *                         j = 0             # <<<<<<<<<<<<<<
@@ -49113,14 +49181,14 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
           __pyx_cur_scope->__pyx_v_j = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1120
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1122
  *                         extracts = []
  *                         j = 0
  *                         extract_start = monitor_cpu()             # <<<<<<<<<<<<<<
  *                         while j < sample.len:
  *                             extract = []
  */
-          __pyx_t_3 = PyFloat_FromDouble(__pyx_f_3_sa_monitor_cpu()); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_3 = PyFloat_FromDouble(__pyx_f_3_sa_monitor_cpu()); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_3);
           __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_extract_start);
           __Pyx_XDECREF(__pyx_cur_scope->__pyx_v_extract_start);
@@ -49128,7 +49196,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __pyx_cur_scope->__pyx_v_extract_start = __pyx_t_3;
           __pyx_t_3 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1121
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1123
  *                         j = 0
  *                         extract_start = monitor_cpu()
  *                         while j < sample.len:             # <<<<<<<<<<<<<<
@@ -49139,14 +49207,14 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __pyx_t_20 = (__pyx_cur_scope->__pyx_v_j < __pyx_cur_scope->__pyx_v_sample->len);
             if (!__pyx_t_20) break;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1122
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1124
  *                         extract_start = monitor_cpu()
  *                         while j < sample.len:
  *                             extract = []             # <<<<<<<<<<<<<<
  * 
  *                             assign_matching(&matching, sample.arr, j, num_subpatterns, self.fda.sent_id.arr)
  */
-            __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_3);
             __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_extract);
             __Pyx_XDECREF(__pyx_cur_scope->__pyx_v_extract);
@@ -49154,7 +49222,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __pyx_cur_scope->__pyx_v_extract = ((PyObject *)__pyx_t_3);
             __pyx_t_3 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1124
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1126
  *                             extract = []
  * 
  *                             assign_matching(&matching, sample.arr, j, num_subpatterns, self.fda.sent_id.arr)             # <<<<<<<<<<<<<<
@@ -49163,21 +49231,21 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
             __pyx_f_3_sa_assign_matching((&__pyx_cur_scope->__pyx_v_matching), __pyx_cur_scope->__pyx_v_sample->arr, __pyx_cur_scope->__pyx_v_j, __pyx_cur_scope->__pyx_v_num_subpatterns, __pyx_cur_scope->__pyx_v_self->fda->sent_id->arr);
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1125
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1127
  * 
  *                             assign_matching(&matching, sample.arr, j, num_subpatterns, self.fda.sent_id.arr)
  *                             loc = tuple(sample[j:j+num_subpatterns])             # <<<<<<<<<<<<<<
  *                             extract = self.extract(hiero_phrase, &matching, chunklen.arr, num_subpatterns)
  *                             extracts.extend([(e, loc) for e in extract])
  */
-            __pyx_t_3 = __Pyx_PySequence_GetSlice(((PyObject *)__pyx_cur_scope->__pyx_v_sample), __pyx_cur_scope->__pyx_v_j, (__pyx_cur_scope->__pyx_v_j + __pyx_cur_scope->__pyx_v_num_subpatterns)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = __Pyx_PySequence_GetSlice(((PyObject *)__pyx_cur_scope->__pyx_v_sample), __pyx_cur_scope->__pyx_v_j, (__pyx_cur_scope->__pyx_v_j + __pyx_cur_scope->__pyx_v_num_subpatterns)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_3);
-            __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_11);
             PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_3);
             __Pyx_GIVEREF(__pyx_t_3);
             __pyx_t_3 = 0;
-            __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_11), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_11), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_3);
             __Pyx_DECREF(((PyObject *)__pyx_t_11)); __pyx_t_11 = 0;
             __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_loc);
@@ -49186,14 +49254,14 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __pyx_cur_scope->__pyx_v_loc = __pyx_t_3;
             __pyx_t_3 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1126
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1128
  *                             assign_matching(&matching, sample.arr, j, num_subpatterns, self.fda.sent_id.arr)
  *                             loc = tuple(sample[j:j+num_subpatterns])
  *                             extract = self.extract(hiero_phrase, &matching, chunklen.arr, num_subpatterns)             # <<<<<<<<<<<<<<
  *                             extracts.extend([(e, loc) for e in extract])
  *                             j = j + num_subpatterns
  */
-            __pyx_t_3 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_cur_scope->__pyx_v_self->__pyx_vtab)->extract(__pyx_cur_scope->__pyx_v_self, __pyx_cur_scope->__pyx_v_hiero_phrase, (&__pyx_cur_scope->__pyx_v_matching), __pyx_cur_scope->__pyx_v_chunklen->arr, __pyx_cur_scope->__pyx_v_num_subpatterns); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_cur_scope->__pyx_v_self->__pyx_vtab)->extract(__pyx_cur_scope->__pyx_v_self, __pyx_cur_scope->__pyx_v_hiero_phrase, (&__pyx_cur_scope->__pyx_v_matching), __pyx_cur_scope->__pyx_v_chunklen->arr, __pyx_cur_scope->__pyx_v_num_subpatterns); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_3);
             __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_extract);
             __Pyx_DECREF(__pyx_cur_scope->__pyx_v_extract);
@@ -49201,22 +49269,22 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __pyx_cur_scope->__pyx_v_extract = __pyx_t_3;
             __pyx_t_3 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1127
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1129
  *                             loc = tuple(sample[j:j+num_subpatterns])
  *                             extract = self.extract(hiero_phrase, &matching, chunklen.arr, num_subpatterns)
  *                             extracts.extend([(e, loc) for e in extract])             # <<<<<<<<<<<<<<
  *                             j = j + num_subpatterns
  * 
  */
-            __pyx_t_3 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_extracts), __pyx_n_s__extend); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_extracts), __pyx_n_s__extend); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_3);
-            __pyx_t_11 = PyList_New(0); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_11 = PyList_New(0); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_11);
             if (PyList_CheckExact(__pyx_cur_scope->__pyx_v_extract) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_v_extract)) {
               __pyx_t_9 = __pyx_cur_scope->__pyx_v_extract; __Pyx_INCREF(__pyx_t_9); __pyx_t_5 = 0;
               __pyx_t_21 = NULL;
             } else {
-              __pyx_t_5 = -1; __pyx_t_9 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_extract); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_5 = -1; __pyx_t_9 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_extract); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_9);
               __pyx_t_21 = Py_TYPE(__pyx_t_9)->tp_iternext;
             }
@@ -49224,23 +49292,23 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
               if (!__pyx_t_21 && PyList_CheckExact(__pyx_t_9)) {
                 if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_9)) break;
                 #if CYTHON_COMPILING_IN_CPYTHON
-                __pyx_t_15 = PyList_GET_ITEM(__pyx_t_9, __pyx_t_5); __Pyx_INCREF(__pyx_t_15); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PyList_GET_ITEM(__pyx_t_9, __pyx_t_5); __Pyx_INCREF(__pyx_t_15); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 #else
-                __pyx_t_15 = PySequence_ITEM(__pyx_t_9, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PySequence_ITEM(__pyx_t_9, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 #endif
               } else if (!__pyx_t_21 && PyTuple_CheckExact(__pyx_t_9)) {
                 if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_9)) break;
                 #if CYTHON_COMPILING_IN_CPYTHON
-                __pyx_t_15 = PyTuple_GET_ITEM(__pyx_t_9, __pyx_t_5); __Pyx_INCREF(__pyx_t_15); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PyTuple_GET_ITEM(__pyx_t_9, __pyx_t_5); __Pyx_INCREF(__pyx_t_15); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 #else
-                __pyx_t_15 = PySequence_ITEM(__pyx_t_9, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PySequence_ITEM(__pyx_t_9, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 #endif
               } else {
                 __pyx_t_15 = __pyx_t_21(__pyx_t_9);
                 if (unlikely(!__pyx_t_15)) {
                   if (PyErr_Occurred()) {
                     if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-                    else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                    else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   }
                   break;
                 }
@@ -49251,7 +49319,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
               __Pyx_GIVEREF(__pyx_t_15);
               __pyx_cur_scope->__pyx_v_e = __pyx_t_15;
               __pyx_t_15 = 0;
-              __pyx_t_15 = PyTuple_New(2); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = PyTuple_New(2); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_15);
               __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e);
               PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_cur_scope->__pyx_v_e);
@@ -49259,23 +49327,23 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
               __Pyx_INCREF(__pyx_cur_scope->__pyx_v_loc);
               PyTuple_SET_ITEM(__pyx_t_15, 1, __pyx_cur_scope->__pyx_v_loc);
               __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_loc);
-              if (unlikely(__Pyx_PyList_Append(__pyx_t_11, (PyObject*)__pyx_t_15))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              if (unlikely(__Pyx_PyList_Append(__pyx_t_11, (PyObject*)__pyx_t_15))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
             }
             __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-            __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_9);
             __Pyx_INCREF(((PyObject *)__pyx_t_11));
             PyTuple_SET_ITEM(__pyx_t_9, 0, ((PyObject *)__pyx_t_11));
             __Pyx_GIVEREF(((PyObject *)__pyx_t_11));
             __Pyx_DECREF(((PyObject *)__pyx_t_11)); __pyx_t_11 = 0;
-            __pyx_t_11 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_11 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_11);
             __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
             __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
             __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1128
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1130
  *                             extract = self.extract(hiero_phrase, &matching, chunklen.arr, num_subpatterns)
  *                             extracts.extend([(e, loc) for e in extract])
  *                             j = j + num_subpatterns             # <<<<<<<<<<<<<<
@@ -49285,7 +49353,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __pyx_cur_scope->__pyx_v_j = (__pyx_cur_scope->__pyx_v_j + __pyx_cur_scope->__pyx_v_num_subpatterns);
           }
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1130
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1132
  *                             j = j + num_subpatterns
  * 
  *                         num_samples = sample.len/num_subpatterns             # <<<<<<<<<<<<<<
@@ -49294,22 +49362,22 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
           if (unlikely(__pyx_cur_scope->__pyx_v_num_subpatterns == 0)) {
             PyErr_Format(PyExc_ZeroDivisionError, "integer division or modulo by zero");
-            {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           }
           else if (sizeof(int) == sizeof(long) && unlikely(__pyx_cur_scope->__pyx_v_num_subpatterns == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_cur_scope->__pyx_v_sample->len))) {
             PyErr_Format(PyExc_OverflowError, "value too large to perform division");
-            {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           }
           __pyx_cur_scope->__pyx_v_num_samples = __Pyx_div_int(__pyx_cur_scope->__pyx_v_sample->len, __pyx_cur_scope->__pyx_v_num_subpatterns);
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1131
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1133
  * 
  *                         num_samples = sample.len/num_subpatterns
  *                         extract_stop = monitor_cpu()             # <<<<<<<<<<<<<<
  *                         self.extract_time = self.extract_time + extract_stop - extract_start
  *                         if len(extracts) > 0:
  */
-          __pyx_t_11 = PyFloat_FromDouble(__pyx_f_3_sa_monitor_cpu()); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyFloat_FromDouble(__pyx_f_3_sa_monitor_cpu()); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
           __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_extract_stop);
           __Pyx_XDECREF(__pyx_cur_scope->__pyx_v_extract_stop);
@@ -49317,46 +49385,46 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __pyx_cur_scope->__pyx_v_extract_stop = __pyx_t_11;
           __pyx_t_11 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1132
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1134
  *                         num_samples = sample.len/num_subpatterns
  *                         extract_stop = monitor_cpu()
  *                         self.extract_time = self.extract_time + extract_stop - extract_start             # <<<<<<<<<<<<<<
  *                         if len(extracts) > 0:
  *                             fcount = Counter()
  */
-          __pyx_t_11 = PyFloat_FromDouble(__pyx_cur_scope->__pyx_v_self->extract_time); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyFloat_FromDouble(__pyx_cur_scope->__pyx_v_self->extract_time); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
-          __pyx_t_9 = PyNumber_Add(__pyx_t_11, __pyx_cur_scope->__pyx_v_extract_stop); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyNumber_Add(__pyx_t_11, __pyx_cur_scope->__pyx_v_extract_stop); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
           __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-          __pyx_t_11 = PyNumber_Subtract(__pyx_t_9, __pyx_cur_scope->__pyx_v_extract_start); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyNumber_Subtract(__pyx_t_9, __pyx_cur_scope->__pyx_v_extract_start); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
           __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-          __pyx_t_22 = __pyx_PyFloat_AsFloat(__pyx_t_11); if (unlikely((__pyx_t_22 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_22 = __pyx_PyFloat_AsFloat(__pyx_t_11); if (unlikely((__pyx_t_22 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
           __pyx_cur_scope->__pyx_v_self->extract_time = __pyx_t_22;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1133
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1135
  *                         extract_stop = monitor_cpu()
  *                         self.extract_time = self.extract_time + extract_stop - extract_start
  *                         if len(extracts) > 0:             # <<<<<<<<<<<<<<
  *                             fcount = Counter()
  *                             fphrases = defaultdict(lambda: defaultdict(lambda: defaultdict(list)))
  */
-          __pyx_t_5 = PyList_GET_SIZE(((PyObject *)__pyx_cur_scope->__pyx_v_extracts)); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_5 = PyList_GET_SIZE(((PyObject *)__pyx_cur_scope->__pyx_v_extracts)); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __pyx_t_20 = (__pyx_t_5 > 0);
           if (__pyx_t_20) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1134
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1136
  *                         self.extract_time = self.extract_time + extract_stop - extract_start
  *                         if len(extracts) > 0:
  *                             fcount = Counter()             # <<<<<<<<<<<<<<
  *                             fphrases = defaultdict(lambda: defaultdict(lambda: defaultdict(list)))
  *                             for (f, e, count, als), loc in extracts:
  */
-            __pyx_t_11 = __Pyx_GetName(__pyx_m, __pyx_n_s__Counter); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_11 = __Pyx_GetName(__pyx_m, __pyx_n_s__Counter); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_11);
-            __pyx_t_9 = PyObject_Call(__pyx_t_11, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_9 = PyObject_Call(__pyx_t_11, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_9);
             __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
             __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_fcount);
@@ -49365,23 +49433,23 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __pyx_cur_scope->__pyx_v_fcount = __pyx_t_9;
             __pyx_t_9 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1135
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1137
  *                         if len(extracts) > 0:
  *                             fcount = Counter()
  *                             fphrases = defaultdict(lambda: defaultdict(lambda: defaultdict(list)))             # <<<<<<<<<<<<<<
  *                             for (f, e, count, als), loc in extracts:
  *                                 fcount[f] += count
  */
-            __pyx_t_9 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_9 = __Pyx_GetName(__pyx_m, __pyx_n_s__defaultdict); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_9);
-            __pyx_t_11 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_5input_lambda4, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_11 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_5input_lambda4, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_11);
-            __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_3);
             PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_11);
             __Pyx_GIVEREF(__pyx_t_11);
             __pyx_t_11 = 0;
-            __pyx_t_11 = PyObject_Call(__pyx_t_9, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_11 = PyObject_Call(__pyx_t_9, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_11);
             __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
             __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
@@ -49391,7 +49459,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __pyx_cur_scope->__pyx_v_fphrases = __pyx_t_11;
             __pyx_t_11 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1136
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1138
  *                             fcount = Counter()
  *                             fphrases = defaultdict(lambda: defaultdict(lambda: defaultdict(list)))
  *                             for (f, e, count, als), loc in extracts:             # <<<<<<<<<<<<<<
@@ -49402,9 +49470,9 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             for (;;) {
               if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_11)) break;
               #if CYTHON_COMPILING_IN_CPYTHON
-              __pyx_t_3 = PyList_GET_ITEM(__pyx_t_11, __pyx_t_5); __Pyx_INCREF(__pyx_t_3); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_3 = PyList_GET_ITEM(__pyx_t_11, __pyx_t_5); __Pyx_INCREF(__pyx_t_3); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               #else
-              __pyx_t_3 = PySequence_ITEM(__pyx_t_11, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_3 = PySequence_ITEM(__pyx_t_11, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               #endif
               if ((likely(PyTuple_CheckExact(__pyx_t_3))) || (PyList_CheckExact(__pyx_t_3))) {
                 PyObject* sequence = __pyx_t_3;
@@ -49416,7 +49484,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 if (unlikely(size != 2)) {
                   if (size > 2) __Pyx_RaiseTooManyValuesError(2);
                   else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 }
                 #if CYTHON_COMPILING_IN_CPYTHON
                 if (likely(PyTuple_CheckExact(sequence))) {
@@ -49429,14 +49497,14 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 __Pyx_INCREF(__pyx_t_9);
                 __Pyx_INCREF(__pyx_t_15);
                 #else
-                __pyx_t_9 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-                __pyx_t_15 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_9 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 #endif
                 __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
               } else
               {
                 Py_ssize_t index = -1;
-                __pyx_t_16 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_16 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_16);
                 __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
                 __pyx_t_18 = Py_TYPE(__pyx_t_16)->tp_iternext;
@@ -49444,7 +49512,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 __Pyx_GOTREF(__pyx_t_9);
                 index = 1; __pyx_t_15 = __pyx_t_18(__pyx_t_16); if (unlikely(!__pyx_t_15)) goto __pyx_L50_unpacking_failed;
                 __Pyx_GOTREF(__pyx_t_15);
-                if (__Pyx_IternextUnpackEndCheck(__pyx_t_18(__pyx_t_16), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                if (__Pyx_IternextUnpackEndCheck(__pyx_t_18(__pyx_t_16), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __pyx_t_18 = NULL;
                 __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
                 goto __pyx_L51_unpacking_done;
@@ -49452,7 +49520,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
                 __pyx_t_18 = NULL;
                 if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-                {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __pyx_L51_unpacking_done:;
               }
               if ((likely(PyTuple_CheckExact(__pyx_t_9))) || (PyList_CheckExact(__pyx_t_9))) {
@@ -49465,7 +49533,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 if (unlikely(size != 4)) {
                   if (size > 4) __Pyx_RaiseTooManyValuesError(4);
                   else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 }
                 #if CYTHON_COMPILING_IN_CPYTHON
                 if (likely(PyTuple_CheckExact(sequence))) {
@@ -49487,7 +49555,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 Py_ssize_t i;
                 PyObject** temps[4] = {&__pyx_t_16,&__pyx_t_1,&__pyx_t_10,&__pyx_t_7};
                 for (i=0; i < 4; i++) {
-                  PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   *(temps[i]) = item;
                 }
                 #endif
@@ -49496,7 +49564,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
               {
                 Py_ssize_t index = -1;
                 PyObject** temps[4] = {&__pyx_t_16,&__pyx_t_1,&__pyx_t_10,&__pyx_t_7};
-                __pyx_t_14 = PyObject_GetIter(__pyx_t_9); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_14 = PyObject_GetIter(__pyx_t_9); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_14);
                 __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
                 __pyx_t_18 = Py_TYPE(__pyx_t_14)->tp_iternext;
@@ -49505,7 +49573,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                   __Pyx_GOTREF(item);
                   *(temps[index]) = item;
                 }
-                if (__Pyx_IternextUnpackEndCheck(__pyx_t_18(__pyx_t_14), 4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                if (__Pyx_IternextUnpackEndCheck(__pyx_t_18(__pyx_t_14), 4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __pyx_t_18 = NULL;
                 __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
                 goto __pyx_L53_unpacking_done;
@@ -49513,7 +49581,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
                 __pyx_t_18 = NULL;
                 if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-                {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __pyx_L53_unpacking_done:;
               }
               __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_f);
@@ -49542,7 +49610,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
               __pyx_cur_scope->__pyx_v_loc = __pyx_t_15;
               __pyx_t_15 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1137
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1139
  *                             fphrases = defaultdict(lambda: defaultdict(lambda: defaultdict(list)))
  *                             for (f, e, count, als), loc in extracts:
  *                                 fcount[f] += count             # <<<<<<<<<<<<<<
@@ -49551,38 +49619,38 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
               __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f);
               __pyx_t_3 = __pyx_cur_scope->__pyx_v_f;
-              __pyx_t_15 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fcount, __pyx_t_3); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fcount, __pyx_t_3); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_15);
-              __pyx_t_9 = PyNumber_InPlaceAdd(__pyx_t_15, __pyx_cur_scope->__pyx_v_count); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_9 = PyNumber_InPlaceAdd(__pyx_t_15, __pyx_cur_scope->__pyx_v_count); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_9);
               __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
-              if (PyObject_SetItem(__pyx_cur_scope->__pyx_v_fcount, __pyx_t_3, __pyx_t_9) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              if (PyObject_SetItem(__pyx_cur_scope->__pyx_v_fcount, __pyx_t_3, __pyx_t_9) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
               __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1138
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1140
  *                             for (f, e, count, als), loc in extracts:
  *                                 fcount[f] += count
  *                                 fphrases[f][e][als].append(loc)             # <<<<<<<<<<<<<<
  *                             for f, elist in fphrases.iteritems():
  *                                 for e, alslist in elist.iteritems():
  */
-              __pyx_t_3 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fphrases, __pyx_cur_scope->__pyx_v_f); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_3 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fphrases, __pyx_cur_scope->__pyx_v_f); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_3);
-              __pyx_t_9 = PyObject_GetItem(__pyx_t_3, __pyx_cur_scope->__pyx_v_e); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_9 = PyObject_GetItem(__pyx_t_3, __pyx_cur_scope->__pyx_v_e); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_9);
               __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-              __pyx_t_3 = PyObject_GetItem(__pyx_t_9, __pyx_cur_scope->__pyx_v_als); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_3 = PyObject_GetItem(__pyx_t_9, __pyx_cur_scope->__pyx_v_als); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_3);
               __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-              __pyx_t_9 = __Pyx_PyObject_Append(__pyx_t_3, __pyx_cur_scope->__pyx_v_loc); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_9 = __Pyx_PyObject_Append(__pyx_t_3, __pyx_cur_scope->__pyx_v_loc); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_9);
               __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
               __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
             }
             __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1139
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1141
  *                                 fcount[f] += count
  *                                 fphrases[f][e][als].append(loc)
  *                             for f, elist in fphrases.iteritems():             # <<<<<<<<<<<<<<
@@ -49592,9 +49660,9 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __pyx_t_5 = 0;
             if (unlikely(__pyx_cur_scope->__pyx_v_fphrases == Py_None)) {
               PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "iteritems");
-              {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             }
-            __pyx_t_9 = __Pyx_dict_iterator(__pyx_cur_scope->__pyx_v_fphrases, 0, ((PyObject *)__pyx_n_s__iteritems), (&__pyx_t_23), (&__pyx_t_19)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_9 = __Pyx_dict_iterator(__pyx_cur_scope->__pyx_v_fphrases, 0, ((PyObject *)__pyx_n_s__iteritems), (&__pyx_t_23), (&__pyx_t_19)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_9);
             __Pyx_XDECREF(__pyx_t_11);
             __pyx_t_11 = __pyx_t_9;
@@ -49602,7 +49670,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             while (1) {
               __pyx_t_6 = __Pyx_dict_iter_next(__pyx_t_11, __pyx_t_23, &__pyx_t_5, &__pyx_t_9, &__pyx_t_3, NULL, __pyx_t_19);
               if (unlikely(__pyx_t_6 == 0)) break;
-              if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_9);
               __Pyx_GOTREF(__pyx_t_3);
               __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_f);
@@ -49616,7 +49684,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
               __pyx_cur_scope->__pyx_v_elist = __pyx_t_3;
               __pyx_t_3 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1140
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1142
  *                                 fphrases[f][e][als].append(loc)
  *                             for f, elist in fphrases.iteritems():
  *                                 for e, alslist in elist.iteritems():             # <<<<<<<<<<<<<<
@@ -49626,9 +49694,9 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
               __pyx_t_24 = 0;
               if (unlikely(__pyx_cur_scope->__pyx_v_elist == Py_None)) {
                 PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "iteritems");
-                {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               }
-              __pyx_t_9 = __Pyx_dict_iterator(__pyx_cur_scope->__pyx_v_elist, 0, ((PyObject *)__pyx_n_s__iteritems), (&__pyx_t_25), (&__pyx_t_6)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_9 = __Pyx_dict_iterator(__pyx_cur_scope->__pyx_v_elist, 0, ((PyObject *)__pyx_n_s__iteritems), (&__pyx_t_25), (&__pyx_t_6)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_9);
               __Pyx_XDECREF(__pyx_t_3);
               __pyx_t_3 = __pyx_t_9;
@@ -49636,7 +49704,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
               while (1) {
                 __pyx_t_4 = __Pyx_dict_iter_next(__pyx_t_3, __pyx_t_25, &__pyx_t_24, &__pyx_t_9, &__pyx_t_15, NULL, __pyx_t_6);
                 if (unlikely(__pyx_t_4 == 0)) break;
-                if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_9);
                 __Pyx_GOTREF(__pyx_t_15);
                 __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_e);
@@ -49650,30 +49718,30 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 __pyx_cur_scope->__pyx_v_alslist = __pyx_t_15;
                 __pyx_t_15 = 0;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1141
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1143
  *                             for f, elist in fphrases.iteritems():
  *                                 for e, alslist in elist.iteritems():
  *                                     alignment, max_locs = max(alslist.iteritems(), key=lambda x: len(x[1]))             # <<<<<<<<<<<<<<
  *                                     locs = tuple(itertools.chain.from_iterable(alslist.itervalues()))
  *                                     count = len(locs)
  */
-                __pyx_t_15 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_alslist, __pyx_n_s__iteritems); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_alslist, __pyx_n_s__iteritems); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_15);
-                __pyx_t_9 = PyObject_Call(__pyx_t_15, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_9 = PyObject_Call(__pyx_t_15, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_9);
                 __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
-                __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_15);
                 PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_t_9);
                 __Pyx_GIVEREF(__pyx_t_9);
                 __pyx_t_9 = 0;
-                __pyx_t_9 = PyDict_New(); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_9 = PyDict_New(); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(((PyObject *)__pyx_t_9));
-                __pyx_t_7 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_5input_1lambda6, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_7 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_5input_1lambda6, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_7);
-                if (PyDict_SetItem(__pyx_t_9, ((PyObject *)__pyx_n_s__key), __pyx_t_7) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                if (PyDict_SetItem(__pyx_t_9, ((PyObject *)__pyx_n_s__key), __pyx_t_7) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-                __pyx_t_7 = PyObject_Call(__pyx_builtin_max, ((PyObject *)__pyx_t_15), ((PyObject *)__pyx_t_9)); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_7 = PyObject_Call(__pyx_builtin_max, ((PyObject *)__pyx_t_15), ((PyObject *)__pyx_t_9)); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_7);
                 __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
                 __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
@@ -49687,7 +49755,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                   if (unlikely(size != 2)) {
                     if (size > 2) __Pyx_RaiseTooManyValuesError(2);
                     else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-                    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   }
                   #if CYTHON_COMPILING_IN_CPYTHON
                   if (likely(PyTuple_CheckExact(sequence))) {
@@ -49700,14 +49768,14 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                   __Pyx_INCREF(__pyx_t_9);
                   __Pyx_INCREF(__pyx_t_15);
                   #else
-                  __pyx_t_9 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-                  __pyx_t_15 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_9 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_15 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #endif
                   __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
                 } else
                 {
                   Py_ssize_t index = -1;
-                  __pyx_t_10 = PyObject_GetIter(__pyx_t_7); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_10 = PyObject_GetIter(__pyx_t_7); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __Pyx_GOTREF(__pyx_t_10);
                   __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
                   __pyx_t_18 = Py_TYPE(__pyx_t_10)->tp_iternext;
@@ -49715,7 +49783,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                   __Pyx_GOTREF(__pyx_t_9);
                   index = 1; __pyx_t_15 = __pyx_t_18(__pyx_t_10); if (unlikely(!__pyx_t_15)) goto __pyx_L58_unpacking_failed;
                   __Pyx_GOTREF(__pyx_t_15);
-                  if (__Pyx_IternextUnpackEndCheck(__pyx_t_18(__pyx_t_10), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  if (__Pyx_IternextUnpackEndCheck(__pyx_t_18(__pyx_t_10), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __pyx_t_18 = NULL;
                   __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
                   goto __pyx_L59_unpacking_done;
@@ -49723,7 +49791,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                   __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
                   __pyx_t_18 = NULL;
                   if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __pyx_L59_unpacking_done:;
                 }
                 __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_alignment);
@@ -49737,41 +49805,41 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 __pyx_cur_scope->__pyx_v_max_locs = __pyx_t_15;
                 __pyx_t_15 = 0;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1142
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1144
  *                                 for e, alslist in elist.iteritems():
  *                                     alignment, max_locs = max(alslist.iteritems(), key=lambda x: len(x[1]))
  *                                     locs = tuple(itertools.chain.from_iterable(alslist.itervalues()))             # <<<<<<<<<<<<<<
  *                                     count = len(locs)
  *                                     scores = self.scorer.score(FeatureContext(
  */
-                __pyx_t_7 = __Pyx_GetName(__pyx_m, __pyx_n_s__itertools); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_7 = __Pyx_GetName(__pyx_m, __pyx_n_s__itertools); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_7);
-                __pyx_t_15 = PyObject_GetAttr(__pyx_t_7, __pyx_n_s__chain); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PyObject_GetAttr(__pyx_t_7, __pyx_n_s__chain); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_15);
                 __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-                __pyx_t_7 = PyObject_GetAttr(__pyx_t_15, __pyx_n_s__from_iterable); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_7 = PyObject_GetAttr(__pyx_t_15, __pyx_n_s__from_iterable); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_7);
                 __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
-                __pyx_t_15 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_alslist, __pyx_n_s__itervalues); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_alslist, __pyx_n_s__itervalues); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_15);
-                __pyx_t_9 = PyObject_Call(__pyx_t_15, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_9 = PyObject_Call(__pyx_t_15, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_9);
                 __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
-                __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_15);
                 PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_t_9);
                 __Pyx_GIVEREF(__pyx_t_9);
                 __pyx_t_9 = 0;
-                __pyx_t_9 = PyObject_Call(__pyx_t_7, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_9 = PyObject_Call(__pyx_t_7, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_9);
                 __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
                 __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
-                __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_15);
                 PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_t_9);
                 __Pyx_GIVEREF(__pyx_t_9);
                 __pyx_t_9 = 0;
-                __pyx_t_9 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_9 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_9);
                 __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
                 __Pyx_XGOTREF(((PyObject *)__pyx_cur_scope->__pyx_v_locs));
@@ -49780,15 +49848,15 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 __pyx_cur_scope->__pyx_v_locs = ((PyObject*)__pyx_t_9);
                 __pyx_t_9 = 0;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1143
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1145
  *                                     alignment, max_locs = max(alslist.iteritems(), key=lambda x: len(x[1]))
  *                                     locs = tuple(itertools.chain.from_iterable(alslist.itervalues()))
  *                                     count = len(locs)             # <<<<<<<<<<<<<<
  *                                     scores = self.scorer.score(FeatureContext(
  *                                                f, e, count, fcount[f], num_samples,
  */
-                __pyx_t_26 = PyTuple_GET_SIZE(((PyObject *)__pyx_cur_scope->__pyx_v_locs)); if (unlikely(__pyx_t_26 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-                __pyx_t_9 = PyInt_FromSsize_t(__pyx_t_26); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_26 = PyTuple_GET_SIZE(((PyObject *)__pyx_cur_scope->__pyx_v_locs)); if (unlikely(__pyx_t_26 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_9 = PyInt_FromSsize_t(__pyx_t_26); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_9);
                 __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_count);
                 __Pyx_XDECREF(__pyx_cur_scope->__pyx_v_count);
@@ -49796,43 +49864,43 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 __pyx_cur_scope->__pyx_v_count = __pyx_t_9;
                 __pyx_t_9 = 0;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1144
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1146
  *                                     locs = tuple(itertools.chain.from_iterable(alslist.itervalues()))
  *                                     count = len(locs)
  *                                     scores = self.scorer.score(FeatureContext(             # <<<<<<<<<<<<<<
  *                                                f, e, count, fcount[f], num_samples,
  *                                                (k,i+spanlen), locs, input_match,
  */
-                __pyx_t_9 = __Pyx_GetName(__pyx_m, __pyx_n_s__FeatureContext); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_9 = __Pyx_GetName(__pyx_m, __pyx_n_s__FeatureContext); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_9);
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1145
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1147
  *                                     count = len(locs)
  *                                     scores = self.scorer.score(FeatureContext(
  *                                                f, e, count, fcount[f], num_samples,             # <<<<<<<<<<<<<<
  *                                                (k,i+spanlen), locs, input_match,
  *                                                fwords, self.fda, self.eda,
  */
-                __pyx_t_15 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fcount, __pyx_cur_scope->__pyx_v_f); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fcount, __pyx_cur_scope->__pyx_v_f); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_15);
-                __pyx_t_7 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_num_samples); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_7 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_num_samples); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_7);
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1146
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1148
  *                                     scores = self.scorer.score(FeatureContext(
  *                                                f, e, count, fcount[f], num_samples,
  *                                                (k,i+spanlen), locs, input_match,             # <<<<<<<<<<<<<<
  *                                                fwords, self.fda, self.eda,
  *                                                meta,
  */
-                __pyx_t_10 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_k); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_10 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_k); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_10);
-                __pyx_t_1 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_1 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_1);
-                __pyx_t_16 = PyNumber_Add(__pyx_t_1, __pyx_cur_scope->__pyx_v_spanlen); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_16 = PyNumber_Add(__pyx_t_1, __pyx_cur_scope->__pyx_v_spanlen); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_16);
                 __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-                __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_1);
                 PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_10);
                 __Pyx_GIVEREF(__pyx_t_10);
@@ -49841,16 +49909,16 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 __pyx_t_10 = 0;
                 __pyx_t_16 = 0;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1150
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1152
  *                                                meta,
  *                                                # Include online stats.  None if none.
  *                                                self.online_ctx_lookup(f, e)))             # <<<<<<<<<<<<<<
  *                                     # Phrase pair processed
  *                                     if self.online:
  */
-                __pyx_t_16 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__online_ctx_lookup); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_16 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__online_ctx_lookup); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_16);
-                __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_10);
                 __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f);
                 PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_cur_scope->__pyx_v_f);
@@ -49858,11 +49926,11 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e);
                 PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_cur_scope->__pyx_v_e);
                 __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_e);
-                __pyx_t_14 = PyObject_Call(__pyx_t_16, ((PyObject *)__pyx_t_10), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_14 = PyObject_Call(__pyx_t_16, ((PyObject *)__pyx_t_10), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_14);
                 __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
                 __Pyx_DECREF(((PyObject *)__pyx_t_10)); __pyx_t_10 = 0;
-                __pyx_t_10 = PyTuple_New(13); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_10 = PyTuple_New(13); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_10);
                 __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f);
                 PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_cur_scope->__pyx_v_f);
@@ -49903,11 +49971,11 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 __pyx_t_7 = 0;
                 __pyx_t_1 = 0;
                 __pyx_t_14 = 0;
-                __pyx_t_14 = PyObject_Call(__pyx_t_9, ((PyObject *)__pyx_t_10), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_14 = PyObject_Call(__pyx_t_9, ((PyObject *)__pyx_t_10), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_14);
                 __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
                 __Pyx_DECREF(((PyObject *)__pyx_t_10)); __pyx_t_10 = 0;
-                __pyx_t_10 = ((PyObject *)((struct __pyx_vtabstruct_3_sa_Scorer *)__pyx_cur_scope->__pyx_v_self->scorer->__pyx_vtab)->score(__pyx_cur_scope->__pyx_v_self->scorer, __pyx_t_14)); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_10 = ((PyObject *)((struct __pyx_vtabstruct_3_sa_Scorer *)__pyx_cur_scope->__pyx_v_self->scorer->__pyx_vtab)->score(__pyx_cur_scope->__pyx_v_self->scorer, __pyx_t_14)); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_10);
                 __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
                 __Pyx_XGOTREF(((PyObject *)__pyx_cur_scope->__pyx_v_scores));
@@ -49916,7 +49984,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 __pyx_cur_scope->__pyx_v_scores = ((struct __pyx_obj_3_sa_FeatureVector *)__pyx_t_10);
                 __pyx_t_10 = 0;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1152
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1154
  *                                                self.online_ctx_lookup(f, e)))
  *                                     # Phrase pair processed
  *                                     if self.online:             # <<<<<<<<<<<<<<
@@ -49925,14 +49993,14 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
                 if (__pyx_cur_scope->__pyx_v_self->online) {
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1153
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1155
  *                                     # Phrase pair processed
  *                                     if self.online:
  *                                         seen_phrases.add((f, e))             # <<<<<<<<<<<<<<
  *                                     yield Rule(self.category, f, e, scores, alignment)
  * 
  */
-                  __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __Pyx_GOTREF(__pyx_t_10);
                   __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f);
                   PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_cur_scope->__pyx_v_f);
@@ -49940,22 +50008,22 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                   __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e);
                   PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_cur_scope->__pyx_v_e);
                   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_e);
-                  __pyx_t_12 = PySet_Add(__pyx_cur_scope->__pyx_v_seen_phrases, ((PyObject *)__pyx_t_10)); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_12 = PySet_Add(__pyx_cur_scope->__pyx_v_seen_phrases, ((PyObject *)__pyx_t_10)); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __Pyx_DECREF(((PyObject *)__pyx_t_10)); __pyx_t_10 = 0;
                   goto __pyx_L60;
                 }
                 __pyx_L60:;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1154
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1156
  *                                     if self.online:
  *                                         seen_phrases.add((f, e))
  *                                     yield Rule(self.category, f, e, scores, alignment)             # <<<<<<<<<<<<<<
  * 
  *                 if len(phrase) < self.max_length and i+spanlen < len(fwords) and pathlen+1 <= self.max_initial_size:
  */
-                __pyx_t_10 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->category); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_10 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->category); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_10);
-                __pyx_t_14 = PyTuple_New(5); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_14 = PyTuple_New(5); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_14);
                 PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_t_10);
                 __Pyx_GIVEREF(__pyx_t_10);
@@ -49972,7 +50040,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 PyTuple_SET_ITEM(__pyx_t_14, 4, __pyx_cur_scope->__pyx_v_alignment);
                 __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_alignment);
                 __pyx_t_10 = 0;
-                __pyx_t_10 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Rule)), ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_10 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Rule)), ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_10);
                 __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
                 __pyx_r = __pyx_t_10;
@@ -50012,7 +50080,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
                 __pyx_t_23 = __pyx_cur_scope->__pyx_t_7;
                 __pyx_t_24 = __pyx_cur_scope->__pyx_t_8;
                 __pyx_t_25 = __pyx_cur_scope->__pyx_t_9;
-                if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               }
               __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
             }
@@ -50027,41 +50095,41 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       }
       __pyx_L32:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1156
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1158
  *                                     yield Rule(self.category, f, e, scores, alignment)
  * 
  *                 if len(phrase) < self.max_length and i+spanlen < len(fwords) and pathlen+1 <= self.max_initial_size:             # <<<<<<<<<<<<<<
  *                     for alt_id in range(len(fwords[i+spanlen])):
  *                         new_frontier.append((k, i+spanlen, input_match, alt_id, pathlen + 1, node, phrase, is_shadow_path))
  */
-      __pyx_t_23 = PyObject_Length(__pyx_cur_scope->__pyx_v_phrase); if (unlikely(__pyx_t_23 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_23 = PyObject_Length(__pyx_cur_scope->__pyx_v_phrase); if (unlikely(__pyx_t_23 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_t_20 = (__pyx_t_23 < __pyx_cur_scope->__pyx_v_self->max_length);
       if (__pyx_t_20) {
-        __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_11);
-        __pyx_t_3 = PyNumber_Add(__pyx_t_11, __pyx_cur_scope->__pyx_v_spanlen); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = PyNumber_Add(__pyx_t_11, __pyx_cur_scope->__pyx_v_spanlen); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
         __pyx_t_11 = __pyx_cur_scope->__pyx_v_fwords;
         __Pyx_INCREF(__pyx_t_11);
-        __pyx_t_23 = PyObject_Length(__pyx_t_11); if (unlikely(__pyx_t_23 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_23 = PyObject_Length(__pyx_t_11); if (unlikely(__pyx_t_23 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-        __pyx_t_11 = PyInt_FromSsize_t(__pyx_t_23); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_11 = PyInt_FromSsize_t(__pyx_t_23); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_11);
-        __pyx_t_10 = PyObject_RichCompare(__pyx_t_3, __pyx_t_11, Py_LT); __Pyx_XGOTREF(__pyx_t_10); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_10 = PyObject_RichCompare(__pyx_t_3, __pyx_t_11, Py_LT); __Pyx_XGOTREF(__pyx_t_10); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-        __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
         if (__pyx_t_8) {
-          __pyx_t_10 = PyNumber_Add(__pyx_cur_scope->__pyx_v_pathlen, __pyx_int_1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_10 = PyNumber_Add(__pyx_cur_scope->__pyx_v_pathlen, __pyx_int_1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_10);
-          __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_initial_size); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_initial_size); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
-          __pyx_t_3 = PyObject_RichCompare(__pyx_t_10, __pyx_t_11, Py_LE); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_3 = PyObject_RichCompare(__pyx_t_10, __pyx_t_11, Py_LE); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
           __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-          __pyx_t_27 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_27 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_27 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_27 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
           __pyx_t_28 = __pyx_t_27;
         } else {
@@ -50073,45 +50141,45 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       }
       if (__pyx_t_8) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1157
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1159
  * 
  *                 if len(phrase) < self.max_length and i+spanlen < len(fwords) and pathlen+1 <= self.max_initial_size:
  *                     for alt_id in range(len(fwords[i+spanlen])):             # <<<<<<<<<<<<<<
  *                         new_frontier.append((k, i+spanlen, input_match, alt_id, pathlen + 1, node, phrase, is_shadow_path))
  *                     num_subpatterns = arity
  */
-        __pyx_t_3 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_3);
-        __pyx_t_11 = PyNumber_Add(__pyx_t_3, __pyx_cur_scope->__pyx_v_spanlen); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_11 = PyNumber_Add(__pyx_t_3, __pyx_cur_scope->__pyx_v_spanlen); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_11);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_3 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fwords, __pyx_t_11); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fwords, __pyx_t_11); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-        __pyx_t_23 = PyObject_Length(__pyx_t_3); if (unlikely(__pyx_t_23 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_23 = PyObject_Length(__pyx_t_3); if (unlikely(__pyx_t_23 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         for (__pyx_t_19 = 0; __pyx_t_19 < __pyx_t_23; __pyx_t_19+=1) {
           __pyx_cur_scope->__pyx_v_alt_id = __pyx_t_19;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1158
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1160
  *                 if len(phrase) < self.max_length and i+spanlen < len(fwords) and pathlen+1 <= self.max_initial_size:
  *                     for alt_id in range(len(fwords[i+spanlen])):
  *                         new_frontier.append((k, i+spanlen, input_match, alt_id, pathlen + 1, node, phrase, is_shadow_path))             # <<<<<<<<<<<<<<
  *                     num_subpatterns = arity
  *                     if not is_shadow_path:
  */
-          __pyx_t_3 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_k); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_3 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_k); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_3);
-          __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
-          __pyx_t_10 = PyNumber_Add(__pyx_t_11, __pyx_cur_scope->__pyx_v_spanlen); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_10 = PyNumber_Add(__pyx_t_11, __pyx_cur_scope->__pyx_v_spanlen); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_10);
           __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-          __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_alt_id); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_alt_id); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
-          __pyx_t_14 = PyNumber_Add(__pyx_cur_scope->__pyx_v_pathlen, __pyx_int_1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_14 = PyNumber_Add(__pyx_cur_scope->__pyx_v_pathlen, __pyx_int_1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_14);
-          __pyx_t_9 = PyTuple_New(8); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyTuple_New(8); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
           PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_3);
           __Pyx_GIVEREF(__pyx_t_3);
@@ -50137,11 +50205,11 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __pyx_t_10 = 0;
           __pyx_t_11 = 0;
           __pyx_t_14 = 0;
-          __pyx_t_12 = PyList_Append(__pyx_cur_scope->__pyx_v_new_frontier, ((PyObject *)__pyx_t_9)); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_12 = PyList_Append(__pyx_cur_scope->__pyx_v_new_frontier, ((PyObject *)__pyx_t_9)); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
         }
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1159
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1161
  *                     for alt_id in range(len(fwords[i+spanlen])):
  *                         new_frontier.append((k, i+spanlen, input_match, alt_id, pathlen + 1, node, phrase, is_shadow_path))
  *                     num_subpatterns = arity             # <<<<<<<<<<<<<<
@@ -50150,18 +50218,18 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
         __pyx_cur_scope->__pyx_v_num_subpatterns = __pyx_cur_scope->__pyx_v_arity;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1160
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1162
  *                         new_frontier.append((k, i+spanlen, input_match, alt_id, pathlen + 1, node, phrase, is_shadow_path))
  *                     num_subpatterns = arity
  *                     if not is_shadow_path:             # <<<<<<<<<<<<<<
  *                         num_subpatterns = num_subpatterns + 1
  *                     if len(phrase)+1 < self.max_length and arity < self.max_nonterminals and num_subpatterns < self.max_chunks:
  */
-        __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_cur_scope->__pyx_v_is_shadow_path); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_cur_scope->__pyx_v_is_shadow_path); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __pyx_t_20 = (!__pyx_t_8);
         if (__pyx_t_20) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1161
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1163
  *                     num_subpatterns = arity
  *                     if not is_shadow_path:
  *                         num_subpatterns = num_subpatterns + 1             # <<<<<<<<<<<<<<
@@ -50173,14 +50241,14 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         }
         __pyx_L65:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1162
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1164
  *                     if not is_shadow_path:
  *                         num_subpatterns = num_subpatterns + 1
  *                     if len(phrase)+1 < self.max_length and arity < self.max_nonterminals and num_subpatterns < self.max_chunks:             # <<<<<<<<<<<<<<
  *                         xcat = sym_setindex(self.category, arity+1)
  *                         xnode = node.children[xcat]
  */
-        __pyx_t_23 = PyObject_Length(__pyx_cur_scope->__pyx_v_phrase); if (unlikely(__pyx_t_23 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_23 = PyObject_Length(__pyx_cur_scope->__pyx_v_phrase); if (unlikely(__pyx_t_23 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __pyx_t_20 = ((__pyx_t_23 + 1) < __pyx_cur_scope->__pyx_v_self->max_length);
         if (__pyx_t_20) {
           __pyx_t_8 = (__pyx_cur_scope->__pyx_v_arity < __pyx_cur_scope->__pyx_v_self->max_nonterminals);
@@ -50196,7 +50264,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         }
         if (__pyx_t_8) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1163
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1165
  *                         num_subpatterns = num_subpatterns + 1
  *                     if len(phrase)+1 < self.max_length and arity < self.max_nonterminals and num_subpatterns < self.max_chunks:
  *                         xcat = sym_setindex(self.category, arity+1)             # <<<<<<<<<<<<<<
@@ -50205,16 +50273,16 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
           __pyx_cur_scope->__pyx_v_xcat = __pyx_f_3_sa_sym_setindex(__pyx_cur_scope->__pyx_v_self->category, (__pyx_cur_scope->__pyx_v_arity + 1));
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1164
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1166
  *                     if len(phrase)+1 < self.max_length and arity < self.max_nonterminals and num_subpatterns < self.max_chunks:
  *                         xcat = sym_setindex(self.category, arity+1)
  *                         xnode = node.children[xcat]             # <<<<<<<<<<<<<<
  *                         # I put spanlen=1 below
  *                         key = tuple([self.min_gap_size, i, 1, pathlen])
  */
-          __pyx_t_9 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_node, __pyx_n_s__children); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
-          __pyx_t_14 = __Pyx_GetItemInt(__pyx_t_9, __pyx_cur_scope->__pyx_v_xcat, sizeof(int), PyInt_FromLong); if (!__pyx_t_14) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_14 = __Pyx_GetItemInt(__pyx_t_9, __pyx_cur_scope->__pyx_v_xcat, sizeof(int), PyInt_FromLong); if (!__pyx_t_14) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_14);
           __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
           __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_xnode);
@@ -50223,18 +50291,18 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __pyx_cur_scope->__pyx_v_xnode = __pyx_t_14;
           __pyx_t_14 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1166
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1168
  *                         xnode = node.children[xcat]
  *                         # I put spanlen=1 below
  *                         key = tuple([self.min_gap_size, i, 1, pathlen])             # <<<<<<<<<<<<<<
  *                         frontier_nodes = []
  *                         if (key in nodes_isteps_away_buffer):
  */
-          __pyx_t_14 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->min_gap_size); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_14 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->min_gap_size); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_14);
-          __pyx_t_9 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
-          __pyx_t_11 = PyList_New(4); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyList_New(4); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
           PyList_SET_ITEM(__pyx_t_11, 0, __pyx_t_14);
           __Pyx_GIVEREF(__pyx_t_14);
@@ -50248,7 +50316,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_pathlen);
           __pyx_t_14 = 0;
           __pyx_t_9 = 0;
-          __pyx_t_9 = ((PyObject *)PyList_AsTuple(__pyx_t_11)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = ((PyObject *)PyList_AsTuple(__pyx_t_11)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(((PyObject *)__pyx_t_9));
           __Pyx_DECREF(((PyObject *)__pyx_t_11)); __pyx_t_11 = 0;
           __Pyx_XGOTREF(((PyObject *)__pyx_cur_scope->__pyx_v_key));
@@ -50257,14 +50325,14 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __pyx_cur_scope->__pyx_v_key = __pyx_t_9;
           __pyx_t_9 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1167
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1169
  *                         # I put spanlen=1 below
  *                         key = tuple([self.min_gap_size, i, 1, pathlen])
  *                         frontier_nodes = []             # <<<<<<<<<<<<<<
  *                         if (key in nodes_isteps_away_buffer):
  *                             frontier_nodes = nodes_isteps_away_buffer[key]
  */
-          __pyx_t_9 = PyList_New(0); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyList_New(0); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
           __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_frontier_nodes);
           __Pyx_XDECREF(__pyx_cur_scope->__pyx_v_frontier_nodes);
@@ -50272,24 +50340,24 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __pyx_cur_scope->__pyx_v_frontier_nodes = ((PyObject *)__pyx_t_9);
           __pyx_t_9 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1168
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1170
  *                         key = tuple([self.min_gap_size, i, 1, pathlen])
  *                         frontier_nodes = []
  *                         if (key in nodes_isteps_away_buffer):             # <<<<<<<<<<<<<<
  *                             frontier_nodes = nodes_isteps_away_buffer[key]
  *                         else:
  */
-          __pyx_t_8 = (__Pyx_PyDict_Contains(((PyObject *)__pyx_cur_scope->__pyx_v_key), ((PyObject *)__pyx_cur_scope->__pyx_v_nodes_isteps_away_buffer), Py_EQ)); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_8 = (__Pyx_PyDict_Contains(((PyObject *)__pyx_cur_scope->__pyx_v_key), ((PyObject *)__pyx_cur_scope->__pyx_v_nodes_isteps_away_buffer), Py_EQ)); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           if (__pyx_t_8) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1169
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1171
  *                         frontier_nodes = []
  *                         if (key in nodes_isteps_away_buffer):
  *                             frontier_nodes = nodes_isteps_away_buffer[key]             # <<<<<<<<<<<<<<
  *                         else:
  *                             frontier_nodes = self.get_all_nodes_isteps_away(self.min_gap_size, i, 1, pathlen, fwords, next_states, reachable_buffer)
  */
-            __pyx_t_9 = __Pyx_PyDict_GetItem(((PyObject *)__pyx_cur_scope->__pyx_v_nodes_isteps_away_buffer), ((PyObject *)__pyx_cur_scope->__pyx_v_key)); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_9 = __Pyx_PyDict_GetItem(((PyObject *)__pyx_cur_scope->__pyx_v_nodes_isteps_away_buffer), ((PyObject *)__pyx_cur_scope->__pyx_v_key)); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_9);
             __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_frontier_nodes);
             __Pyx_DECREF(__pyx_cur_scope->__pyx_v_frontier_nodes);
@@ -50300,20 +50368,20 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           }
           /*else*/ {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1171
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1173
  *                             frontier_nodes = nodes_isteps_away_buffer[key]
  *                         else:
  *                             frontier_nodes = self.get_all_nodes_isteps_away(self.min_gap_size, i, 1, pathlen, fwords, next_states, reachable_buffer)             # <<<<<<<<<<<<<<
  *                             nodes_isteps_away_buffer[key] = frontier_nodes
  * 
  */
-            __pyx_t_9 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s_123); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_9 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s_123); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_9);
-            __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->min_gap_size); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->min_gap_size); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_11);
-            __pyx_t_14 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_14 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_14);
-            __pyx_t_10 = PyTuple_New(7); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_10 = PyTuple_New(7); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_10);
             PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_11);
             __Pyx_GIVEREF(__pyx_t_11);
@@ -50336,7 +50404,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __Pyx_GIVEREF(((PyObject *)__pyx_cur_scope->__pyx_v_reachable_buffer));
             __pyx_t_11 = 0;
             __pyx_t_14 = 0;
-            __pyx_t_14 = PyObject_Call(__pyx_t_9, ((PyObject *)__pyx_t_10), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_14 = PyObject_Call(__pyx_t_9, ((PyObject *)__pyx_t_10), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_14);
             __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
             __Pyx_DECREF(((PyObject *)__pyx_t_10)); __pyx_t_10 = 0;
@@ -50346,18 +50414,18 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __pyx_cur_scope->__pyx_v_frontier_nodes = __pyx_t_14;
             __pyx_t_14 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1172
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1174
  *                         else:
  *                             frontier_nodes = self.get_all_nodes_isteps_away(self.min_gap_size, i, 1, pathlen, fwords, next_states, reachable_buffer)
  *                             nodes_isteps_away_buffer[key] = frontier_nodes             # <<<<<<<<<<<<<<
  * 
  *                         for (i, alt, pathlen) in frontier_nodes:
  */
-            if (PyDict_SetItem(((PyObject *)__pyx_cur_scope->__pyx_v_nodes_isteps_away_buffer), ((PyObject *)__pyx_cur_scope->__pyx_v_key), __pyx_cur_scope->__pyx_v_frontier_nodes) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            if (PyDict_SetItem(((PyObject *)__pyx_cur_scope->__pyx_v_nodes_isteps_away_buffer), ((PyObject *)__pyx_cur_scope->__pyx_v_key), __pyx_cur_scope->__pyx_v_frontier_nodes) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           }
           __pyx_L67:;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1174
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1176
  *                             nodes_isteps_away_buffer[key] = frontier_nodes
  * 
  *                         for (i, alt, pathlen) in frontier_nodes:             # <<<<<<<<<<<<<<
@@ -50368,7 +50436,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __pyx_t_14 = __pyx_cur_scope->__pyx_v_frontier_nodes; __Pyx_INCREF(__pyx_t_14); __pyx_t_23 = 0;
             __pyx_t_21 = NULL;
           } else {
-            __pyx_t_23 = -1; __pyx_t_14 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_frontier_nodes); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_23 = -1; __pyx_t_14 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_frontier_nodes); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_14);
             __pyx_t_21 = Py_TYPE(__pyx_t_14)->tp_iternext;
           }
@@ -50376,23 +50444,23 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             if (!__pyx_t_21 && PyList_CheckExact(__pyx_t_14)) {
               if (__pyx_t_23 >= PyList_GET_SIZE(__pyx_t_14)) break;
               #if CYTHON_COMPILING_IN_CPYTHON
-              __pyx_t_10 = PyList_GET_ITEM(__pyx_t_14, __pyx_t_23); __Pyx_INCREF(__pyx_t_10); __pyx_t_23++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_10 = PyList_GET_ITEM(__pyx_t_14, __pyx_t_23); __Pyx_INCREF(__pyx_t_10); __pyx_t_23++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               #else
-              __pyx_t_10 = PySequence_ITEM(__pyx_t_14, __pyx_t_23); __pyx_t_23++; if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_10 = PySequence_ITEM(__pyx_t_14, __pyx_t_23); __pyx_t_23++; if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               #endif
             } else if (!__pyx_t_21 && PyTuple_CheckExact(__pyx_t_14)) {
               if (__pyx_t_23 >= PyTuple_GET_SIZE(__pyx_t_14)) break;
               #if CYTHON_COMPILING_IN_CPYTHON
-              __pyx_t_10 = PyTuple_GET_ITEM(__pyx_t_14, __pyx_t_23); __Pyx_INCREF(__pyx_t_10); __pyx_t_23++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_10 = PyTuple_GET_ITEM(__pyx_t_14, __pyx_t_23); __Pyx_INCREF(__pyx_t_10); __pyx_t_23++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               #else
-              __pyx_t_10 = PySequence_ITEM(__pyx_t_14, __pyx_t_23); __pyx_t_23++; if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_10 = PySequence_ITEM(__pyx_t_14, __pyx_t_23); __pyx_t_23++; if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               #endif
             } else {
               __pyx_t_10 = __pyx_t_21(__pyx_t_14);
               if (unlikely(!__pyx_t_10)) {
                 if (PyErr_Occurred()) {
                   if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-                  else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 }
                 break;
               }
@@ -50408,7 +50476,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
               if (unlikely(size != 3)) {
                 if (size > 3) __Pyx_RaiseTooManyValuesError(3);
                 else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-                {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               }
               #if CYTHON_COMPILING_IN_CPYTHON
               if (likely(PyTuple_CheckExact(sequence))) {
@@ -50424,15 +50492,15 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
               __Pyx_INCREF(__pyx_t_11);
               __Pyx_INCREF(__pyx_t_3);
               #else
-              __pyx_t_9 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-              __pyx_t_11 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-              __pyx_t_3 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_9 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_11 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_3 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               #endif
               __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
             } else
             {
               Py_ssize_t index = -1;
-              __pyx_t_1 = PyObject_GetIter(__pyx_t_10); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_1 = PyObject_GetIter(__pyx_t_10); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_1);
               __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
               __pyx_t_18 = Py_TYPE(__pyx_t_1)->tp_iternext;
@@ -50442,7 +50510,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
               __Pyx_GOTREF(__pyx_t_11);
               index = 2; __pyx_t_3 = __pyx_t_18(__pyx_t_1); if (unlikely(!__pyx_t_3)) goto __pyx_L70_unpacking_failed;
               __Pyx_GOTREF(__pyx_t_3);
-              if (__Pyx_IternextUnpackEndCheck(__pyx_t_18(__pyx_t_1), 3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              if (__Pyx_IternextUnpackEndCheck(__pyx_t_18(__pyx_t_1), 3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __pyx_t_18 = NULL;
               __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
               goto __pyx_L71_unpacking_done;
@@ -50450,12 +50518,12 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
               __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
               __pyx_t_18 = NULL;
               if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-              {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __pyx_L71_unpacking_done:;
             }
-            __pyx_t_19 = __Pyx_PyInt_AsInt(__pyx_t_9); if (unlikely((__pyx_t_19 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_19 = __Pyx_PyInt_AsInt(__pyx_t_9); if (unlikely((__pyx_t_19 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-            __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_t_11); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_t_11); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
             __pyx_cur_scope->__pyx_v_i = __pyx_t_19;
             __pyx_cur_scope->__pyx_v_alt = __pyx_t_6;
@@ -50465,40 +50533,40 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __pyx_cur_scope->__pyx_v_pathlen = __pyx_t_3;
             __pyx_t_3 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1175
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1177
  * 
  *                         for (i, alt, pathlen) in frontier_nodes:
  *                             new_frontier.append((k, i, input_match + (i,), alt, pathlen, xnode, phrase +(xcat,), is_shadow_path))             # <<<<<<<<<<<<<<
  *             frontier = new_frontier
  * 
  */
-            __pyx_t_10 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_k); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_10 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_k); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_10);
-            __pyx_t_3 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_3 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_3);
-            __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_11);
-            __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_9);
             PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_11);
             __Pyx_GIVEREF(__pyx_t_11);
             __pyx_t_11 = 0;
-            __pyx_t_11 = PyNumber_Add(__pyx_cur_scope->__pyx_v_input_match, ((PyObject *)__pyx_t_9)); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_11 = PyNumber_Add(__pyx_cur_scope->__pyx_v_input_match, ((PyObject *)__pyx_t_9)); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_11);
             __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
-            __pyx_t_9 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_alt); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_9 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_alt); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_9);
-            __pyx_t_1 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_xcat); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_1 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_xcat); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_1);
-            __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_7);
             PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_1);
             __Pyx_GIVEREF(__pyx_t_1);
             __pyx_t_1 = 0;
-            __pyx_t_1 = PyNumber_Add(__pyx_cur_scope->__pyx_v_phrase, ((PyObject *)__pyx_t_7)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_1 = PyNumber_Add(__pyx_cur_scope->__pyx_v_phrase, ((PyObject *)__pyx_t_7)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_1);
             __Pyx_DECREF(((PyObject *)__pyx_t_7)); __pyx_t_7 = 0;
-            __pyx_t_7 = PyTuple_New(8); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_7 = PyTuple_New(8); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_7);
             PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_10);
             __Pyx_GIVEREF(__pyx_t_10);
@@ -50524,7 +50592,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
             __pyx_t_11 = 0;
             __pyx_t_9 = 0;
             __pyx_t_1 = 0;
-            __pyx_t_12 = PyList_Append(__pyx_cur_scope->__pyx_v_new_frontier, ((PyObject *)__pyx_t_7)); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_12 = PyList_Append(__pyx_cur_scope->__pyx_v_new_frontier, ((PyObject *)__pyx_t_7)); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_DECREF(((PyObject *)__pyx_t_7)); __pyx_t_7 = 0;
           }
           __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
@@ -50538,7 +50606,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
     }
     __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1176
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1178
  *                         for (i, alt, pathlen) in frontier_nodes:
  *                             new_frontier.append((k, i, input_match + (i,), alt, pathlen, xnode, phrase +(xcat,), is_shadow_path))
  *             frontier = new_frontier             # <<<<<<<<<<<<<<
@@ -50552,7 +50620,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
     __pyx_cur_scope->__pyx_v_frontier = __pyx_cur_scope->__pyx_v_new_frontier;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1179
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1181
  * 
  *         # Online rule extraction and scoring
  *         if self.online:             # <<<<<<<<<<<<<<
@@ -50561,42 +50629,42 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
  */
   if (__pyx_cur_scope->__pyx_v_self->online) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1180
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1182
  *         # Online rule extraction and scoring
  *         if self.online:
  *             f_syms = tuple(word[0][0] for word in fwords)             # <<<<<<<<<<<<<<
  *             for (f, lex_i, lex_j) in self.get_f_phrases(f_syms):
  *                 spanlen = (lex_j - lex_i) + 1
  */
-    __pyx_t_13 = __pyx_pf_3_sa_23HieroCachingRuleFactory_5input_2genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_13 = __pyx_pf_3_sa_23HieroCachingRuleFactory_5input_2genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_13);
-    __pyx_t_14 = PyTuple_New(1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_14 = PyTuple_New(1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_14);
     PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_t_13);
     __Pyx_GIVEREF(__pyx_t_13);
     __pyx_t_13 = 0;
-    __pyx_t_13 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_13 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_13);
     __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
     __Pyx_GIVEREF(__pyx_t_13);
     __pyx_cur_scope->__pyx_v_f_syms = ((PyObject*)__pyx_t_13);
     __pyx_t_13 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1181
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1183
  *         if self.online:
  *             f_syms = tuple(word[0][0] for word in fwords)
  *             for (f, lex_i, lex_j) in self.get_f_phrases(f_syms):             # <<<<<<<<<<<<<<
  *                 spanlen = (lex_j - lex_i) + 1
  *                 if not sym_isvar(f[0]):
  */
-    __pyx_t_13 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__get_f_phrases); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_13 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__get_f_phrases); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_13);
-    __pyx_t_14 = PyTuple_New(1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_14 = PyTuple_New(1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_14);
     __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_v_f_syms));
     PyTuple_SET_ITEM(__pyx_t_14, 0, ((PyObject *)__pyx_cur_scope->__pyx_v_f_syms));
     __Pyx_GIVEREF(((PyObject *)__pyx_cur_scope->__pyx_v_f_syms));
-    __pyx_t_7 = PyObject_Call(__pyx_t_13, ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyObject_Call(__pyx_t_13, ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_7);
     __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
@@ -50604,7 +50672,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       __pyx_t_14 = __pyx_t_7; __Pyx_INCREF(__pyx_t_14); __pyx_t_2 = 0;
       __pyx_t_21 = NULL;
     } else {
-      __pyx_t_2 = -1; __pyx_t_14 = PyObject_GetIter(__pyx_t_7); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = -1; __pyx_t_14 = PyObject_GetIter(__pyx_t_7); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_14);
       __pyx_t_21 = Py_TYPE(__pyx_t_14)->tp_iternext;
     }
@@ -50613,23 +50681,23 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       if (!__pyx_t_21 && PyList_CheckExact(__pyx_t_14)) {
         if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_14)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_7 = PyList_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_7); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PyList_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_7); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_7 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else if (!__pyx_t_21 && PyTuple_CheckExact(__pyx_t_14)) {
         if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_14)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_7); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_7); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_7 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else {
         __pyx_t_7 = __pyx_t_21(__pyx_t_14);
         if (unlikely(!__pyx_t_7)) {
           if (PyErr_Occurred()) {
             if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           }
           break;
         }
@@ -50645,7 +50713,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         if (unlikely(size != 3)) {
           if (size > 3) __Pyx_RaiseTooManyValuesError(3);
           else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-          {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         #if CYTHON_COMPILING_IN_CPYTHON
         if (likely(PyTuple_CheckExact(sequence))) {
@@ -50661,15 +50729,15 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         __Pyx_INCREF(__pyx_t_1);
         __Pyx_INCREF(__pyx_t_9);
         #else
-        __pyx_t_13 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __pyx_t_1 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __pyx_t_9 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_13 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_9 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
         __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       } else
       {
         Py_ssize_t index = -1;
-        __pyx_t_11 = PyObject_GetIter(__pyx_t_7); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_11 = PyObject_GetIter(__pyx_t_7); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_11);
         __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
         __pyx_t_18 = Py_TYPE(__pyx_t_11)->tp_iternext;
@@ -50679,7 +50747,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         __Pyx_GOTREF(__pyx_t_1);
         index = 2; __pyx_t_9 = __pyx_t_18(__pyx_t_11); if (unlikely(!__pyx_t_9)) goto __pyx_L75_unpacking_failed;
         __Pyx_GOTREF(__pyx_t_9);
-        if (__Pyx_IternextUnpackEndCheck(__pyx_t_18(__pyx_t_11), 3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (__Pyx_IternextUnpackEndCheck(__pyx_t_18(__pyx_t_11), 3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __pyx_t_18 = NULL;
         __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
         goto __pyx_L76_unpacking_done;
@@ -50687,7 +50755,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
         __pyx_t_18 = NULL;
         if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __pyx_L76_unpacking_done:;
       }
       __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_f);
@@ -50706,16 +50774,16 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       __pyx_cur_scope->__pyx_v_lex_j = __pyx_t_9;
       __pyx_t_9 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1182
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1184
  *             f_syms = tuple(word[0][0] for word in fwords)
  *             for (f, lex_i, lex_j) in self.get_f_phrases(f_syms):
  *                 spanlen = (lex_j - lex_i) + 1             # <<<<<<<<<<<<<<
  *                 if not sym_isvar(f[0]):
  *                     spanlen += 1
  */
-      __pyx_t_7 = PyNumber_Subtract(__pyx_cur_scope->__pyx_v_lex_j, __pyx_cur_scope->__pyx_v_lex_i); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyNumber_Subtract(__pyx_cur_scope->__pyx_v_lex_j, __pyx_cur_scope->__pyx_v_lex_i); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_7);
-      __pyx_t_9 = PyNumber_Add(__pyx_t_7, __pyx_int_1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_9 = PyNumber_Add(__pyx_t_7, __pyx_int_1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_9);
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_spanlen);
@@ -50724,28 +50792,28 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       __pyx_cur_scope->__pyx_v_spanlen = __pyx_t_9;
       __pyx_t_9 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1183
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1185
  *             for (f, lex_i, lex_j) in self.get_f_phrases(f_syms):
  *                 spanlen = (lex_j - lex_i) + 1
  *                 if not sym_isvar(f[0]):             # <<<<<<<<<<<<<<
  *                     spanlen += 1
  *                 if not sym_isvar(f[1]):
  */
-      __pyx_t_9 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_f, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_9 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_f, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_9);
-      __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_t_9); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_t_9); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
       __pyx_t_8 = (!__pyx_f_3_sa_sym_isvar(__pyx_t_6));
       if (__pyx_t_8) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1184
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1186
  *                 spanlen = (lex_j - lex_i) + 1
  *                 if not sym_isvar(f[0]):
  *                     spanlen += 1             # <<<<<<<<<<<<<<
  *                 if not sym_isvar(f[1]):
  *                     spanlen += 1
  */
-        __pyx_t_9 = PyNumber_InPlaceAdd(__pyx_cur_scope->__pyx_v_spanlen, __pyx_int_1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_9 = PyNumber_InPlaceAdd(__pyx_cur_scope->__pyx_v_spanlen, __pyx_int_1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_9);
         __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_spanlen);
         __Pyx_DECREF(__pyx_cur_scope->__pyx_v_spanlen);
@@ -50756,28 +50824,28 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       }
       __pyx_L77:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1185
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1187
  *                 if not sym_isvar(f[0]):
  *                     spanlen += 1
  *                 if not sym_isvar(f[1]):             # <<<<<<<<<<<<<<
  *                     spanlen += 1
  *                 for e in self.phrases_fe.get(f, ()):
  */
-      __pyx_t_9 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_f, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_9 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_f, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_9);
-      __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_t_9); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_t_9); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
       __pyx_t_8 = (!__pyx_f_3_sa_sym_isvar(__pyx_t_6));
       if (__pyx_t_8) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1186
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1188
  *                     spanlen += 1
  *                 if not sym_isvar(f[1]):
  *                     spanlen += 1             # <<<<<<<<<<<<<<
  *                 for e in self.phrases_fe.get(f, ()):
  *                     if (f, e) not in seen_phrases:
  */
-        __pyx_t_9 = PyNumber_InPlaceAdd(__pyx_cur_scope->__pyx_v_spanlen, __pyx_int_1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_9 = PyNumber_InPlaceAdd(__pyx_cur_scope->__pyx_v_spanlen, __pyx_int_1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_9);
         __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_spanlen);
         __Pyx_DECREF(__pyx_cur_scope->__pyx_v_spanlen);
@@ -50788,16 +50856,16 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       }
       __pyx_L78:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1187
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1189
  *                 if not sym_isvar(f[1]):
  *                     spanlen += 1
  *                 for e in self.phrases_fe.get(f, ()):             # <<<<<<<<<<<<<<
  *                     if (f, e) not in seen_phrases:
  *                         # Don't add multiple instances of the same phrase here
  */
-      __pyx_t_9 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_self->phrases_fe, __pyx_n_s__get); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_9 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_self->phrases_fe, __pyx_n_s__get); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_9);
-      __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_7);
       __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f);
       PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_cur_scope->__pyx_v_f);
@@ -50805,7 +50873,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
       __Pyx_INCREF(((PyObject *)__pyx_empty_tuple));
       PyTuple_SET_ITEM(__pyx_t_7, 1, ((PyObject *)__pyx_empty_tuple));
       __Pyx_GIVEREF(((PyObject *)__pyx_empty_tuple));
-      __pyx_t_1 = PyObject_Call(__pyx_t_9, ((PyObject *)__pyx_t_7), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_Call(__pyx_t_9, ((PyObject *)__pyx_t_7), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_7)); __pyx_t_7 = 0;
@@ -50813,7 +50881,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         __pyx_t_7 = __pyx_t_1; __Pyx_INCREF(__pyx_t_7); __pyx_t_23 = 0;
         __pyx_t_29 = NULL;
       } else {
-        __pyx_t_23 = -1; __pyx_t_7 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_23 = -1; __pyx_t_7 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_7);
         __pyx_t_29 = Py_TYPE(__pyx_t_7)->tp_iternext;
       }
@@ -50822,23 +50890,23 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         if (!__pyx_t_29 && PyList_CheckExact(__pyx_t_7)) {
           if (__pyx_t_23 >= PyList_GET_SIZE(__pyx_t_7)) break;
           #if CYTHON_COMPILING_IN_CPYTHON
-          __pyx_t_1 = PyList_GET_ITEM(__pyx_t_7, __pyx_t_23); __Pyx_INCREF(__pyx_t_1); __pyx_t_23++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_1 = PyList_GET_ITEM(__pyx_t_7, __pyx_t_23); __Pyx_INCREF(__pyx_t_1); __pyx_t_23++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           #else
-          __pyx_t_1 = PySequence_ITEM(__pyx_t_7, __pyx_t_23); __pyx_t_23++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_1 = PySequence_ITEM(__pyx_t_7, __pyx_t_23); __pyx_t_23++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           #endif
         } else if (!__pyx_t_29 && PyTuple_CheckExact(__pyx_t_7)) {
           if (__pyx_t_23 >= PyTuple_GET_SIZE(__pyx_t_7)) break;
           #if CYTHON_COMPILING_IN_CPYTHON
-          __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_7, __pyx_t_23); __Pyx_INCREF(__pyx_t_1); __pyx_t_23++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_7, __pyx_t_23); __Pyx_INCREF(__pyx_t_1); __pyx_t_23++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           #else
-          __pyx_t_1 = PySequence_ITEM(__pyx_t_7, __pyx_t_23); __pyx_t_23++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_1 = PySequence_ITEM(__pyx_t_7, __pyx_t_23); __pyx_t_23++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           #endif
         } else {
           __pyx_t_1 = __pyx_t_29(__pyx_t_7);
           if (unlikely(!__pyx_t_1)) {
             if (PyErr_Occurred()) {
               if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-              else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             }
             break;
           }
@@ -50850,14 +50918,14 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         __pyx_cur_scope->__pyx_v_e = __pyx_t_1;
         __pyx_t_1 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1188
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1190
  *                     spanlen += 1
  *                 for e in self.phrases_fe.get(f, ()):
  *                     if (f, e) not in seen_phrases:             # <<<<<<<<<<<<<<
  *                         # Don't add multiple instances of the same phrase here
  *                         seen_phrases.add((f, e))
  */
-        __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
         __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f);
         PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_cur_scope->__pyx_v_f);
@@ -50865,18 +50933,18 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
         __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e);
         PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_cur_scope->__pyx_v_e);
         __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_e);
-        __pyx_t_8 = (__Pyx_PySequence_Contains(((PyObject *)__pyx_t_1), ((PyObject *)__pyx_cur_scope->__pyx_v_seen_phrases), Py_NE)); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_8 = (__Pyx_PySequence_Contains(((PyObject *)__pyx_t_1), ((PyObject *)__pyx_cur_scope->__pyx_v_seen_phrases), Py_NE)); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
         if (__pyx_t_8) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1190
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1192
  *                     if (f, e) not in seen_phrases:
  *                         # Don't add multiple instances of the same phrase here
  *                         seen_phrases.add((f, e))             # <<<<<<<<<<<<<<
  *                         scores = self.scorer.score(FeatureContext(
  *                                 f, e, 0, 0, 0,
  */
-          __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_1);
           __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f);
           PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_cur_scope->__pyx_v_f);
@@ -50884,29 +50952,29 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e);
           PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_cur_scope->__pyx_v_e);
           __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_e);
-          __pyx_t_12 = PySet_Add(__pyx_cur_scope->__pyx_v_seen_phrases, ((PyObject *)__pyx_t_1)); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_12 = PySet_Add(__pyx_cur_scope->__pyx_v_seen_phrases, ((PyObject *)__pyx_t_1)); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1191
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1193
  *                         # Don't add multiple instances of the same phrase here
  *                         seen_phrases.add((f, e))
  *                         scores = self.scorer.score(FeatureContext(             # <<<<<<<<<<<<<<
  *                                 f, e, 0, 0, 0,
  *                                 spanlen, None, None,
  */
-          __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__FeatureContext); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__FeatureContext); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_1);
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1196
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1198
  *                                 fwords, self.fda, self.eda,
  *                                 meta,
  *                                 self.online_ctx_lookup(f, e)))             # <<<<<<<<<<<<<<
  *                         alignment = self.phrases_al[f][e]
  *                         yield Rule(self.category, f, e, scores, alignment)
  */
-          __pyx_t_9 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__online_ctx_lookup); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_9 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__online_ctx_lookup); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1198; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_9);
-          __pyx_t_13 = PyTuple_New(2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_13 = PyTuple_New(2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1198; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_13);
           __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f);
           PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_cur_scope->__pyx_v_f);
@@ -50914,11 +50982,11 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e);
           PyTuple_SET_ITEM(__pyx_t_13, 1, __pyx_cur_scope->__pyx_v_e);
           __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_e);
-          __pyx_t_11 = PyObject_Call(__pyx_t_9, ((PyObject *)__pyx_t_13), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyObject_Call(__pyx_t_9, ((PyObject *)__pyx_t_13), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1198; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
           __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
           __Pyx_DECREF(((PyObject *)__pyx_t_13)); __pyx_t_13 = 0;
-          __pyx_t_13 = PyTuple_New(13); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_13 = PyTuple_New(13); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_13);
           __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f);
           PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_cur_scope->__pyx_v_f);
@@ -50959,11 +51027,11 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           PyTuple_SET_ITEM(__pyx_t_13, 12, __pyx_t_11);
           __Pyx_GIVEREF(__pyx_t_11);
           __pyx_t_11 = 0;
-          __pyx_t_11 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_13), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_13), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
           __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
           __Pyx_DECREF(((PyObject *)__pyx_t_13)); __pyx_t_13 = 0;
-          __pyx_t_13 = ((PyObject *)((struct __pyx_vtabstruct_3_sa_Scorer *)__pyx_cur_scope->__pyx_v_self->scorer->__pyx_vtab)->score(__pyx_cur_scope->__pyx_v_self->scorer, __pyx_t_11)); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_13 = ((PyObject *)((struct __pyx_vtabstruct_3_sa_Scorer *)__pyx_cur_scope->__pyx_v_self->scorer->__pyx_vtab)->score(__pyx_cur_scope->__pyx_v_self->scorer, __pyx_t_11)); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_13);
           __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
           __Pyx_XGOTREF(((PyObject *)__pyx_cur_scope->__pyx_v_scores));
@@ -50972,16 +51040,16 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __pyx_cur_scope->__pyx_v_scores = ((struct __pyx_obj_3_sa_FeatureVector *)__pyx_t_13);
           __pyx_t_13 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1197
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1199
  *                                 meta,
  *                                 self.online_ctx_lookup(f, e)))
  *                         alignment = self.phrases_al[f][e]             # <<<<<<<<<<<<<<
  *                         yield Rule(self.category, f, e, scores, alignment)
  * 
  */
-          __pyx_t_13 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_self->phrases_al, __pyx_cur_scope->__pyx_v_f); if (!__pyx_t_13) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_13 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_self->phrases_al, __pyx_cur_scope->__pyx_v_f); if (!__pyx_t_13) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1199; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_13);
-          __pyx_t_11 = PyObject_GetItem(__pyx_t_13, __pyx_cur_scope->__pyx_v_e); if (!__pyx_t_11) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyObject_GetItem(__pyx_t_13, __pyx_cur_scope->__pyx_v_e); if (!__pyx_t_11) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1199; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
           __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
           __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_alignment);
@@ -50990,16 +51058,16 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __pyx_cur_scope->__pyx_v_alignment = __pyx_t_11;
           __pyx_t_11 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1198
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1200
  *                                 self.online_ctx_lookup(f, e)))
  *                         alignment = self.phrases_al[f][e]
  *                         yield Rule(self.category, f, e, scores, alignment)             # <<<<<<<<<<<<<<
  * 
  *         stop_time = monitor_cpu()
  */
-          __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->category); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1198; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->category); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
-          __pyx_t_13 = PyTuple_New(5); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1198; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_13 = PyTuple_New(5); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_13);
           PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_11);
           __Pyx_GIVEREF(__pyx_t_11);
@@ -51016,7 +51084,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           PyTuple_SET_ITEM(__pyx_t_13, 4, __pyx_cur_scope->__pyx_v_alignment);
           __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_alignment);
           __pyx_t_11 = 0;
-          __pyx_t_11 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Rule)), ((PyObject *)__pyx_t_13), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1198; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_11 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Rule)), ((PyObject *)__pyx_t_13), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_11);
           __Pyx_DECREF(((PyObject *)__pyx_t_13)); __pyx_t_13 = 0;
           __pyx_r = __pyx_t_11;
@@ -51045,7 +51113,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
           __pyx_t_21 = __pyx_cur_scope->__pyx_t_10;
           __pyx_t_23 = __pyx_cur_scope->__pyx_t_2;
           __pyx_t_29 = __pyx_cur_scope->__pyx_t_11;
-          if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1198; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           goto __pyx_L81;
         }
         __pyx_L81:;
@@ -51057,37 +51125,37 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
   }
   __pyx_L72:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1200
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1202
  *                         yield Rule(self.category, f, e, scores, alignment)
  * 
  *         stop_time = monitor_cpu()             # <<<<<<<<<<<<<<
  *         logger.info("Total time for rule lookup, extraction, and scoring = %f seconds", (stop_time - start_time))
  *         gc.collect()
  */
-  __pyx_t_14 = PyFloat_FromDouble(__pyx_f_3_sa_monitor_cpu()); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_14 = PyFloat_FromDouble(__pyx_f_3_sa_monitor_cpu()); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1202; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_14);
   __Pyx_GIVEREF(__pyx_t_14);
   __pyx_cur_scope->__pyx_v_stop_time = __pyx_t_14;
   __pyx_t_14 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1201
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1203
  * 
  *         stop_time = monitor_cpu()
  *         logger.info("Total time for rule lookup, extraction, and scoring = %f seconds", (stop_time - start_time))             # <<<<<<<<<<<<<<
  *         gc.collect()
  *         logger.info("    Extract time = %f seconds", self.extract_time)
  */
-  __pyx_t_14 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_14 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_14);
-  __pyx_t_7 = PyObject_GetAttr(__pyx_t_14, __pyx_n_s__info); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_7 = PyObject_GetAttr(__pyx_t_14, __pyx_n_s__info); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_7);
   __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
-  __pyx_t_14 = PyFloat_FromDouble(__pyx_cur_scope->__pyx_v_start_time); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_14 = PyFloat_FromDouble(__pyx_cur_scope->__pyx_v_start_time); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_14);
-  __pyx_t_11 = PyNumber_Subtract(__pyx_cur_scope->__pyx_v_stop_time, __pyx_t_14); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_11 = PyNumber_Subtract(__pyx_cur_scope->__pyx_v_stop_time, __pyx_t_14); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_11);
   __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
-  __pyx_t_14 = PyTuple_New(2); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_14 = PyTuple_New(2); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_14);
   __Pyx_INCREF(((PyObject *)__pyx_kp_s_124));
   PyTuple_SET_ITEM(__pyx_t_14, 0, ((PyObject *)__pyx_kp_s_124));
@@ -51095,44 +51163,44 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
   PyTuple_SET_ITEM(__pyx_t_14, 1, __pyx_t_11);
   __Pyx_GIVEREF(__pyx_t_11);
   __pyx_t_11 = 0;
-  __pyx_t_11 = PyObject_Call(__pyx_t_7, ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_11 = PyObject_Call(__pyx_t_7, ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_11);
   __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
   __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1202
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1204
  *         stop_time = monitor_cpu()
  *         logger.info("Total time for rule lookup, extraction, and scoring = %f seconds", (stop_time - start_time))
  *         gc.collect()             # <<<<<<<<<<<<<<
  *         logger.info("    Extract time = %f seconds", self.extract_time)
  * 
  */
-  __pyx_t_11 = __Pyx_GetName(__pyx_m, __pyx_n_s__gc); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1202; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_11 = __Pyx_GetName(__pyx_m, __pyx_n_s__gc); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_11);
-  __pyx_t_14 = PyObject_GetAttr(__pyx_t_11, __pyx_n_s__collect); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1202; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_14 = PyObject_GetAttr(__pyx_t_11, __pyx_n_s__collect); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_14);
   __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-  __pyx_t_11 = PyObject_Call(__pyx_t_14, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1202; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_11 = PyObject_Call(__pyx_t_14, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_11);
   __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
   __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1203
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1205
  *         logger.info("Total time for rule lookup, extraction, and scoring = %f seconds", (stop_time - start_time))
  *         gc.collect()
  *         logger.info("    Extract time = %f seconds", self.extract_time)             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_t_11 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_11 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_11);
-  __pyx_t_14 = PyObject_GetAttr(__pyx_t_11, __pyx_n_s__info); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_14 = PyObject_GetAttr(__pyx_t_11, __pyx_n_s__info); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_14);
   __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-  __pyx_t_11 = PyFloat_FromDouble(__pyx_cur_scope->__pyx_v_self->extract_time); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_11 = PyFloat_FromDouble(__pyx_cur_scope->__pyx_v_self->extract_time); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_11);
-  __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_7);
   __Pyx_INCREF(((PyObject *)__pyx_kp_s_125));
   PyTuple_SET_ITEM(__pyx_t_7, 0, ((PyObject *)__pyx_kp_s_125));
@@ -51140,7 +51208,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
   PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_11);
   __Pyx_GIVEREF(__pyx_t_11);
   __pyx_t_11 = 0;
-  __pyx_t_11 = PyObject_Call(__pyx_t_14, ((PyObject *)__pyx_t_7), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_11 = PyObject_Call(__pyx_t_14, ((PyObject *)__pyx_t_7), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_11);
   __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_7)); __pyx_t_7 = 0;
@@ -51168,7 +51236,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_24generator4(__pyx_Gene
   return NULL;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1206
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1208
  * 
  * 
  *     cdef int find_fixpoint(self,             # <<<<<<<<<<<<<<
@@ -51198,7 +51266,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("find_fixpoint", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1221
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1223
  *         cdef int e_low_prev, e_high_prev, f_low_prev, f_high_prev, new_x, new_low_x, new_high_x
  * 
  *         e_low[0] = e_in_low             # <<<<<<<<<<<<<<
@@ -51207,7 +51275,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
   (__pyx_v_e_low[0]) = __pyx_v_e_in_low;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1222
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1224
  * 
  *         e_low[0] = e_in_low
  *         e_high[0] = e_in_high             # <<<<<<<<<<<<<<
@@ -51216,19 +51284,19 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
   (__pyx_v_e_high[0]) = __pyx_v_e_in_high;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1223
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1225
  *         e_low[0] = e_in_low
  *         e_high[0] = e_in_high
  *         self.find_projection(f_low, f_high, f_links_low, f_links_high, e_low, e_high)             # <<<<<<<<<<<<<<
  *         if e_low[0] == -1:
  *             # low-priority corner case: if phrase w is unaligned,
  */
-  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_f_high); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1223; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_2 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->find_projection(__pyx_v_self, __pyx_v_f_low, __pyx_t_1, __pyx_v_f_links_low, __pyx_v_f_links_high, __pyx_v_e_low, __pyx_v_e_high); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1223; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_f_high); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->find_projection(__pyx_v_self, __pyx_v_f_low, __pyx_t_1, __pyx_v_f_links_low, __pyx_v_f_links_high, __pyx_v_e_low, __pyx_v_e_high); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1224
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1226
  *         e_high[0] = e_in_high
  *         self.find_projection(f_low, f_high, f_links_low, f_links_high, e_low, e_high)
  *         if e_low[0] == -1:             # <<<<<<<<<<<<<<
@@ -51238,7 +51306,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
   __pyx_t_3 = ((__pyx_v_e_low[0]) == -1);
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1230
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1232
  *             # rule X -> X_1 w X_2 / X_1 X_2.    This is probably
  *             # not worth the bother, though.
  *             return 0             # <<<<<<<<<<<<<<
@@ -51250,7 +51318,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     goto __pyx_L3;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1231
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1233
  *             # not worth the bother, though.
  *             return 0
  *         elif e_in_low != -1 and e_low[0] != e_in_low:             # <<<<<<<<<<<<<<
@@ -51266,7 +51334,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
   }
   if (__pyx_t_5) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1232
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1234
  *             return 0
  *         elif e_in_low != -1 and e_low[0] != e_in_low:
  *             if e_in_low - e_low[0] < min_ex_size:             # <<<<<<<<<<<<<<
@@ -51276,7 +51344,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     __pyx_t_5 = ((__pyx_v_e_in_low - (__pyx_v_e_low[0])) < __pyx_v_min_ex_size);
     if (__pyx_t_5) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1233
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1235
  *         elif e_in_low != -1 and e_low[0] != e_in_low:
  *             if e_in_low - e_low[0] < min_ex_size:
  *                 e_low[0] = e_in_low - min_ex_size             # <<<<<<<<<<<<<<
@@ -51285,7 +51353,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
       (__pyx_v_e_low[0]) = (__pyx_v_e_in_low - __pyx_v_min_ex_size);
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1234
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1236
  *             if e_in_low - e_low[0] < min_ex_size:
  *                 e_low[0] = e_in_low - min_ex_size
  *                 if e_low[0] < 0:             # <<<<<<<<<<<<<<
@@ -51295,7 +51363,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
       __pyx_t_5 = ((__pyx_v_e_low[0]) < 0);
       if (__pyx_t_5) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1235
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1237
  *                 e_low[0] = e_in_low - min_ex_size
  *                 if e_low[0] < 0:
  *                     return 0             # <<<<<<<<<<<<<<
@@ -51314,7 +51382,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1237
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1239
  *                     return 0
  * 
  *         if e_high[0] - e_low[0] > max_e_len:             # <<<<<<<<<<<<<<
@@ -51324,7 +51392,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
   __pyx_t_5 = (((__pyx_v_e_high[0]) - (__pyx_v_e_low[0])) > __pyx_v_max_e_len);
   if (__pyx_t_5) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1238
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1240
  * 
  *         if e_high[0] - e_low[0] > max_e_len:
  *             return 0             # <<<<<<<<<<<<<<
@@ -51336,7 +51404,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     goto __pyx_L6;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1239
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1241
  *         if e_high[0] - e_low[0] > max_e_len:
  *             return 0
  *         elif e_in_high != -1 and e_high[0] != e_in_high:             # <<<<<<<<<<<<<<
@@ -51352,7 +51420,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
   }
   if (__pyx_t_4) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1240
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1242
  *             return 0
  *         elif e_in_high != -1 and e_high[0] != e_in_high:
  *             if e_high[0] - e_in_high < min_ex_size:             # <<<<<<<<<<<<<<
@@ -51362,7 +51430,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     __pyx_t_4 = (((__pyx_v_e_high[0]) - __pyx_v_e_in_high) < __pyx_v_min_ex_size);
     if (__pyx_t_4) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1241
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1243
  *         elif e_in_high != -1 and e_high[0] != e_in_high:
  *             if e_high[0] - e_in_high < min_ex_size:
  *                 e_high[0] = e_in_high + min_ex_size             # <<<<<<<<<<<<<<
@@ -51371,7 +51439,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
       (__pyx_v_e_high[0]) = (__pyx_v_e_in_high + __pyx_v_min_ex_size);
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1242
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1244
  *             if e_high[0] - e_in_high < min_ex_size:
  *                 e_high[0] = e_in_high + min_ex_size
  *                 if e_high[0] > e_sent_len:             # <<<<<<<<<<<<<<
@@ -51381,7 +51449,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
       __pyx_t_4 = ((__pyx_v_e_high[0]) > __pyx_v_e_sent_len);
       if (__pyx_t_4) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1243
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1245
  *                 e_high[0] = e_in_high + min_ex_size
  *                 if e_high[0] > e_sent_len:
  *                     return 0             # <<<<<<<<<<<<<<
@@ -51400,7 +51468,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
   }
   __pyx_L6:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1245
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1247
  *                     return 0
  * 
  *         f_back_low[0] = -1             # <<<<<<<<<<<<<<
@@ -51409,7 +51477,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
   (__pyx_v_f_back_low[0]) = -1;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1246
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1248
  * 
  *         f_back_low[0] = -1
  *         f_back_high[0] = -1             # <<<<<<<<<<<<<<
@@ -51418,7 +51486,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
   (__pyx_v_f_back_high[0]) = -1;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1247
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1249
  *         f_back_low[0] = -1
  *         f_back_high[0] = -1
  *         f_low_prev = f_low             # <<<<<<<<<<<<<<
@@ -51427,17 +51495,17 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
   __pyx_v_f_low_prev = __pyx_v_f_low;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1248
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1250
  *         f_back_high[0] = -1
  *         f_low_prev = f_low
  *         f_high_prev = f_high             # <<<<<<<<<<<<<<
  *         new_x = 0
  *         new_low_x = 0
  */
-  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_f_high); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1248; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_f_high); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1250; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_v_f_high_prev = __pyx_t_1;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1249
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1251
  *         f_low_prev = f_low
  *         f_high_prev = f_high
  *         new_x = 0             # <<<<<<<<<<<<<<
@@ -51446,7 +51514,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
   __pyx_v_new_x = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1250
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1252
  *         f_high_prev = f_high
  *         new_x = 0
  *         new_low_x = 0             # <<<<<<<<<<<<<<
@@ -51455,7 +51523,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
   __pyx_v_new_low_x = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1251
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1253
  *         new_x = 0
  *         new_low_x = 0
  *         new_high_x = 0             # <<<<<<<<<<<<<<
@@ -51464,7 +51532,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
   __pyx_v_new_high_x = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1253
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1255
  *         new_high_x = 0
  * 
  *         while True:             # <<<<<<<<<<<<<<
@@ -51474,7 +51542,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
   while (1) {
     if (!1) break;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1255
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1257
  *         while True:
  * 
  *             if f_back_low[0] == -1:             # <<<<<<<<<<<<<<
@@ -51484,45 +51552,45 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     __pyx_t_4 = ((__pyx_v_f_back_low[0]) == -1);
     if (__pyx_t_4) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1256
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1258
  * 
  *             if f_back_low[0] == -1:
  *                 self.find_projection(e_low[0], e_high[0], e_links_low, e_links_high, f_back_low, f_back_high)             # <<<<<<<<<<<<<<
  *             else:
  *                 self.find_projection(e_low[0], e_low_prev, e_links_low, e_links_high, f_back_low, f_back_high)
  */
-      __pyx_t_2 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->find_projection(__pyx_v_self, (__pyx_v_e_low[0]), (__pyx_v_e_high[0]), __pyx_v_e_links_low, __pyx_v_e_links_high, __pyx_v_f_back_low, __pyx_v_f_back_high); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->find_projection(__pyx_v_self, (__pyx_v_e_low[0]), (__pyx_v_e_high[0]), __pyx_v_e_links_low, __pyx_v_e_links_high, __pyx_v_f_back_low, __pyx_v_f_back_high); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       goto __pyx_L11;
     }
     /*else*/ {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1258
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1260
  *                 self.find_projection(e_low[0], e_high[0], e_links_low, e_links_high, f_back_low, f_back_high)
  *             else:
  *                 self.find_projection(e_low[0], e_low_prev, e_links_low, e_links_high, f_back_low, f_back_high)             # <<<<<<<<<<<<<<
  *                 self.find_projection(e_high_prev, e_high[0], e_links_low, e_links_high, f_back_low, f_back_high)
  * 
  */
-      __pyx_t_2 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->find_projection(__pyx_v_self, (__pyx_v_e_low[0]), __pyx_v_e_low_prev, __pyx_v_e_links_low, __pyx_v_e_links_high, __pyx_v_f_back_low, __pyx_v_f_back_high); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->find_projection(__pyx_v_self, (__pyx_v_e_low[0]), __pyx_v_e_low_prev, __pyx_v_e_links_low, __pyx_v_e_links_high, __pyx_v_f_back_low, __pyx_v_f_back_high); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1259
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1261
  *             else:
  *                 self.find_projection(e_low[0], e_low_prev, e_links_low, e_links_high, f_back_low, f_back_high)
  *                 self.find_projection(e_high_prev, e_high[0], e_links_low, e_links_high, f_back_low, f_back_high)             # <<<<<<<<<<<<<<
  * 
  *             if f_back_low[0] > f_low:
  */
-      __pyx_t_2 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->find_projection(__pyx_v_self, __pyx_v_e_high_prev, (__pyx_v_e_high[0]), __pyx_v_e_links_low, __pyx_v_e_links_high, __pyx_v_f_back_low, __pyx_v_f_back_high); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->find_projection(__pyx_v_self, __pyx_v_e_high_prev, (__pyx_v_e_high[0]), __pyx_v_e_links_low, __pyx_v_e_links_high, __pyx_v_f_back_low, __pyx_v_f_back_high); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     }
     __pyx_L11:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1261
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1263
  *                 self.find_projection(e_high_prev, e_high[0], e_links_low, e_links_high, f_back_low, f_back_high)
  * 
  *             if f_back_low[0] > f_low:             # <<<<<<<<<<<<<<
@@ -51532,7 +51600,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     __pyx_t_4 = ((__pyx_v_f_back_low[0]) > __pyx_v_f_low);
     if (__pyx_t_4) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1262
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1264
  * 
  *             if f_back_low[0] > f_low:
  *                 f_back_low[0] = f_low             # <<<<<<<<<<<<<<
@@ -51544,35 +51612,35 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     }
     __pyx_L12:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1264
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1266
  *                 f_back_low[0] = f_low
  * 
  *             if f_back_high[0] < f_high:             # <<<<<<<<<<<<<<
  *                 f_back_high[0] = f_high
  * 
  */
-    __pyx_t_2 = PyInt_FromLong((__pyx_v_f_back_high[0])); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyInt_FromLong((__pyx_v_f_back_high[0])); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1266; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_6 = PyObject_RichCompare(__pyx_t_2, __pyx_v_f_high, Py_LT); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyObject_RichCompare(__pyx_t_2, __pyx_v_f_high, Py_LT); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1266; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1266; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     if (__pyx_t_4) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1265
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1267
  * 
  *             if f_back_high[0] < f_high:
  *                 f_back_high[0] = f_high             # <<<<<<<<<<<<<<
  * 
  *             if f_back_low[0] == f_low_prev and f_back_high[0] == f_high_prev:
  */
-      __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_f_high); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1265; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_v_f_high); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       (__pyx_v_f_back_high[0]) = __pyx_t_1;
       goto __pyx_L13;
     }
     __pyx_L13:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1267
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1269
  *                 f_back_high[0] = f_high
  * 
  *             if f_back_low[0] == f_low_prev and f_back_high[0] == f_high_prev:             # <<<<<<<<<<<<<<
@@ -51588,7 +51656,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     }
     if (__pyx_t_3) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1268
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1270
  * 
  *             if f_back_low[0] == f_low_prev and f_back_high[0] == f_high_prev:
  *                 return 1             # <<<<<<<<<<<<<<
@@ -51601,7 +51669,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     }
     __pyx_L14:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1270
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1272
  *                 return 1
  * 
  *             if allow_low_x == 0 and f_back_low[0] < f_low:             # <<<<<<<<<<<<<<
@@ -51617,7 +51685,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     }
     if (__pyx_t_5) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1272
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1274
  *             if allow_low_x == 0 and f_back_low[0] < f_low:
  *                 # FAIL: f phrase is not tight
  *                 return 0             # <<<<<<<<<<<<<<
@@ -51630,7 +51698,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     }
     __pyx_L15:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1274
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1276
  *                 return 0
  * 
  *             if f_back_high[0] - f_back_low[0] > max_f_len:             # <<<<<<<<<<<<<<
@@ -51640,7 +51708,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     __pyx_t_5 = (((__pyx_v_f_back_high[0]) - (__pyx_v_f_back_low[0])) > __pyx_v_max_f_len);
     if (__pyx_t_5) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1276
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1278
  *             if f_back_high[0] - f_back_low[0] > max_f_len:
  *                 # FAIL: f back projection is too wide
  *                 return 0             # <<<<<<<<<<<<<<
@@ -51653,7 +51721,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     }
     __pyx_L16:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1278
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1280
  *                 return 0
  * 
  *             if allow_high_x == 0 and f_back_high[0] > f_high:             # <<<<<<<<<<<<<<
@@ -51662,11 +51730,11 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
     __pyx_t_5 = (__pyx_v_allow_high_x == 0);
     if (__pyx_t_5) {
-      __pyx_t_6 = PyInt_FromLong((__pyx_v_f_back_high[0])); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PyInt_FromLong((__pyx_v_f_back_high[0])); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1280; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_6);
-      __pyx_t_2 = PyObject_RichCompare(__pyx_t_6, __pyx_v_f_high, Py_GT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_RichCompare(__pyx_t_6, __pyx_v_f_high, Py_GT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1280; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-      __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1280; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __pyx_t_4 = __pyx_t_3;
     } else {
@@ -51674,7 +51742,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     }
     if (__pyx_t_4) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1280
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1282
  *             if allow_high_x == 0 and f_back_high[0] > f_high:
  *                 # FAIL: extension on high side not allowed
  *                 return 0             # <<<<<<<<<<<<<<
@@ -51687,7 +51755,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     }
     __pyx_L17:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1282
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1284
  *                 return 0
  * 
  *             if f_low != f_back_low[0]:             # <<<<<<<<<<<<<<
@@ -51697,7 +51765,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     __pyx_t_4 = (__pyx_v_f_low != (__pyx_v_f_back_low[0]));
     if (__pyx_t_4) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1283
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1285
  * 
  *             if f_low != f_back_low[0]:
  *                 if new_low_x == 0:             # <<<<<<<<<<<<<<
@@ -51707,7 +51775,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
       __pyx_t_4 = (__pyx_v_new_low_x == 0);
       if (__pyx_t_4) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1284
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1286
  *             if f_low != f_back_low[0]:
  *                 if new_low_x == 0:
  *                     if new_x >= max_new_x:             # <<<<<<<<<<<<<<
@@ -51717,7 +51785,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
         __pyx_t_4 = (__pyx_v_new_x >= __pyx_v_max_new_x);
         if (__pyx_t_4) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1286
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1288
  *                     if new_x >= max_new_x:
  *                         # FAIL: extension required on low side violates max # of gaps
  *                         return 0             # <<<<<<<<<<<<<<
@@ -51730,7 +51798,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
         }
         /*else*/ {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1288
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1290
  *                         return 0
  *                     else:
  *                         new_x = new_x + 1             # <<<<<<<<<<<<<<
@@ -51739,7 +51807,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
           __pyx_v_new_x = (__pyx_v_new_x + 1);
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1289
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1291
  *                     else:
  *                         new_x = new_x + 1
  *                         new_low_x = 1             # <<<<<<<<<<<<<<
@@ -51753,7 +51821,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
       }
       __pyx_L19:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1290
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1292
  *                         new_x = new_x + 1
  *                         new_low_x = 1
  *                 if f_low - f_back_low[0] < min_fx_size:             # <<<<<<<<<<<<<<
@@ -51763,7 +51831,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
       __pyx_t_4 = ((__pyx_v_f_low - (__pyx_v_f_back_low[0])) < __pyx_v_min_fx_size);
       if (__pyx_t_4) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1291
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1293
  *                         new_low_x = 1
  *                 if f_low - f_back_low[0] < min_fx_size:
  *                     f_back_low[0] = f_low - min_fx_size             # <<<<<<<<<<<<<<
@@ -51772,7 +51840,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
         (__pyx_v_f_back_low[0]) = (__pyx_v_f_low - __pyx_v_min_fx_size);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1292
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1294
  *                 if f_low - f_back_low[0] < min_fx_size:
  *                     f_back_low[0] = f_low - min_fx_size
  *                     if f_back_high[0] - f_back_low[0] > max_f_len:             # <<<<<<<<<<<<<<
@@ -51782,7 +51850,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
         __pyx_t_4 = (((__pyx_v_f_back_high[0]) - (__pyx_v_f_back_low[0])) > __pyx_v_max_f_len);
         if (__pyx_t_4) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1294
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1296
  *                     if f_back_high[0] - f_back_low[0] > max_f_len:
  *                         # FAIL: extension required on low side violates max initial length
  *                         return 0             # <<<<<<<<<<<<<<
@@ -51795,7 +51863,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
         }
         __pyx_L22:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1295
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1297
  *                         # FAIL: extension required on low side violates max initial length
  *                         return 0
  *                     if f_back_low[0] < 0:             # <<<<<<<<<<<<<<
@@ -51805,7 +51873,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
         __pyx_t_4 = ((__pyx_v_f_back_low[0]) < 0);
         if (__pyx_t_4) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1297
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1299
  *                     if f_back_low[0] < 0:
  *                         # FAIL: extension required on low side violates sentence boundary
  *                         return 0             # <<<<<<<<<<<<<<
@@ -51824,22 +51892,22 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     }
     __pyx_L18:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1299
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1301
  *                         return 0
  * 
  *             if f_high != f_back_high[0]:             # <<<<<<<<<<<<<<
  *                 if new_high_x == 0:
  *                     if new_x >= max_new_x:
  */
-    __pyx_t_2 = PyInt_FromLong((__pyx_v_f_back_high[0])); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyInt_FromLong((__pyx_v_f_back_high[0])); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1301; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_6 = PyObject_RichCompare(__pyx_v_f_high, __pyx_t_2, Py_NE); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyObject_RichCompare(__pyx_v_f_high, __pyx_t_2, Py_NE); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1301; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1301; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     if (__pyx_t_4) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1300
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1302
  * 
  *             if f_high != f_back_high[0]:
  *                 if new_high_x == 0:             # <<<<<<<<<<<<<<
@@ -51849,7 +51917,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
       __pyx_t_4 = (__pyx_v_new_high_x == 0);
       if (__pyx_t_4) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1301
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1303
  *             if f_high != f_back_high[0]:
  *                 if new_high_x == 0:
  *                     if new_x >= max_new_x:             # <<<<<<<<<<<<<<
@@ -51859,7 +51927,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
         __pyx_t_4 = (__pyx_v_new_x >= __pyx_v_max_new_x);
         if (__pyx_t_4) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1303
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1305
  *                     if new_x >= max_new_x:
  *                         # FAIL: extension required on high side violates max # of gaps
  *                         return 0             # <<<<<<<<<<<<<<
@@ -51872,7 +51940,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
         }
         /*else*/ {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1305
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1307
  *                         return 0
  *                     else:
  *                         new_x = new_x + 1             # <<<<<<<<<<<<<<
@@ -51881,7 +51949,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
           __pyx_v_new_x = (__pyx_v_new_x + 1);
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1306
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1308
  *                     else:
  *                         new_x = new_x + 1
  *                         new_high_x = 1             # <<<<<<<<<<<<<<
@@ -51895,44 +51963,44 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
       }
       __pyx_L25:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1307
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1309
  *                         new_x = new_x + 1
  *                         new_high_x = 1
  *                 if f_back_high[0] - f_high < min_fx_size:             # <<<<<<<<<<<<<<
  *                     f_back_high[0] = f_high + min_fx_size
  *                     if f_back_high[0] - f_back_low[0] > max_f_len:
  */
-      __pyx_t_6 = PyInt_FromLong((__pyx_v_f_back_high[0])); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PyInt_FromLong((__pyx_v_f_back_high[0])); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1309; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_6);
-      __pyx_t_2 = PyNumber_Subtract(__pyx_t_6, __pyx_v_f_high); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_Subtract(__pyx_t_6, __pyx_v_f_high); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1309; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-      __pyx_t_6 = PyInt_FromLong(__pyx_v_min_fx_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PyInt_FromLong(__pyx_v_min_fx_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1309; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_6);
-      __pyx_t_7 = PyObject_RichCompare(__pyx_t_2, __pyx_t_6, Py_LT); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyObject_RichCompare(__pyx_t_2, __pyx_t_6, Py_LT); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1309; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-      __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1309; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       if (__pyx_t_4) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1308
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1310
  *                         new_high_x = 1
  *                 if f_back_high[0] - f_high < min_fx_size:
  *                     f_back_high[0] = f_high + min_fx_size             # <<<<<<<<<<<<<<
  *                     if f_back_high[0] - f_back_low[0] > max_f_len:
  *                         # FAIL: extension required on high side violates max initial length
  */
-        __pyx_t_7 = PyInt_FromLong(__pyx_v_min_fx_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PyInt_FromLong(__pyx_v_min_fx_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1310; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_7);
-        __pyx_t_6 = PyNumber_Add(__pyx_v_f_high, __pyx_t_7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_6 = PyNumber_Add(__pyx_v_f_high, __pyx_t_7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1310; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_6);
         __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-        __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_t_6); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = __Pyx_PyInt_AsInt(__pyx_t_6); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1310; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
         (__pyx_v_f_back_high[0]) = __pyx_t_1;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1309
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1311
  *                 if f_back_high[0] - f_high < min_fx_size:
  *                     f_back_high[0] = f_high + min_fx_size
  *                     if f_back_high[0] - f_back_low[0] > max_f_len:             # <<<<<<<<<<<<<<
@@ -51942,7 +52010,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
         __pyx_t_4 = (((__pyx_v_f_back_high[0]) - (__pyx_v_f_back_low[0])) > __pyx_v_max_f_len);
         if (__pyx_t_4) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1311
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1313
  *                     if f_back_high[0] - f_back_low[0] > max_f_len:
  *                         # FAIL: extension required on high side violates max initial length
  *                         return 0             # <<<<<<<<<<<<<<
@@ -51955,7 +52023,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
         }
         __pyx_L28:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1312
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1314
  *                         # FAIL: extension required on high side violates max initial length
  *                         return 0
  *                     if f_back_high[0] > f_sent_len:             # <<<<<<<<<<<<<<
@@ -51965,7 +52033,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
         __pyx_t_4 = ((__pyx_v_f_back_high[0]) > __pyx_v_f_sent_len);
         if (__pyx_t_4) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1314
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1316
  *                     if f_back_high[0] > f_sent_len:
  *                         # FAIL: extension required on high side violates sentence boundary
  *                         return 0             # <<<<<<<<<<<<<<
@@ -51984,7 +52052,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     }
     __pyx_L24:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1316
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1318
  *                         return 0
  * 
  *             e_low_prev = e_low[0]             # <<<<<<<<<<<<<<
@@ -51993,7 +52061,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
     __pyx_v_e_low_prev = (__pyx_v_e_low[0]);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1317
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1319
  * 
  *             e_low_prev = e_low[0]
  *             e_high_prev = e_high[0]             # <<<<<<<<<<<<<<
@@ -52002,29 +52070,29 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
     __pyx_v_e_high_prev = (__pyx_v_e_high[0]);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1319
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1321
  *             e_high_prev = e_high[0]
  * 
  *             self.find_projection(f_back_low[0], f_low_prev, f_links_low, f_links_high, e_low, e_high)             # <<<<<<<<<<<<<<
  *             self.find_projection(f_high_prev, f_back_high[0], f_links_low, f_links_high, e_low, e_high)
  *             if e_low[0] == e_low_prev and e_high[0] == e_high_prev:
  */
-    __pyx_t_6 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->find_projection(__pyx_v_self, (__pyx_v_f_back_low[0]), __pyx_v_f_low_prev, __pyx_v_f_links_low, __pyx_v_f_links_high, __pyx_v_e_low, __pyx_v_e_high); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1319; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->find_projection(__pyx_v_self, (__pyx_v_f_back_low[0]), __pyx_v_f_low_prev, __pyx_v_f_links_low, __pyx_v_f_links_high, __pyx_v_e_low, __pyx_v_e_high); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1320
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1322
  * 
  *             self.find_projection(f_back_low[0], f_low_prev, f_links_low, f_links_high, e_low, e_high)
  *             self.find_projection(f_high_prev, f_back_high[0], f_links_low, f_links_high, e_low, e_high)             # <<<<<<<<<<<<<<
  *             if e_low[0] == e_low_prev and e_high[0] == e_high_prev:
  *                 return 1
  */
-    __pyx_t_6 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->find_projection(__pyx_v_self, __pyx_v_f_high_prev, (__pyx_v_f_back_high[0]), __pyx_v_f_links_low, __pyx_v_f_links_high, __pyx_v_e_low, __pyx_v_e_high); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1320; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->find_projection(__pyx_v_self, __pyx_v_f_high_prev, (__pyx_v_f_back_high[0]), __pyx_v_f_links_low, __pyx_v_f_links_high, __pyx_v_e_low, __pyx_v_e_high); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1322; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1321
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1323
  *             self.find_projection(f_back_low[0], f_low_prev, f_links_low, f_links_high, e_low, e_high)
  *             self.find_projection(f_high_prev, f_back_high[0], f_links_low, f_links_high, e_low, e_high)
  *             if e_low[0] == e_low_prev and e_high[0] == e_high_prev:             # <<<<<<<<<<<<<<
@@ -52040,7 +52108,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     }
     if (__pyx_t_3) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1322
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1324
  *             self.find_projection(f_high_prev, f_back_high[0], f_links_low, f_links_high, e_low, e_high)
  *             if e_low[0] == e_low_prev and e_high[0] == e_high_prev:
  *                 return 1             # <<<<<<<<<<<<<<
@@ -52053,7 +52121,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     }
     __pyx_L30:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1323
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1325
  *             if e_low[0] == e_low_prev and e_high[0] == e_high_prev:
  *                 return 1
  *             if allow_arbitrary_x == 0:             # <<<<<<<<<<<<<<
@@ -52063,7 +52131,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     __pyx_t_3 = (__pyx_v_allow_arbitrary_x == 0);
     if (__pyx_t_3) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1325
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1327
  *             if allow_arbitrary_x == 0:
  *                 # FAIL: arbitrary expansion not permitted
  *                 return 0             # <<<<<<<<<<<<<<
@@ -52076,7 +52144,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     }
     __pyx_L31:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1326
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1328
  *                 # FAIL: arbitrary expansion not permitted
  *                 return 0
  *             if e_high[0] - e_low[0] > max_e_len:             # <<<<<<<<<<<<<<
@@ -52086,7 +52154,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     __pyx_t_3 = (((__pyx_v_e_high[0]) - (__pyx_v_e_low[0])) > __pyx_v_max_e_len);
     if (__pyx_t_3) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1328
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1330
  *             if e_high[0] - e_low[0] > max_e_len:
  *                 # FAIL: re-projection violates sentence max phrase length
  *                 return 0             # <<<<<<<<<<<<<<
@@ -52099,7 +52167,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
     }
     __pyx_L32:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1329
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1331
  *                 # FAIL: re-projection violates sentence max phrase length
  *                 return 0
  *             f_low_prev = f_back_low[0]             # <<<<<<<<<<<<<<
@@ -52108,7 +52176,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
  */
     __pyx_v_f_low_prev = (__pyx_v_f_back_low[0]);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1330
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1332
  *                 return 0
  *             f_low_prev = f_back_low[0]
  *             f_high_prev = f_back_high[0]             # <<<<<<<<<<<<<<
@@ -52131,7 +52199,7 @@ static int __pyx_f_3_sa_23HieroCachingRuleFactory_find_fixpoint(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1333
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1335
  * 
  * 
  *     cdef find_projection(self, int in_low, int in_high, int* in_links_low, int* in_links_high,             # <<<<<<<<<<<<<<
@@ -52149,7 +52217,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_find_projection(CYTHON_U
   int __pyx_t_4;
   __Pyx_RefNannySetupContext("find_projection", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1336
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1338
  *                         int* out_low, int* out_high):
  *         cdef int i
  *         for i from in_low <= i < in_high:             # <<<<<<<<<<<<<<
@@ -52159,7 +52227,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_find_projection(CYTHON_U
   __pyx_t_1 = __pyx_v_in_high;
   for (__pyx_v_i = __pyx_v_in_low; __pyx_v_i < __pyx_t_1; __pyx_v_i++) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1337
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1339
  *         cdef int i
  *         for i from in_low <= i < in_high:
  *             if in_links_low[i] != -1:             # <<<<<<<<<<<<<<
@@ -52169,7 +52237,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_find_projection(CYTHON_U
     __pyx_t_2 = ((__pyx_v_in_links_low[__pyx_v_i]) != -1);
     if (__pyx_t_2) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1338
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1340
  *         for i from in_low <= i < in_high:
  *             if in_links_low[i] != -1:
  *                 if out_low[0] == -1 or in_links_low[i] < out_low[0]:             # <<<<<<<<<<<<<<
@@ -52185,7 +52253,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_find_projection(CYTHON_U
       }
       if (__pyx_t_4) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1339
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1341
  *             if in_links_low[i] != -1:
  *                 if out_low[0] == -1 or in_links_low[i] < out_low[0]:
  *                     out_low[0] = in_links_low[i]             # <<<<<<<<<<<<<<
@@ -52197,7 +52265,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_find_projection(CYTHON_U
       }
       __pyx_L6:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1340
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1342
  *                 if out_low[0] == -1 or in_links_low[i] < out_low[0]:
  *                     out_low[0] = in_links_low[i]
  *                 if out_high[0] == -1 or in_links_high[i] > out_high[0]:             # <<<<<<<<<<<<<<
@@ -52213,7 +52281,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_find_projection(CYTHON_U
       }
       if (__pyx_t_3) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1341
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1343
  *                     out_low[0] = in_links_low[i]
  *                 if out_high[0] == -1 or in_links_high[i] > out_high[0]:
  *                     out_high[0] = in_links_high[i]             # <<<<<<<<<<<<<<
@@ -52235,7 +52303,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_find_projection(CYTHON_U
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1344
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1346
  * 
  * 
  *     cdef int* int_arr_extend(self, int* arr, int* arr_len, int* data, int data_len):             # <<<<<<<<<<<<<<
@@ -52249,7 +52317,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_int_arr_extend(CYTHON_UNUSED
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("int_arr_extend", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1346
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1348
  *     cdef int* int_arr_extend(self, int* arr, int* arr_len, int* data, int data_len):
  *         cdef int new_len
  *         new_len = arr_len[0] + data_len             # <<<<<<<<<<<<<<
@@ -52258,7 +52326,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_int_arr_extend(CYTHON_UNUSED
  */
   __pyx_v_new_len = ((__pyx_v_arr_len[0]) + __pyx_v_data_len);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1347
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1349
  *         cdef int new_len
  *         new_len = arr_len[0] + data_len
  *         arr = <int*> realloc(arr, new_len*sizeof(int))             # <<<<<<<<<<<<<<
@@ -52267,7 +52335,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_int_arr_extend(CYTHON_UNUSED
  */
   __pyx_v_arr = ((int *)realloc(__pyx_v_arr, (__pyx_v_new_len * (sizeof(int)))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1348
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1350
  *         new_len = arr_len[0] + data_len
  *         arr = <int*> realloc(arr, new_len*sizeof(int))
  *         memcpy(arr+arr_len[0], data, data_len*sizeof(int))             # <<<<<<<<<<<<<<
@@ -52276,7 +52344,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_int_arr_extend(CYTHON_UNUSED
  */
   memcpy((__pyx_v_arr + (__pyx_v_arr_len[0])), __pyx_v_data, (__pyx_v_data_len * (sizeof(int))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1349
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1351
  *         arr = <int*> realloc(arr, new_len*sizeof(int))
  *         memcpy(arr+arr_len[0], data, data_len*sizeof(int))
  *         arr_len[0] = new_len             # <<<<<<<<<<<<<<
@@ -52285,7 +52353,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_int_arr_extend(CYTHON_UNUSED
  */
   (__pyx_v_arr_len[0]) = __pyx_v_new_len;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1350
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1352
  *         memcpy(arr+arr_len[0], data, data_len*sizeof(int))
  *         arr_len[0] = new_len
  *         return arr             # <<<<<<<<<<<<<<
@@ -52301,7 +52369,7 @@ static int *__pyx_f_3_sa_23HieroCachingRuleFactory_int_arr_extend(CYTHON_UNUSED
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1353
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1355
  * 
  * 
  *     cdef extract_phrases(self, int e_low, int e_high, int* e_gap_low, int* e_gap_high, int* e_links_low, int num_gaps,             # <<<<<<<<<<<<<<
@@ -52347,19 +52415,19 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("extract_phrases", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1361
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1363
  *         cdef result
  * 
  *         result = []             # <<<<<<<<<<<<<<
  *         len1 = 0
  *         e_gaps1 = <int*> malloc(0)
  */
-  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1361; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_result = ((PyObject *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1362
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1364
  * 
  *         result = []
  *         len1 = 0             # <<<<<<<<<<<<<<
@@ -52368,7 +52436,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
   __pyx_v_len1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1363
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1365
  *         result = []
  *         len1 = 0
  *         e_gaps1 = <int*> malloc(0)             # <<<<<<<<<<<<<<
@@ -52377,19 +52445,19 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
   __pyx_v_e_gaps1 = ((int *)malloc(0));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1364
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1366
  *         len1 = 0
  *         e_gaps1 = <int*> malloc(0)
  *         ephr_arr = IntList()             # <<<<<<<<<<<<<<
  * 
  *         e_gap_order = <int*> malloc(num_gaps*sizeof(int))
  */
-  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1364; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1366; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_ephr_arr = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1366
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1368
  *         ephr_arr = IntList()
  * 
  *         e_gap_order = <int*> malloc(num_gaps*sizeof(int))             # <<<<<<<<<<<<<<
@@ -52398,7 +52466,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
   __pyx_v_e_gap_order = ((int *)malloc((__pyx_v_num_gaps * (sizeof(int)))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1367
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1369
  * 
  *         e_gap_order = <int*> malloc(num_gaps*sizeof(int))
  *         if num_gaps > 0:             # <<<<<<<<<<<<<<
@@ -52408,7 +52476,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
   __pyx_t_2 = (__pyx_v_num_gaps > 0);
   if (__pyx_t_2) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1368
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1370
  *         e_gap_order = <int*> malloc(num_gaps*sizeof(int))
  *         if num_gaps > 0:
  *             e_gap_order[0] = 0             # <<<<<<<<<<<<<<
@@ -52417,7 +52485,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
     (__pyx_v_e_gap_order[0]) = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1369
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1371
  *         if num_gaps > 0:
  *             e_gap_order[0] = 0
  *             for i from 1 <= i < num_gaps:             # <<<<<<<<<<<<<<
@@ -52427,7 +52495,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
     __pyx_t_3 = __pyx_v_num_gaps;
     for (__pyx_v_i = 1; __pyx_v_i < __pyx_t_3; __pyx_v_i++) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1370
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1372
  *             e_gap_order[0] = 0
  *             for i from 1 <= i < num_gaps:
  *                 for j from 0 <= j < i:             # <<<<<<<<<<<<<<
@@ -52437,7 +52505,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       __pyx_t_4 = __pyx_v_i;
       for (__pyx_v_j = 0; __pyx_v_j < __pyx_t_4; __pyx_v_j++) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1371
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1373
  *             for i from 1 <= i < num_gaps:
  *                 for j from 0 <= j < i:
  *                     if e_gap_low[i] < e_gap_low[j]:             # <<<<<<<<<<<<<<
@@ -52447,7 +52515,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
         __pyx_t_2 = ((__pyx_v_e_gap_low[__pyx_v_i]) < (__pyx_v_e_gap_low[__pyx_v_j]));
         if (__pyx_t_2) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1372
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1374
  *                 for j from 0 <= j < i:
  *                     if e_gap_low[i] < e_gap_low[j]:
  *                         for k from j <= k < i:             # <<<<<<<<<<<<<<
@@ -52457,7 +52525,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
           __pyx_t_5 = __pyx_v_i;
           for (__pyx_v_k = __pyx_v_j; __pyx_v_k < __pyx_t_5; __pyx_v_k++) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1373
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1375
  *                     if e_gap_low[i] < e_gap_low[j]:
  *                         for k from j <= k < i:
  *                             e_gap_order[k+1] = e_gap_order[k]             # <<<<<<<<<<<<<<
@@ -52467,7 +52535,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
             (__pyx_v_e_gap_order[(__pyx_v_k + 1)]) = (__pyx_v_e_gap_order[__pyx_v_k]);
           }
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1374
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1376
  *                         for k from j <= k < i:
  *                             e_gap_order[k+1] = e_gap_order[k]
  *                         e_gap_order[j] = i             # <<<<<<<<<<<<<<
@@ -52476,7 +52544,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
           (__pyx_v_e_gap_order[__pyx_v_j]) = __pyx_v_i;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1375
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1377
  *                             e_gap_order[k+1] = e_gap_order[k]
  *                         e_gap_order[j] = i
  *                         break             # <<<<<<<<<<<<<<
@@ -52490,7 +52558,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       }
       /*else*/ {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1377
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1379
  *                         break
  *                 else:
  *                     e_gap_order[i] = i             # <<<<<<<<<<<<<<
@@ -52505,7 +52573,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1379
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1381
  *                     e_gap_order[i] = i
  * 
  *         e_x_low = e_low             # <<<<<<<<<<<<<<
@@ -52514,7 +52582,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
   __pyx_v_e_x_low = __pyx_v_e_low;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1380
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1382
  * 
  *         e_x_low = e_low
  *         e_x_high = e_high             # <<<<<<<<<<<<<<
@@ -52523,7 +52591,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
   __pyx_v_e_x_high = __pyx_v_e_high;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1381
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1383
  *         e_x_low = e_low
  *         e_x_high = e_high
  *         if not self.tight_phrases:             # <<<<<<<<<<<<<<
@@ -52533,7 +52601,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
   __pyx_t_2 = (!__pyx_v_self->tight_phrases);
   if (__pyx_t_2) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1382
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1384
  *         e_x_high = e_high
  *         if not self.tight_phrases:
  *             while e_x_low > 0 and e_high - e_x_low < self.train_max_initial_size and e_links_low[e_x_low-1] == -1:             # <<<<<<<<<<<<<<
@@ -52556,7 +52624,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       }
       if (!__pyx_t_6) break;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1383
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1385
  *         if not self.tight_phrases:
  *             while e_x_low > 0 and e_high - e_x_low < self.train_max_initial_size and e_links_low[e_x_low-1] == -1:
  *                 e_x_low = e_x_low - 1             # <<<<<<<<<<<<<<
@@ -52566,7 +52634,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       __pyx_v_e_x_low = (__pyx_v_e_x_low - 1);
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1384
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1386
  *             while e_x_low > 0 and e_high - e_x_low < self.train_max_initial_size and e_links_low[e_x_low-1] == -1:
  *                 e_x_low = e_x_low - 1
  *             while e_x_high < e_sent_len and e_x_high - e_low < self.train_max_initial_size and e_links_low[e_x_high] == -1:             # <<<<<<<<<<<<<<
@@ -52589,7 +52657,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       }
       if (!__pyx_t_2) break;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1385
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1387
  *                 e_x_low = e_x_low - 1
  *             while e_x_high < e_sent_len and e_x_high - e_low < self.train_max_initial_size and e_links_low[e_x_high] == -1:
  *                 e_x_high = e_x_high + 1             # <<<<<<<<<<<<<<
@@ -52602,7 +52670,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
   }
   __pyx_L11:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1387
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1389
  *                 e_x_high = e_x_high + 1
  * 
  *         for i from e_x_low <= i <= e_low:             # <<<<<<<<<<<<<<
@@ -52612,7 +52680,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
   __pyx_t_3 = __pyx_v_e_low;
   for (__pyx_v_i = __pyx_v_e_x_low; __pyx_v_i <= __pyx_t_3; __pyx_v_i++) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1388
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1390
  * 
  *         for i from e_x_low <= i <= e_low:
  *             e_gaps1 = self.int_arr_extend(e_gaps1, &len1, &i, 1)             # <<<<<<<<<<<<<<
@@ -52622,7 +52690,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
     __pyx_v_e_gaps1 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->int_arr_extend(__pyx_v_self, __pyx_v_e_gaps1, (&__pyx_v_len1), (&__pyx_v_i), 1);
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1390
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1392
  *             e_gaps1 = self.int_arr_extend(e_gaps1, &len1, &i, 1)
  * 
  *         for i from 0 <= i < num_gaps:             # <<<<<<<<<<<<<<
@@ -52632,7 +52700,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
   __pyx_t_3 = __pyx_v_num_gaps;
   for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_3; __pyx_v_i++) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1391
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1393
  * 
  *         for i from 0 <= i < num_gaps:
  *             e_gaps2 = <int*> malloc(0)             # <<<<<<<<<<<<<<
@@ -52641,7 +52709,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
     __pyx_v_e_gaps2 = ((int *)malloc(0));
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1392
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1394
  *         for i from 0 <= i < num_gaps:
  *             e_gaps2 = <int*> malloc(0)
  *             len2 = 0             # <<<<<<<<<<<<<<
@@ -52650,7 +52718,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
     __pyx_v_len2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1394
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1396
  *             len2 = 0
  * 
  *             j = e_gap_order[i]             # <<<<<<<<<<<<<<
@@ -52659,7 +52727,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
     __pyx_v_j = (__pyx_v_e_gap_order[__pyx_v_i]);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1395
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1397
  * 
  *             j = e_gap_order[i]
  *             e_x_gap_low = e_gap_low[j]             # <<<<<<<<<<<<<<
@@ -52668,7 +52736,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
     __pyx_v_e_x_gap_low = (__pyx_v_e_gap_low[__pyx_v_j]);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1396
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1398
  *             j = e_gap_order[i]
  *             e_x_gap_low = e_gap_low[j]
  *             e_x_gap_high = e_gap_high[j]             # <<<<<<<<<<<<<<
@@ -52677,7 +52745,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
     __pyx_v_e_x_gap_high = (__pyx_v_e_gap_high[__pyx_v_j]);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1397
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1399
  *             e_x_gap_low = e_gap_low[j]
  *             e_x_gap_high = e_gap_high[j]
  *             if not self.tight_phrases:             # <<<<<<<<<<<<<<
@@ -52687,7 +52755,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
     __pyx_t_2 = (!__pyx_v_self->tight_phrases);
     if (__pyx_t_2) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1398
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1400
  *             e_x_gap_high = e_gap_high[j]
  *             if not self.tight_phrases:
  *                 while e_x_gap_low > e_x_low and e_links_low[e_x_gap_low-1] == -1:             # <<<<<<<<<<<<<<
@@ -52704,7 +52772,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
         }
         if (!__pyx_t_7) break;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1399
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1401
  *             if not self.tight_phrases:
  *                 while e_x_gap_low > e_x_low and e_links_low[e_x_gap_low-1] == -1:
  *                     e_x_gap_low = e_x_gap_low - 1             # <<<<<<<<<<<<<<
@@ -52714,7 +52782,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
         __pyx_v_e_x_gap_low = (__pyx_v_e_x_gap_low - 1);
       }
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1400
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1402
  *                 while e_x_gap_low > e_x_low and e_links_low[e_x_gap_low-1] == -1:
  *                     e_x_gap_low = e_x_gap_low - 1
  *                 while e_x_gap_high < e_x_high and e_links_low[e_x_gap_high] == -1:             # <<<<<<<<<<<<<<
@@ -52731,7 +52799,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
         }
         if (!__pyx_t_6) break;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1401
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1403
  *                     e_x_gap_low = e_x_gap_low - 1
  *                 while e_x_gap_high < e_x_high and e_links_low[e_x_gap_high] == -1:
  *                     e_x_gap_high = e_x_gap_high + 1             # <<<<<<<<<<<<<<
@@ -52744,7 +52812,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
     }
     __pyx_L20:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1403
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1405
  *                     e_x_gap_high = e_x_gap_high + 1
  * 
  *             k = 0             # <<<<<<<<<<<<<<
@@ -52753,7 +52821,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
     __pyx_v_k = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1404
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1406
  * 
  *             k = 0
  *             step = 1+(i*2)             # <<<<<<<<<<<<<<
@@ -52762,7 +52830,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
     __pyx_v_step = (1 + (__pyx_v_i * 2));
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1405
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1407
  *             k = 0
  *             step = 1+(i*2)
  *             while k < len1:             # <<<<<<<<<<<<<<
@@ -52773,7 +52841,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       __pyx_t_6 = (__pyx_v_k < __pyx_v_len1);
       if (!__pyx_t_6) break;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1406
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1408
  *             step = 1+(i*2)
  *             while k < len1:
  *                 for m from e_x_gap_low <= m <= e_gap_low[j]:             # <<<<<<<<<<<<<<
@@ -52783,7 +52851,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       __pyx_t_4 = (__pyx_v_e_gap_low[__pyx_v_j]);
       for (__pyx_v_m = __pyx_v_e_x_gap_low; __pyx_v_m <= __pyx_t_4; __pyx_v_m++) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1407
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1409
  *             while k < len1:
  *                 for m from e_x_gap_low <= m <= e_gap_low[j]:
  *                     if m >= e_gaps1[k+step-1]:             # <<<<<<<<<<<<<<
@@ -52793,7 +52861,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
         __pyx_t_6 = (__pyx_v_m >= (__pyx_v_e_gaps1[((__pyx_v_k + __pyx_v_step) - 1)]));
         if (__pyx_t_6) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1408
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1410
  *                 for m from e_x_gap_low <= m <= e_gap_low[j]:
  *                     if m >= e_gaps1[k+step-1]:
  *                         for n from e_gap_high[j] <= n <= e_x_gap_high:             # <<<<<<<<<<<<<<
@@ -52803,7 +52871,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
           __pyx_t_5 = __pyx_v_e_x_gap_high;
           for (__pyx_v_n = (__pyx_v_e_gap_high[__pyx_v_j]); __pyx_v_n <= __pyx_t_5; __pyx_v_n++) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1409
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1411
  *                     if m >= e_gaps1[k+step-1]:
  *                         for n from e_gap_high[j] <= n <= e_x_gap_high:
  *                             if n-m >= 1:    # extractor.py doesn't restrict target-side gap length             # <<<<<<<<<<<<<<
@@ -52813,7 +52881,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
             __pyx_t_6 = ((__pyx_v_n - __pyx_v_m) >= 1);
             if (__pyx_t_6) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1410
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1412
  *                         for n from e_gap_high[j] <= n <= e_x_gap_high:
  *                             if n-m >= 1:    # extractor.py doesn't restrict target-side gap length
  *                                 e_gaps2 = self.int_arr_extend(e_gaps2, &len2, e_gaps1+k, step)             # <<<<<<<<<<<<<<
@@ -52822,7 +52890,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
               __pyx_v_e_gaps2 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->int_arr_extend(__pyx_v_self, __pyx_v_e_gaps2, (&__pyx_v_len2), (__pyx_v_e_gaps1 + __pyx_v_k), __pyx_v_step);
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1411
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1413
  *                             if n-m >= 1:    # extractor.py doesn't restrict target-side gap length
  *                                 e_gaps2 = self.int_arr_extend(e_gaps2, &len2, e_gaps1+k, step)
  *                                 e_gaps2 = self.int_arr_extend(e_gaps2, &len2, &m, 1)             # <<<<<<<<<<<<<<
@@ -52831,7 +52899,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
               __pyx_v_e_gaps2 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->int_arr_extend(__pyx_v_self, __pyx_v_e_gaps2, (&__pyx_v_len2), (&__pyx_v_m), 1);
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1412
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1414
  *                                 e_gaps2 = self.int_arr_extend(e_gaps2, &len2, e_gaps1+k, step)
  *                                 e_gaps2 = self.int_arr_extend(e_gaps2, &len2, &m, 1)
  *                                 e_gaps2 = self.int_arr_extend(e_gaps2, &len2, &n, 1)             # <<<<<<<<<<<<<<
@@ -52848,7 +52916,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
         __pyx_L29:;
       }
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1413
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1415
  *                                 e_gaps2 = self.int_arr_extend(e_gaps2, &len2, &m, 1)
  *                                 e_gaps2 = self.int_arr_extend(e_gaps2, &len2, &n, 1)
  *                 k = k + step             # <<<<<<<<<<<<<<
@@ -52858,7 +52926,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       __pyx_v_k = (__pyx_v_k + __pyx_v_step);
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1414
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1416
  *                                 e_gaps2 = self.int_arr_extend(e_gaps2, &len2, &n, 1)
  *                 k = k + step
  *             free(e_gaps1)             # <<<<<<<<<<<<<<
@@ -52867,7 +52935,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
     free(__pyx_v_e_gaps1);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1415
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1417
  *                 k = k + step
  *             free(e_gaps1)
  *             e_gaps1 = e_gaps2             # <<<<<<<<<<<<<<
@@ -52876,7 +52944,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
     __pyx_v_e_gaps1 = __pyx_v_e_gaps2;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1416
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1418
  *             free(e_gaps1)
  *             e_gaps1 = e_gaps2
  *             len1 = len2             # <<<<<<<<<<<<<<
@@ -52886,7 +52954,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
     __pyx_v_len1 = __pyx_v_len2;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1418
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1420
  *             len1 = len2
  * 
  *         step = 1+(num_gaps*2)             # <<<<<<<<<<<<<<
@@ -52895,7 +52963,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
   __pyx_v_step = (1 + (__pyx_v_num_gaps * 2));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1419
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1421
  * 
  *         step = 1+(num_gaps*2)
  *         e_gaps2 = <int*> malloc(0)             # <<<<<<<<<<<<<<
@@ -52904,7 +52972,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
   __pyx_v_e_gaps2 = ((int *)malloc(0));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1420
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1422
  *         step = 1+(num_gaps*2)
  *         e_gaps2 = <int*> malloc(0)
  *         len2 = 0             # <<<<<<<<<<<<<<
@@ -52913,7 +52981,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
   __pyx_v_len2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1421
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1423
  *         e_gaps2 = <int*> malloc(0)
  *         len2 = 0
  *         for i from e_high <= i <= e_x_high:             # <<<<<<<<<<<<<<
@@ -52923,7 +52991,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
   __pyx_t_3 = __pyx_v_e_x_high;
   for (__pyx_v_i = __pyx_v_e_high; __pyx_v_i <= __pyx_t_3; __pyx_v_i++) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1422
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1424
  *         len2 = 0
  *         for i from e_high <= i <= e_x_high:
  *             j = 0             # <<<<<<<<<<<<<<
@@ -52932,7 +53000,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
     __pyx_v_j = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1423
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1425
  *         for i from e_high <= i <= e_x_high:
  *             j = 0
  *             while j < len1:             # <<<<<<<<<<<<<<
@@ -52943,7 +53011,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       __pyx_t_6 = (__pyx_v_j < __pyx_v_len1);
       if (!__pyx_t_6) break;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1424
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1426
  *             j = 0
  *             while j < len1:
  *                 if i - e_gaps1[j] <= self.train_max_initial_size and i >= e_gaps1[j+step-1]:             # <<<<<<<<<<<<<<
@@ -52959,7 +53027,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       }
       if (__pyx_t_2) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1425
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1427
  *             while j < len1:
  *                 if i - e_gaps1[j] <= self.train_max_initial_size and i >= e_gaps1[j+step-1]:
  *                     e_gaps2 = self.int_arr_extend(e_gaps2, &len2, e_gaps1+j, step)             # <<<<<<<<<<<<<<
@@ -52968,7 +53036,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
         __pyx_v_e_gaps2 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->int_arr_extend(__pyx_v_self, __pyx_v_e_gaps2, (&__pyx_v_len2), (__pyx_v_e_gaps1 + __pyx_v_j), __pyx_v_step);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1426
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1428
  *                 if i - e_gaps1[j] <= self.train_max_initial_size and i >= e_gaps1[j+step-1]:
  *                     e_gaps2 = self.int_arr_extend(e_gaps2, &len2, e_gaps1+j, step)
  *                     e_gaps2 = self.int_arr_extend(e_gaps2, &len2, &i, 1)             # <<<<<<<<<<<<<<
@@ -52980,7 +53048,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       }
       __pyx_L37:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1427
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1429
  *                     e_gaps2 = self.int_arr_extend(e_gaps2, &len2, e_gaps1+j, step)
  *                     e_gaps2 = self.int_arr_extend(e_gaps2, &len2, &i, 1)
  *                 j = j + step             # <<<<<<<<<<<<<<
@@ -52991,7 +53059,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
     }
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1428
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1430
  *                     e_gaps2 = self.int_arr_extend(e_gaps2, &len2, &i, 1)
  *                 j = j + step
  *         free(e_gaps1)             # <<<<<<<<<<<<<<
@@ -53000,7 +53068,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
   free(__pyx_v_e_gaps1);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1429
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1431
  *                 j = j + step
  *         free(e_gaps1)
  *         e_gaps1 = e_gaps2             # <<<<<<<<<<<<<<
@@ -53009,7 +53077,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
   __pyx_v_e_gaps1 = __pyx_v_e_gaps2;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1430
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1432
  *         free(e_gaps1)
  *         e_gaps1 = e_gaps2
  *         len1 = len2             # <<<<<<<<<<<<<<
@@ -53018,7 +53086,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
   __pyx_v_len1 = __pyx_v_len2;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1432
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1434
  *         len1 = len2
  * 
  *         step = (num_gaps+1)*2             # <<<<<<<<<<<<<<
@@ -53027,7 +53095,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
   __pyx_v_step = ((__pyx_v_num_gaps + 1) * 2);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1433
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1435
  * 
  *         step = (num_gaps+1)*2
  *         i = 0             # <<<<<<<<<<<<<<
@@ -53036,7 +53104,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
   __pyx_v_i = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1435
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1437
  *         i = 0
  * 
  *         while i < len1:             # <<<<<<<<<<<<<<
@@ -53047,7 +53115,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
     __pyx_t_2 = (__pyx_v_i < __pyx_v_len1);
     if (!__pyx_t_2) break;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1436
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1438
  * 
  *         while i < len1:
  *             ephr_arr._clear()             # <<<<<<<<<<<<<<
@@ -53056,7 +53124,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
     ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_ephr_arr->__pyx_vtab)->_clear(__pyx_v_ephr_arr);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1437
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1439
  *         while i < len1:
  *             ephr_arr._clear()
  *             num_chunks = 0             # <<<<<<<<<<<<<<
@@ -53065,20 +53133,20 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
     __pyx_v_num_chunks = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1438
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1440
  *             ephr_arr._clear()
  *             num_chunks = 0
  *             indexes = []             # <<<<<<<<<<<<<<
  *             for j from 0 <= j < num_gaps+1:
  *                 if e_gaps1[i+2*j] < e_gaps1[i+(2*j)+1]:
  */
-    __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1438; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1440; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_XDECREF(((PyObject *)__pyx_v_indexes));
     __pyx_v_indexes = __pyx_t_1;
     __pyx_t_1 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1439
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1441
  *             num_chunks = 0
  *             indexes = []
  *             for j from 0 <= j < num_gaps+1:             # <<<<<<<<<<<<<<
@@ -53088,7 +53156,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
     __pyx_t_9 = (__pyx_v_num_gaps + 1);
     for (__pyx_v_j = 0; __pyx_v_j < __pyx_t_9; __pyx_v_j++) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1440
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1442
  *             indexes = []
  *             for j from 0 <= j < num_gaps+1:
  *                 if e_gaps1[i+2*j] < e_gaps1[i+(2*j)+1]:             # <<<<<<<<<<<<<<
@@ -53098,7 +53166,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       __pyx_t_2 = ((__pyx_v_e_gaps1[(__pyx_v_i + (2 * __pyx_v_j))]) < (__pyx_v_e_gaps1[((__pyx_v_i + (2 * __pyx_v_j)) + 1)]));
       if (__pyx_t_2) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1441
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1443
  *             for j from 0 <= j < num_gaps+1:
  *                 if e_gaps1[i+2*j] < e_gaps1[i+(2*j)+1]:
  *                     num_chunks = num_chunks + 1             # <<<<<<<<<<<<<<
@@ -53110,7 +53178,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       }
       __pyx_L42:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1442
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1444
  *                 if e_gaps1[i+2*j] < e_gaps1[i+(2*j)+1]:
  *                     num_chunks = num_chunks + 1
  *                 for k from e_gaps1[i+2*j] <= k < e_gaps1[i+(2*j)+1]:             # <<<<<<<<<<<<<<
@@ -53120,19 +53188,19 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       __pyx_t_3 = (__pyx_v_e_gaps1[((__pyx_v_i + (2 * __pyx_v_j)) + 1)]);
       for (__pyx_v_k = (__pyx_v_e_gaps1[(__pyx_v_i + (2 * __pyx_v_j))]); __pyx_v_k < __pyx_t_3; __pyx_v_k++) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1443
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1445
  *                     num_chunks = num_chunks + 1
  *                 for k from e_gaps1[i+2*j] <= k < e_gaps1[i+(2*j)+1]:
  *                     indexes.append(k)             # <<<<<<<<<<<<<<
  *                     ephr_arr._append(self.eid2symid[self.eda.data.arr[e_sent_start+k]])
  *                 if j < num_gaps:
  */
-        __pyx_t_1 = PyInt_FromLong(__pyx_v_k); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1443; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyInt_FromLong(__pyx_v_k); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1445; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
-        __pyx_t_10 = PyList_Append(__pyx_v_indexes, __pyx_t_1); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1443; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_10 = PyList_Append(__pyx_v_indexes, __pyx_t_1); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1445; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1444
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1446
  *                 for k from e_gaps1[i+2*j] <= k < e_gaps1[i+(2*j)+1]:
  *                     indexes.append(k)
  *                     ephr_arr._append(self.eid2symid[self.eda.data.arr[e_sent_start+k]])             # <<<<<<<<<<<<<<
@@ -53140,14 +53208,14 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  *                     indexes.append(sym_setindex(self.category, e_gap_order[j]+1))
  */
         __pyx_t_4 = (__pyx_v_self->eda->data->arr[(__pyx_v_e_sent_start + __pyx_v_k)]);
-        __pyx_t_1 = __Pyx_GetItemInt(((PyObject *)__pyx_v_self->eid2symid), __pyx_t_4, sizeof(int), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1444; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = __Pyx_GetItemInt(((PyObject *)__pyx_v_self->eid2symid), __pyx_t_4, sizeof(int), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
-        __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1444; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
         ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_ephr_arr->__pyx_vtab)->_append(__pyx_v_ephr_arr, __pyx_t_4);
       }
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1445
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1447
  *                     indexes.append(k)
  *                     ephr_arr._append(self.eid2symid[self.eda.data.arr[e_sent_start+k]])
  *                 if j < num_gaps:             # <<<<<<<<<<<<<<
@@ -53157,19 +53225,19 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       __pyx_t_2 = (__pyx_v_j < __pyx_v_num_gaps);
       if (__pyx_t_2) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1446
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1448
  *                     ephr_arr._append(self.eid2symid[self.eda.data.arr[e_sent_start+k]])
  *                 if j < num_gaps:
  *                     indexes.append(sym_setindex(self.category, e_gap_order[j]+1))             # <<<<<<<<<<<<<<
  *                     ephr_arr._append(sym_setindex(self.category, e_gap_order[j]+1))
  *             i = i + step
  */
-        __pyx_t_1 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, ((__pyx_v_e_gap_order[__pyx_v_j]) + 1))); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, ((__pyx_v_e_gap_order[__pyx_v_j]) + 1))); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1448; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
-        __pyx_t_10 = PyList_Append(__pyx_v_indexes, __pyx_t_1); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_10 = PyList_Append(__pyx_v_indexes, __pyx_t_1); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1448; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1447
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1449
  *                 if j < num_gaps:
  *                     indexes.append(sym_setindex(self.category, e_gap_order[j]+1))
  *                     ephr_arr._append(sym_setindex(self.category, e_gap_order[j]+1))             # <<<<<<<<<<<<<<
@@ -53182,7 +53250,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       __pyx_L45:;
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1448
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1450
  *                     indexes.append(sym_setindex(self.category, e_gap_order[j]+1))
  *                     ephr_arr._append(sym_setindex(self.category, e_gap_order[j]+1))
  *             i = i + step             # <<<<<<<<<<<<<<
@@ -53191,7 +53259,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
     __pyx_v_i = (__pyx_v_i + __pyx_v_step);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1449
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1451
  *                     ephr_arr._append(sym_setindex(self.category, e_gap_order[j]+1))
  *             i = i + step
  *             if ephr_arr.len <= self.max_target_length and num_chunks <= self.max_target_chunks:             # <<<<<<<<<<<<<<
@@ -53207,22 +53275,22 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
     }
     if (__pyx_t_7) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1450
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1452
  *             i = i + step
  *             if ephr_arr.len <= self.max_target_length and num_chunks <= self.max_target_chunks:
  *                 result.append((Phrase(ephr_arr),indexes))             # <<<<<<<<<<<<<<
  * 
  *         free(e_gaps1)
  */
-      __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1452; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_INCREF(((PyObject *)__pyx_v_ephr_arr));
       PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_v_ephr_arr));
       __Pyx_GIVEREF(((PyObject *)__pyx_v_ephr_arr));
-      __pyx_t_11 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_11 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1452; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_11);
       __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-      __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1452; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_11);
       __Pyx_GIVEREF(__pyx_t_11);
@@ -53230,7 +53298,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
       PyTuple_SET_ITEM(__pyx_t_1, 1, ((PyObject *)__pyx_v_indexes));
       __Pyx_GIVEREF(((PyObject *)__pyx_v_indexes));
       __pyx_t_11 = 0;
-      __pyx_t_11 = __Pyx_PyObject_Append(__pyx_v_result, ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_11 = __Pyx_PyObject_Append(__pyx_v_result, ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1452; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_11);
       __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
       __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
@@ -53239,7 +53307,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
     __pyx_L46:;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1452
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1454
  *                 result.append((Phrase(ephr_arr),indexes))
  * 
  *         free(e_gaps1)             # <<<<<<<<<<<<<<
@@ -53248,7 +53316,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
   free(__pyx_v_e_gaps1);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1453
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1455
  * 
  *         free(e_gaps1)
  *         free(e_gap_order)             # <<<<<<<<<<<<<<
@@ -53257,7 +53325,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
  */
   free(__pyx_v_e_gap_order);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1454
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1456
  *         free(e_gaps1)
  *         free(e_gap_order)
  *         return result             # <<<<<<<<<<<<<<
@@ -53285,7 +53353,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases(struct _
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1456
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1458
  *         return result
  * 
  *     cdef IntList create_alignments(self, int* sent_links, int num_links, findexes, eindexes):             # <<<<<<<<<<<<<<
@@ -53313,55 +53381,55 @@ static struct __pyx_obj_3_sa_IntList *__pyx_f_3_sa_23HieroCachingRuleFactory_cre
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("create_alignments", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1458
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1460
  *     cdef IntList create_alignments(self, int* sent_links, int num_links, findexes, eindexes):
  *         cdef unsigned i
  *         cdef IntList ret = IntList()             # <<<<<<<<<<<<<<
  *         for i in range(len(findexes)):
  *             s = findexes[i]
  */
-  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1458; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_ret = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1459
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1461
  *         cdef unsigned i
  *         cdef IntList ret = IntList()
  *         for i in range(len(findexes)):             # <<<<<<<<<<<<<<
  *             s = findexes[i]
  *             if (s<0):
  */
-  __pyx_t_2 = PyObject_Length(__pyx_v_findexes); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Length(__pyx_v_findexes); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1461; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
     __pyx_v_i = __pyx_t_3;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1460
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1462
  *         cdef IntList ret = IntList()
  *         for i in range(len(findexes)):
  *             s = findexes[i]             # <<<<<<<<<<<<<<
  *             if (s<0):
  *                 continue
  */
-    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_findexes, __pyx_v_i, sizeof(unsigned int)+1, PyLong_FromUnsignedLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_findexes, __pyx_v_i, sizeof(unsigned int)+1, PyLong_FromUnsignedLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_XDECREF(__pyx_v_s);
     __pyx_v_s = __pyx_t_1;
     __pyx_t_1 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1461
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1463
  *         for i in range(len(findexes)):
  *             s = findexes[i]
  *             if (s<0):             # <<<<<<<<<<<<<<
  *                 continue
  *             idx = 0
  */
-    __pyx_t_1 = PyObject_RichCompare(__pyx_v_s, __pyx_int_0, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1461; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1461; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_RichCompare(__pyx_v_s, __pyx_int_0, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     if (__pyx_t_4) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1462
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1464
  *             s = findexes[i]
  *             if (s<0):
  *                 continue             # <<<<<<<<<<<<<<
@@ -53373,7 +53441,7 @@ static struct __pyx_obj_3_sa_IntList *__pyx_f_3_sa_23HieroCachingRuleFactory_cre
     }
     __pyx_L5:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1463
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1465
  *             if (s<0):
  *                 continue
  *             idx = 0             # <<<<<<<<<<<<<<
@@ -53384,7 +53452,7 @@ static struct __pyx_obj_3_sa_IntList *__pyx_f_3_sa_23HieroCachingRuleFactory_cre
     __Pyx_XDECREF(__pyx_v_idx);
     __pyx_v_idx = __pyx_int_0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1464
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1466
  *                 continue
  *             idx = 0
  *             while (idx < num_links*2):             # <<<<<<<<<<<<<<
@@ -53392,51 +53460,51 @@ static struct __pyx_obj_3_sa_IntList *__pyx_f_3_sa_23HieroCachingRuleFactory_cre
  *                     j = eindexes.index(sent_links[idx+1])
  */
     while (1) {
-      __pyx_t_1 = PyInt_FromLong((__pyx_v_num_links * 2)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyInt_FromLong((__pyx_v_num_links * 2)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_5 = PyObject_RichCompare(__pyx_v_idx, __pyx_t_1, Py_LT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyObject_RichCompare(__pyx_v_idx, __pyx_t_1, Py_LT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       if (!__pyx_t_4) break;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1465
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1467
  *             idx = 0
  *             while (idx < num_links*2):
  *                 if (sent_links[idx] == s):             # <<<<<<<<<<<<<<
  *                     j = eindexes.index(sent_links[idx+1])
  *                     ret.append(i*65536+j)
  */
-      __pyx_t_6 = __Pyx_PyIndex_AsSsize_t(__pyx_v_idx); if (unlikely((__pyx_t_6 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_5 = PyInt_FromLong((__pyx_v_sent_links[__pyx_t_6])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyIndex_AsSsize_t(__pyx_v_idx); if (unlikely((__pyx_t_6 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyInt_FromLong((__pyx_v_sent_links[__pyx_t_6])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_1 = PyObject_RichCompare(__pyx_t_5, __pyx_v_s, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_RichCompare(__pyx_t_5, __pyx_v_s, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       if (__pyx_t_4) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1466
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1468
  *             while (idx < num_links*2):
  *                 if (sent_links[idx] == s):
  *                     j = eindexes.index(sent_links[idx+1])             # <<<<<<<<<<<<<<
  *                     ret.append(i*65536+j)
  *                 idx += 2
  */
-        __pyx_t_1 = PyObject_GetAttr(__pyx_v_eindexes, __pyx_n_s__index); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyObject_GetAttr(__pyx_v_eindexes, __pyx_n_s__index); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
-        __pyx_t_5 = PyNumber_Add(__pyx_v_idx, __pyx_int_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = PyNumber_Add(__pyx_v_idx, __pyx_int_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_5);
-        __pyx_t_6 = __Pyx_PyIndex_AsSsize_t(__pyx_t_5); if (unlikely((__pyx_t_6 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_6 = __Pyx_PyIndex_AsSsize_t(__pyx_t_5); if (unlikely((__pyx_t_6 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-        __pyx_t_5 = PyInt_FromLong((__pyx_v_sent_links[__pyx_t_6])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = PyInt_FromLong((__pyx_v_sent_links[__pyx_t_6])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_5);
-        __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_7);
         PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5);
         __Pyx_GIVEREF(__pyx_t_5);
         __pyx_t_5 = 0;
-        __pyx_t_5 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_7), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_7), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_5);
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
         __Pyx_DECREF(((PyObject *)__pyx_t_7)); __pyx_t_7 = 0;
@@ -53444,19 +53512,19 @@ static struct __pyx_obj_3_sa_IntList *__pyx_f_3_sa_23HieroCachingRuleFactory_cre
         __pyx_v_j = __pyx_t_5;
         __pyx_t_5 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1467
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1469
  *                 if (sent_links[idx] == s):
  *                     j = eindexes.index(sent_links[idx+1])
  *                     ret.append(i*65536+j)             # <<<<<<<<<<<<<<
  *                 idx += 2
  *         return ret
  */
-        __pyx_t_5 = PyInt_FromLong((__pyx_v_i * 65536)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = PyInt_FromLong((__pyx_v_i * 65536)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1469; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_5);
-        __pyx_t_7 = PyNumber_Add(__pyx_t_5, __pyx_v_j); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PyNumber_Add(__pyx_t_5, __pyx_v_j); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1469; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_7);
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-        __pyx_t_5 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_ret), __pyx_t_7); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_ret), __pyx_t_7); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1469; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_5);
         __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
@@ -53464,14 +53532,14 @@ static struct __pyx_obj_3_sa_IntList *__pyx_f_3_sa_23HieroCachingRuleFactory_cre
       }
       __pyx_L8:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1468
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1470
  *                     j = eindexes.index(sent_links[idx+1])
  *                     ret.append(i*65536+j)
  *                 idx += 2             # <<<<<<<<<<<<<<
  *         return ret
  * 
  */
-      __pyx_t_5 = PyNumber_InPlaceAdd(__pyx_v_idx, __pyx_int_2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyNumber_InPlaceAdd(__pyx_v_idx, __pyx_int_2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1470; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_DECREF(__pyx_v_idx);
       __pyx_v_idx = __pyx_t_5;
@@ -53480,7 +53548,7 @@ static struct __pyx_obj_3_sa_IntList *__pyx_f_3_sa_23HieroCachingRuleFactory_cre
     __pyx_L3_continue:;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1469
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1471
  *                     ret.append(i*65536+j)
  *                 idx += 2
  *         return ret             # <<<<<<<<<<<<<<
@@ -53510,7 +53578,7 @@ static struct __pyx_obj_3_sa_IntList *__pyx_f_3_sa_23HieroCachingRuleFactory_cre
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1471
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1473
  *         return ret
  * 
  *     cdef extract(self, Phrase phrase, Matching* matching, int* chunklen, int num_chunks):             # <<<<<<<<<<<<<<
@@ -53604,19 +53672,19 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("extract", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1484
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1486
  *         cdef reason_for_failure
  * 
  *         fphr_arr = IntList()             # <<<<<<<<<<<<<<
  *         phrase_len = phrase.n
  *         extracts = []
  */
-  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1484; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_IntList)), ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1486; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_fphr_arr = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1485
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1487
  * 
  *         fphr_arr = IntList()
  *         phrase_len = phrase.n             # <<<<<<<<<<<<<<
@@ -53625,19 +53693,19 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_phrase_len = __pyx_v_phrase->n;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1486
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1488
  *         fphr_arr = IntList()
  *         phrase_len = phrase.n
  *         extracts = []             # <<<<<<<<<<<<<<
  *         sent_links = self.alignment._get_sent_links(matching.sent_id, &num_links)
  * 
  */
-  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1486; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1488; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_extracts = ((PyObject *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1487
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1489
  *         phrase_len = phrase.n
  *         extracts = []
  *         sent_links = self.alignment._get_sent_links(matching.sent_id, &num_links)             # <<<<<<<<<<<<<<
@@ -53646,7 +53714,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_sent_links = ((struct __pyx_vtabstruct_3_sa_Alignment *)__pyx_v_self->alignment->__pyx_vtab)->_get_sent_links(__pyx_v_self->alignment, __pyx_v_matching->sent_id, (&__pyx_v_num_links));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1489
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1491
  *         sent_links = self.alignment._get_sent_links(matching.sent_id, &num_links)
  * 
  *         e_sent_start = self.eda.sent_index.arr[matching.sent_id]             # <<<<<<<<<<<<<<
@@ -53655,7 +53723,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_e_sent_start = (__pyx_v_self->eda->sent_index->arr[__pyx_v_matching->sent_id]);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1490
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1492
  * 
  *         e_sent_start = self.eda.sent_index.arr[matching.sent_id]
  *         e_sent_end = self.eda.sent_index.arr[matching.sent_id+1]             # <<<<<<<<<<<<<<
@@ -53664,7 +53732,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_e_sent_end = (__pyx_v_self->eda->sent_index->arr[(__pyx_v_matching->sent_id + 1)]);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1491
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1493
  *         e_sent_start = self.eda.sent_index.arr[matching.sent_id]
  *         e_sent_end = self.eda.sent_index.arr[matching.sent_id+1]
  *         e_sent_len = e_sent_end - e_sent_start - 1             # <<<<<<<<<<<<<<
@@ -53673,7 +53741,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_e_sent_len = ((__pyx_v_e_sent_end - __pyx_v_e_sent_start) - 1);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1492
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1494
  *         e_sent_end = self.eda.sent_index.arr[matching.sent_id+1]
  *         e_sent_len = e_sent_end - e_sent_start - 1
  *         f_sent_start = self.fda.sent_index.arr[matching.sent_id]             # <<<<<<<<<<<<<<
@@ -53682,7 +53750,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_f_sent_start = (__pyx_v_self->fda->sent_index->arr[__pyx_v_matching->sent_id]);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1493
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1495
  *         e_sent_len = e_sent_end - e_sent_start - 1
  *         f_sent_start = self.fda.sent_index.arr[matching.sent_id]
  *         f_sent_end = self.fda.sent_index.arr[matching.sent_id+1]             # <<<<<<<<<<<<<<
@@ -53691,7 +53759,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_f_sent_end = (__pyx_v_self->fda->sent_index->arr[(__pyx_v_matching->sent_id + 1)]);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1494
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1496
  *         f_sent_start = self.fda.sent_index.arr[matching.sent_id]
  *         f_sent_end = self.fda.sent_index.arr[matching.sent_id+1]
  *         f_sent_len = f_sent_end - f_sent_start - 1             # <<<<<<<<<<<<<<
@@ -53700,21 +53768,21 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_f_sent_len = ((__pyx_v_f_sent_end - __pyx_v_f_sent_start) - 1);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1496
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1498
  *         f_sent_len = f_sent_end - f_sent_start - 1
  * 
  *         self.findexes1.reset()             # <<<<<<<<<<<<<<
  *         sofar = 0
  *         for i in range(num_chunks):
  */
-  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes1), __pyx_n_s__reset); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes1), __pyx_n_s__reset); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1498; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1498; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1497
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1499
  * 
  *         self.findexes1.reset()
  *         sofar = 0             # <<<<<<<<<<<<<<
@@ -53724,7 +53792,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
   __Pyx_INCREF(__pyx_int_0);
   __pyx_v_sofar = __pyx_int_0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1498
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1500
  *         self.findexes1.reset()
  *         sofar = 0
  *         for i in range(num_chunks):             # <<<<<<<<<<<<<<
@@ -53735,7 +53803,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
   for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
     __pyx_v_i = __pyx_t_4;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1499
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1501
  *         sofar = 0
  *         for i in range(num_chunks):
  *             for j in range(chunklen[i]):             # <<<<<<<<<<<<<<
@@ -53746,35 +53814,35 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
       __pyx_v_j = __pyx_t_6;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1500
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1502
  *         for i in range(num_chunks):
  *             for j in range(chunklen[i]):
  *                 self.findexes1.append(matching.arr[matching.start+i]+j-f_sent_start);             # <<<<<<<<<<<<<<
  *                 sofar += 1
  *             if (i+1<num_chunks):
  */
-      __pyx_t_2 = PyInt_FromLong((((__pyx_v_matching->arr[(__pyx_v_matching->start + __pyx_v_i)]) + __pyx_v_j) - __pyx_v_f_sent_start)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1500; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyInt_FromLong((((__pyx_v_matching->arr[(__pyx_v_matching->start + __pyx_v_i)]) + __pyx_v_j) - __pyx_v_f_sent_start)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_1 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes1), __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1500; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes1), __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1501
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1503
  *             for j in range(chunklen[i]):
  *                 self.findexes1.append(matching.arr[matching.start+i]+j-f_sent_start);
  *                 sofar += 1             # <<<<<<<<<<<<<<
  *             if (i+1<num_chunks):
  *                 self.findexes1.append(phrase[sofar])
  */
-      __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_sofar, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1501; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_sofar, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1503; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_v_sofar);
       __pyx_v_sofar = __pyx_t_1;
       __pyx_t_1 = 0;
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1502
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1504
  *                 self.findexes1.append(matching.arr[matching.start+i]+j-f_sent_start);
  *                 sofar += 1
  *             if (i+1<num_chunks):             # <<<<<<<<<<<<<<
@@ -53784,28 +53852,28 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     __pyx_t_7 = ((__pyx_v_i + 1) < __pyx_v_num_chunks);
     if (__pyx_t_7) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1503
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1505
  *                 sofar += 1
  *             if (i+1<num_chunks):
  *                 self.findexes1.append(phrase[sofar])             # <<<<<<<<<<<<<<
  *                 sofar += 1
  * 
  */
-      __pyx_t_1 = PyObject_GetItem(((PyObject *)__pyx_v_phrase), __pyx_v_sofar); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1503; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_GetItem(((PyObject *)__pyx_v_phrase), __pyx_v_sofar); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1505; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_2 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes1), __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1503; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes1), __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1505; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1504
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1506
  *             if (i+1<num_chunks):
  *                 self.findexes1.append(phrase[sofar])
  *                 sofar += 1             # <<<<<<<<<<<<<<
  * 
  * 
  */
-      __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_sofar, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1504; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_sofar, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1506; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_v_sofar);
       __pyx_v_sofar = __pyx_t_2;
@@ -53815,7 +53883,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     __pyx_L7:;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1507
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1509
  * 
  * 
  *         e_links_low = <int*> malloc(e_sent_len*sizeof(int))             # <<<<<<<<<<<<<<
@@ -53824,7 +53892,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_e_links_low = ((int *)malloc((__pyx_v_e_sent_len * (sizeof(int)))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1508
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1510
  * 
  *         e_links_low = <int*> malloc(e_sent_len*sizeof(int))
  *         e_links_high = <int*> malloc(e_sent_len*sizeof(int))             # <<<<<<<<<<<<<<
@@ -53833,7 +53901,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_e_links_high = ((int *)malloc((__pyx_v_e_sent_len * (sizeof(int)))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1509
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1511
  *         e_links_low = <int*> malloc(e_sent_len*sizeof(int))
  *         e_links_high = <int*> malloc(e_sent_len*sizeof(int))
  *         f_links_low = <int*> malloc(f_sent_len*sizeof(int))             # <<<<<<<<<<<<<<
@@ -53842,7 +53910,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_f_links_low = ((int *)malloc((__pyx_v_f_sent_len * (sizeof(int)))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1510
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1512
  *         e_links_high = <int*> malloc(e_sent_len*sizeof(int))
  *         f_links_low = <int*> malloc(f_sent_len*sizeof(int))
  *         f_links_high = <int*> malloc(f_sent_len*sizeof(int))             # <<<<<<<<<<<<<<
@@ -53851,7 +53919,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_f_links_high = ((int *)malloc((__pyx_v_f_sent_len * (sizeof(int)))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1511
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1513
  *         f_links_low = <int*> malloc(f_sent_len*sizeof(int))
  *         f_links_high = <int*> malloc(f_sent_len*sizeof(int))
  *         f_gap_low = <int*> malloc((num_chunks+1)*sizeof(int))             # <<<<<<<<<<<<<<
@@ -53860,7 +53928,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_f_gap_low = ((int *)malloc(((__pyx_v_num_chunks + 1) * (sizeof(int)))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1512
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1514
  *         f_links_high = <int*> malloc(f_sent_len*sizeof(int))
  *         f_gap_low = <int*> malloc((num_chunks+1)*sizeof(int))
  *         f_gap_high = <int*> malloc((num_chunks+1)*sizeof(int))             # <<<<<<<<<<<<<<
@@ -53869,7 +53937,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_f_gap_high = ((int *)malloc(((__pyx_v_num_chunks + 1) * (sizeof(int)))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1513
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1515
  *         f_gap_low = <int*> malloc((num_chunks+1)*sizeof(int))
  *         f_gap_high = <int*> malloc((num_chunks+1)*sizeof(int))
  *         e_gap_low = <int*> malloc((num_chunks+1)*sizeof(int))             # <<<<<<<<<<<<<<
@@ -53878,7 +53946,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_e_gap_low = ((int *)malloc(((__pyx_v_num_chunks + 1) * (sizeof(int)))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1514
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1516
  *         f_gap_high = <int*> malloc((num_chunks+1)*sizeof(int))
  *         e_gap_low = <int*> malloc((num_chunks+1)*sizeof(int))
  *         e_gap_high = <int*> malloc((num_chunks+1)*sizeof(int))             # <<<<<<<<<<<<<<
@@ -53887,7 +53955,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_e_gap_high = ((int *)malloc(((__pyx_v_num_chunks + 1) * (sizeof(int)))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1515
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1517
  *         e_gap_low = <int*> malloc((num_chunks+1)*sizeof(int))
  *         e_gap_high = <int*> malloc((num_chunks+1)*sizeof(int))
  *         memset(f_gap_low, 0, (num_chunks+1)*sizeof(int))             # <<<<<<<<<<<<<<
@@ -53896,7 +53964,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   memset(__pyx_v_f_gap_low, 0, ((__pyx_v_num_chunks + 1) * (sizeof(int))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1516
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1518
  *         e_gap_high = <int*> malloc((num_chunks+1)*sizeof(int))
  *         memset(f_gap_low, 0, (num_chunks+1)*sizeof(int))
  *         memset(f_gap_high, 0, (num_chunks+1)*sizeof(int))             # <<<<<<<<<<<<<<
@@ -53905,7 +53973,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   memset(__pyx_v_f_gap_high, 0, ((__pyx_v_num_chunks + 1) * (sizeof(int))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1517
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1519
  *         memset(f_gap_low, 0, (num_chunks+1)*sizeof(int))
  *         memset(f_gap_high, 0, (num_chunks+1)*sizeof(int))
  *         memset(e_gap_low, 0, (num_chunks+1)*sizeof(int))             # <<<<<<<<<<<<<<
@@ -53914,7 +53982,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   memset(__pyx_v_e_gap_low, 0, ((__pyx_v_num_chunks + 1) * (sizeof(int))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1518
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1520
  *         memset(f_gap_high, 0, (num_chunks+1)*sizeof(int))
  *         memset(e_gap_low, 0, (num_chunks+1)*sizeof(int))
  *         memset(e_gap_high, 0, (num_chunks+1)*sizeof(int))             # <<<<<<<<<<<<<<
@@ -53923,7 +53991,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   memset(__pyx_v_e_gap_high, 0, ((__pyx_v_num_chunks + 1) * (sizeof(int))));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1520
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1522
  *         memset(e_gap_high, 0, (num_chunks+1)*sizeof(int))
  * 
  *         reason_for_failure = ""             # <<<<<<<<<<<<<<
@@ -53933,7 +54001,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
   __Pyx_INCREF(((PyObject *)__pyx_kp_s_45));
   __pyx_v_reason_for_failure = ((PyObject *)__pyx_kp_s_45);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1522
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1524
  *         reason_for_failure = ""
  * 
  *         for i from 0 <= i < e_sent_len:             # <<<<<<<<<<<<<<
@@ -53943,7 +54011,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
   __pyx_t_3 = __pyx_v_e_sent_len;
   for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_3; __pyx_v_i++) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1523
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1525
  * 
  *         for i from 0 <= i < e_sent_len:
  *             e_links_low[i] = -1             # <<<<<<<<<<<<<<
@@ -53952,7 +54020,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
     (__pyx_v_e_links_low[__pyx_v_i]) = -1;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1524
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1526
  *         for i from 0 <= i < e_sent_len:
  *             e_links_low[i] = -1
  *             e_links_high[i] = -1             # <<<<<<<<<<<<<<
@@ -53962,7 +54030,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     (__pyx_v_e_links_high[__pyx_v_i]) = -1;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1525
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1527
  *             e_links_low[i] = -1
  *             e_links_high[i] = -1
  *         for i from 0 <= i < f_sent_len:             # <<<<<<<<<<<<<<
@@ -53972,7 +54040,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
   __pyx_t_3 = __pyx_v_f_sent_len;
   for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_3; __pyx_v_i++) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1526
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1528
  *             e_links_high[i] = -1
  *         for i from 0 <= i < f_sent_len:
  *             f_links_low[i] = -1             # <<<<<<<<<<<<<<
@@ -53981,7 +54049,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
     (__pyx_v_f_links_low[__pyx_v_i]) = -1;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1527
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1529
  *         for i from 0 <= i < f_sent_len:
  *             f_links_low[i] = -1
  *             f_links_high[i] = -1             # <<<<<<<<<<<<<<
@@ -53991,7 +54059,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     (__pyx_v_f_links_high[__pyx_v_i]) = -1;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1533
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1535
  *         # links that we care about (but then how to look up
  *         # when we want to check something on the e side?)
  *         i = 0             # <<<<<<<<<<<<<<
@@ -54000,7 +54068,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_i = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1534
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1536
  *         # when we want to check something on the e side?)
  *         i = 0
  *         while i < num_links*2:             # <<<<<<<<<<<<<<
@@ -54011,7 +54079,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     __pyx_t_7 = (__pyx_v_i < (__pyx_v_num_links * 2));
     if (!__pyx_t_7) break;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1535
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1537
  *         i = 0
  *         while i < num_links*2:
  *             f_i = sent_links[i]             # <<<<<<<<<<<<<<
@@ -54020,7 +54088,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
     __pyx_v_f_i = (__pyx_v_sent_links[__pyx_v_i]);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1536
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1538
  *         while i < num_links*2:
  *             f_i = sent_links[i]
  *             e_i = sent_links[i+1]             # <<<<<<<<<<<<<<
@@ -54029,7 +54097,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
     __pyx_v_e_i = (__pyx_v_sent_links[(__pyx_v_i + 1)]);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1537
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1539
  *             f_i = sent_links[i]
  *             e_i = sent_links[i+1]
  *             if f_links_low[f_i] == -1 or f_links_low[f_i] > e_i:             # <<<<<<<<<<<<<<
@@ -54045,7 +54113,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     }
     if (__pyx_t_9) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1538
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1540
  *             e_i = sent_links[i+1]
  *             if f_links_low[f_i] == -1 or f_links_low[f_i] > e_i:
  *                 f_links_low[f_i] = e_i             # <<<<<<<<<<<<<<
@@ -54057,7 +54125,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     }
     __pyx_L14:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1539
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1541
  *             if f_links_low[f_i] == -1 or f_links_low[f_i] > e_i:
  *                 f_links_low[f_i] = e_i
  *             if f_links_high[f_i] == -1 or f_links_high[f_i] < e_i + 1:             # <<<<<<<<<<<<<<
@@ -54073,7 +54141,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     }
     if (__pyx_t_8) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1540
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1542
  *                 f_links_low[f_i] = e_i
  *             if f_links_high[f_i] == -1 or f_links_high[f_i] < e_i + 1:
  *                 f_links_high[f_i] = e_i + 1             # <<<<<<<<<<<<<<
@@ -54085,7 +54153,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     }
     __pyx_L15:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1541
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1543
  *             if f_links_high[f_i] == -1 or f_links_high[f_i] < e_i + 1:
  *                 f_links_high[f_i] = e_i + 1
  *             if e_links_low[e_i] == -1 or e_links_low[e_i] > f_i:             # <<<<<<<<<<<<<<
@@ -54101,7 +54169,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     }
     if (__pyx_t_7) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1542
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1544
  *                 f_links_high[f_i] = e_i + 1
  *             if e_links_low[e_i] == -1 or e_links_low[e_i] > f_i:
  *                 e_links_low[e_i] = f_i             # <<<<<<<<<<<<<<
@@ -54113,7 +54181,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     }
     __pyx_L16:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1543
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1545
  *             if e_links_low[e_i] == -1 or e_links_low[e_i] > f_i:
  *                 e_links_low[e_i] = f_i
  *             if e_links_high[e_i] == -1 or e_links_high[e_i] < f_i + 1:             # <<<<<<<<<<<<<<
@@ -54129,7 +54197,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     }
     if (__pyx_t_9) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1544
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1546
  *                 e_links_low[e_i] = f_i
  *             if e_links_high[e_i] == -1 or e_links_high[e_i] < f_i + 1:
  *                 e_links_high[e_i] = f_i + 1             # <<<<<<<<<<<<<<
@@ -54141,7 +54209,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     }
     __pyx_L17:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1545
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1547
  *             if e_links_high[e_i] == -1 or e_links_high[e_i] < f_i + 1:
  *                 e_links_high[e_i] = f_i + 1
  *             i = i + 2             # <<<<<<<<<<<<<<
@@ -54151,19 +54219,19 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     __pyx_v_i = (__pyx_v_i + 2);
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1547
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1549
  *             i = i + 2
  * 
  *         als = []             # <<<<<<<<<<<<<<
  *         for x in range(matching.start,matching.end):
  *             al = (matching.arr[x]-f_sent_start,f_links_low[matching.arr[x]-f_sent_start])
  */
-  __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1547; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1549; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_v_als = __pyx_t_2;
   __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1548
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1550
  * 
  *         als = []
  *         for x in range(matching.start,matching.end):             # <<<<<<<<<<<<<<
@@ -54174,18 +54242,18 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
   for (__pyx_t_4 = __pyx_v_matching->start; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
     __pyx_v_x = __pyx_t_4;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1549
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1551
  *         als = []
  *         for x in range(matching.start,matching.end):
  *             al = (matching.arr[x]-f_sent_start,f_links_low[matching.arr[x]-f_sent_start])             # <<<<<<<<<<<<<<
  *             als.append(al)
  *         # check all source-side alignment constraints
  */
-    __pyx_t_2 = PyInt_FromLong(((__pyx_v_matching->arr[__pyx_v_x]) - __pyx_v_f_sent_start)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1549; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyInt_FromLong(((__pyx_v_matching->arr[__pyx_v_x]) - __pyx_v_f_sent_start)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1551; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_1 = PyInt_FromLong((__pyx_v_f_links_low[((__pyx_v_matching->arr[__pyx_v_x]) - __pyx_v_f_sent_start)])); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1549; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyInt_FromLong((__pyx_v_f_links_low[((__pyx_v_matching->arr[__pyx_v_x]) - __pyx_v_f_sent_start)])); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1551; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1549; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1551; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_10);
     PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_2);
     __Pyx_GIVEREF(__pyx_t_2);
@@ -54197,17 +54265,17 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     __pyx_v_al = __pyx_t_10;
     __pyx_t_10 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1550
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1552
  *         for x in range(matching.start,matching.end):
  *             al = (matching.arr[x]-f_sent_start,f_links_low[matching.arr[x]-f_sent_start])
  *             als.append(al)             # <<<<<<<<<<<<<<
  *         # check all source-side alignment constraints
  *         met_constraints = 1
  */
-    __pyx_t_11 = PyList_Append(__pyx_v_als, ((PyObject *)__pyx_v_al)); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1550; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_11 = PyList_Append(__pyx_v_als, ((PyObject *)__pyx_v_al)); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1552; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1552
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1554
  *             als.append(al)
  *         # check all source-side alignment constraints
  *         met_constraints = 1             # <<<<<<<<<<<<<<
@@ -54216,7 +54284,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_met_constraints = 1;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1553
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1555
  *         # check all source-side alignment constraints
  *         met_constraints = 1
  *         if self.require_aligned_terminal:             # <<<<<<<<<<<<<<
@@ -54225,7 +54293,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   if (__pyx_v_self->require_aligned_terminal) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1554
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1556
  *         met_constraints = 1
  *         if self.require_aligned_terminal:
  *             num_aligned_chunks = 0             # <<<<<<<<<<<<<<
@@ -54234,7 +54302,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
     __pyx_v_num_aligned_chunks = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1555
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1557
  *         if self.require_aligned_terminal:
  *             num_aligned_chunks = 0
  *             for i from 0 <= i < num_chunks:             # <<<<<<<<<<<<<<
@@ -54244,7 +54312,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     __pyx_t_3 = __pyx_v_num_chunks;
     for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_3; __pyx_v_i++) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1556
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1558
  *             num_aligned_chunks = 0
  *             for i from 0 <= i < num_chunks:
  *                 for j from 0 <= j < chunklen[i]:             # <<<<<<<<<<<<<<
@@ -54254,7 +54322,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       __pyx_t_4 = (__pyx_v_chunklen[__pyx_v_i]);
       for (__pyx_v_j = 0; __pyx_v_j < __pyx_t_4; __pyx_v_j++) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1557
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1559
  *             for i from 0 <= i < num_chunks:
  *                 for j from 0 <= j < chunklen[i]:
  *                     if f_links_low[matching.arr[matching.start+i]+j-f_sent_start] > -1:             # <<<<<<<<<<<<<<
@@ -54264,7 +54332,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         __pyx_t_9 = ((__pyx_v_f_links_low[(((__pyx_v_matching->arr[(__pyx_v_matching->start + __pyx_v_i)]) + __pyx_v_j) - __pyx_v_f_sent_start)]) > -1);
         if (__pyx_t_9) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1558
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1560
  *                 for j from 0 <= j < chunklen[i]:
  *                     if f_links_low[matching.arr[matching.start+i]+j-f_sent_start] > -1:
  *                         num_aligned_chunks = num_aligned_chunks + 1             # <<<<<<<<<<<<<<
@@ -54273,7 +54341,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
           __pyx_v_num_aligned_chunks = (__pyx_v_num_aligned_chunks + 1);
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1559
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1561
  *                     if f_links_low[matching.arr[matching.start+i]+j-f_sent_start] > -1:
  *                         num_aligned_chunks = num_aligned_chunks + 1
  *                         break             # <<<<<<<<<<<<<<
@@ -54288,7 +54356,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       __pyx_L24_break:;
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1560
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1562
  *                         num_aligned_chunks = num_aligned_chunks + 1
  *                         break
  *             if num_aligned_chunks == 0:             # <<<<<<<<<<<<<<
@@ -54298,7 +54366,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     __pyx_t_9 = (__pyx_v_num_aligned_chunks == 0);
     if (__pyx_t_9) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1561
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1563
  *                         break
  *             if num_aligned_chunks == 0:
  *                 reason_for_failure = "No aligned terminals"             # <<<<<<<<<<<<<<
@@ -54309,7 +54377,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       __Pyx_DECREF(__pyx_v_reason_for_failure);
       __pyx_v_reason_for_failure = ((PyObject *)__pyx_kp_s_126);
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1562
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1564
  *             if num_aligned_chunks == 0:
  *                 reason_for_failure = "No aligned terminals"
  *                 met_constraints = 0             # <<<<<<<<<<<<<<
@@ -54321,7 +54389,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     }
     __pyx_L26:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1563
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1565
  *                 reason_for_failure = "No aligned terminals"
  *                 met_constraints = 0
  *             if self.require_aligned_chunks and num_aligned_chunks < num_chunks:             # <<<<<<<<<<<<<<
@@ -54336,7 +54404,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     }
     if (__pyx_t_7) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1564
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1566
  *                 met_constraints = 0
  *             if self.require_aligned_chunks and num_aligned_chunks < num_chunks:
  *                 reason_for_failure = "Unaligned chunk"             # <<<<<<<<<<<<<<
@@ -54347,7 +54415,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       __Pyx_DECREF(__pyx_v_reason_for_failure);
       __pyx_v_reason_for_failure = ((PyObject *)__pyx_kp_s_127);
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1565
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1567
  *             if self.require_aligned_chunks and num_aligned_chunks < num_chunks:
  *                 reason_for_failure = "Unaligned chunk"
  *                 met_constraints = 0             # <<<<<<<<<<<<<<
@@ -54362,7 +54430,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
   }
   __pyx_L20:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1567
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1569
  *                 met_constraints = 0
  * 
  *         if met_constraints and self.tight_phrases:             # <<<<<<<<<<<<<<
@@ -54377,7 +54445,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
   }
   if (__pyx_t_9) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1569
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1571
  *         if met_constraints and self.tight_phrases:
  *             # outside edge constraints are checked later
  *             for i from 0 <= i < num_chunks-1:             # <<<<<<<<<<<<<<
@@ -54387,7 +54455,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     __pyx_t_12 = (__pyx_v_num_chunks - 1);
     for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_12; __pyx_v_i++) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1570
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1572
  *             # outside edge constraints are checked later
  *             for i from 0 <= i < num_chunks-1:
  *                 if f_links_low[matching.arr[matching.start+i]+chunklen[i]-f_sent_start] == -1:             # <<<<<<<<<<<<<<
@@ -54397,7 +54465,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       __pyx_t_9 = ((__pyx_v_f_links_low[(((__pyx_v_matching->arr[(__pyx_v_matching->start + __pyx_v_i)]) + (__pyx_v_chunklen[__pyx_v_i])) - __pyx_v_f_sent_start)]) == -1);
       if (__pyx_t_9) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1571
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1573
  *             for i from 0 <= i < num_chunks-1:
  *                 if f_links_low[matching.arr[matching.start+i]+chunklen[i]-f_sent_start] == -1:
  *                     reason_for_failure = "Gaps are not tight phrases"             # <<<<<<<<<<<<<<
@@ -54408,7 +54476,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         __Pyx_DECREF(__pyx_v_reason_for_failure);
         __pyx_v_reason_for_failure = ((PyObject *)__pyx_kp_s_128);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1572
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1574
  *                 if f_links_low[matching.arr[matching.start+i]+chunklen[i]-f_sent_start] == -1:
  *                     reason_for_failure = "Gaps are not tight phrases"
  *                     met_constraints = 0             # <<<<<<<<<<<<<<
@@ -54417,7 +54485,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         __pyx_v_met_constraints = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1573
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1575
  *                     reason_for_failure = "Gaps are not tight phrases"
  *                     met_constraints = 0
  *                     break             # <<<<<<<<<<<<<<
@@ -54429,7 +54497,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       }
       __pyx_L31:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1574
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1576
  *                     met_constraints = 0
  *                     break
  *                 if f_links_low[matching.arr[matching.start+i+1]-1-f_sent_start] == -1:             # <<<<<<<<<<<<<<
@@ -54439,7 +54507,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       __pyx_t_9 = ((__pyx_v_f_links_low[(((__pyx_v_matching->arr[((__pyx_v_matching->start + __pyx_v_i) + 1)]) - 1) - __pyx_v_f_sent_start)]) == -1);
       if (__pyx_t_9) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1575
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1577
  *                     break
  *                 if f_links_low[matching.arr[matching.start+i+1]-1-f_sent_start] == -1:
  *                     reason_for_failure = "Gaps are not tight phrases"             # <<<<<<<<<<<<<<
@@ -54450,7 +54518,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         __Pyx_DECREF(__pyx_v_reason_for_failure);
         __pyx_v_reason_for_failure = ((PyObject *)__pyx_kp_s_128);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1576
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1578
  *                 if f_links_low[matching.arr[matching.start+i+1]-1-f_sent_start] == -1:
  *                     reason_for_failure = "Gaps are not tight phrases"
  *                     met_constraints = 0             # <<<<<<<<<<<<<<
@@ -54459,7 +54527,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         __pyx_v_met_constraints = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1577
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1579
  *                     reason_for_failure = "Gaps are not tight phrases"
  *                     met_constraints = 0
  *                     break             # <<<<<<<<<<<<<<
@@ -54476,7 +54544,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
   }
   __pyx_L28:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1579
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1581
  *                     break
  * 
  *         f_low = matching.arr[matching.start] - f_sent_start             # <<<<<<<<<<<<<<
@@ -54485,7 +54553,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_f_low = ((__pyx_v_matching->arr[__pyx_v_matching->start]) - __pyx_v_f_sent_start);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1580
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1582
  * 
  *         f_low = matching.arr[matching.start] - f_sent_start
  *         f_high = matching.arr[matching.start + matching.size - 1] + chunklen[num_chunks-1] - f_sent_start             # <<<<<<<<<<<<<<
@@ -54494,7 +54562,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   __pyx_v_f_high = (((__pyx_v_matching->arr[((__pyx_v_matching->start + __pyx_v_matching->size) - 1)]) + (__pyx_v_chunklen[(__pyx_v_num_chunks - 1)])) - __pyx_v_f_sent_start);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1581
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1583
  *         f_low = matching.arr[matching.start] - f_sent_start
  *         f_high = matching.arr[matching.start + matching.size - 1] + chunklen[num_chunks-1] - f_sent_start
  *         if met_constraints:             # <<<<<<<<<<<<<<
@@ -54503,17 +54571,17 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   if (__pyx_v_met_constraints) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1583
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1585
  *         if met_constraints:
  * 
  *             if self.find_fixpoint(f_low, f_high, f_links_low, f_links_high, e_links_low, e_links_high,             # <<<<<<<<<<<<<<
  *                                 -1, -1, &e_low, &e_high, &f_back_low, &f_back_high, f_sent_len, e_sent_len,
  *                                 self.train_max_initial_size, self.train_max_initial_size,
  */
-    __pyx_t_10 = PyInt_FromLong(__pyx_v_f_high); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1583; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = PyInt_FromLong(__pyx_v_f_high); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1585; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_10);
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1587
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1589
  *                                 self.train_max_initial_size, self.train_max_initial_size,
  *                                 self.train_min_gap_size, 0,
  *                                 self.max_nonterminals - num_chunks + 1, 1, 1, 0, 0):             # <<<<<<<<<<<<<<
@@ -54524,7 +54592,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
     if (__pyx_t_3) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1588
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1590
  *                                 self.train_min_gap_size, 0,
  *                                 self.max_nonterminals - num_chunks + 1, 1, 1, 0, 0):
  *                 gap_error = 0             # <<<<<<<<<<<<<<
@@ -54533,7 +54601,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
       __pyx_v_gap_error = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1589
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1591
  *                                 self.max_nonterminals - num_chunks + 1, 1, 1, 0, 0):
  *                 gap_error = 0
  *                 num_gaps = 0             # <<<<<<<<<<<<<<
@@ -54542,7 +54610,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
       __pyx_v_num_gaps = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1591
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1593
  *                 num_gaps = 0
  * 
  *                 if f_back_low < f_low:             # <<<<<<<<<<<<<<
@@ -54552,7 +54620,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       __pyx_t_9 = (__pyx_v_f_back_low < __pyx_v_f_low);
       if (__pyx_t_9) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1592
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1594
  * 
  *                 if f_back_low < f_low:
  *                     f_gap_low[0] = f_back_low             # <<<<<<<<<<<<<<
@@ -54561,7 +54629,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         (__pyx_v_f_gap_low[0]) = __pyx_v_f_back_low;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1593
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1595
  *                 if f_back_low < f_low:
  *                     f_gap_low[0] = f_back_low
  *                     f_gap_high[0] = f_low             # <<<<<<<<<<<<<<
@@ -54570,7 +54638,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         (__pyx_v_f_gap_high[0]) = __pyx_v_f_low;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1594
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1596
  *                     f_gap_low[0] = f_back_low
  *                     f_gap_high[0] = f_low
  *                     num_gaps = 1             # <<<<<<<<<<<<<<
@@ -54579,7 +54647,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         __pyx_v_num_gaps = 1;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1595
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1597
  *                     f_gap_high[0] = f_low
  *                     num_gaps = 1
  *                     gap_start = 0             # <<<<<<<<<<<<<<
@@ -54588,7 +54656,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         __pyx_v_gap_start = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1596
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1598
  *                     num_gaps = 1
  *                     gap_start = 0
  *                     phrase_len = phrase_len+1             # <<<<<<<<<<<<<<
@@ -54597,7 +54665,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         __pyx_v_phrase_len = (__pyx_v_phrase_len + 1);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1597
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1599
  *                     gap_start = 0
  *                     phrase_len = phrase_len+1
  *                     if phrase_len > self.max_length:             # <<<<<<<<<<<<<<
@@ -54607,7 +54675,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         __pyx_t_9 = (__pyx_v_phrase_len > __pyx_v_self->max_length);
         if (__pyx_t_9) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1598
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1600
  *                     phrase_len = phrase_len+1
  *                     if phrase_len > self.max_length:
  *                         gap_error = 1             # <<<<<<<<<<<<<<
@@ -54619,7 +54687,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         }
         __pyx_L36:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1599
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1601
  *                     if phrase_len > self.max_length:
  *                         gap_error = 1
  *                     if self.tight_phrases:             # <<<<<<<<<<<<<<
@@ -54628,7 +54696,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         if (__pyx_v_self->tight_phrases) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1600
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1602
  *                         gap_error = 1
  *                     if self.tight_phrases:
  *                         if f_links_low[f_back_low] == -1 or f_links_low[f_low-1] == -1:             # <<<<<<<<<<<<<<
@@ -54644,7 +54712,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           }
           if (__pyx_t_8) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1601
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1603
  *                     if self.tight_phrases:
  *                         if f_links_low[f_back_low] == -1 or f_links_low[f_low-1] == -1:
  *                             gap_error = 1             # <<<<<<<<<<<<<<
@@ -54653,7 +54721,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             __pyx_v_gap_error = 1;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1602
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1604
  *                         if f_links_low[f_back_low] == -1 or f_links_low[f_low-1] == -1:
  *                             gap_error = 1
  *                             reason_for_failure = "Inside edges of preceding subphrase are not tight"             # <<<<<<<<<<<<<<
@@ -54673,7 +54741,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       }
       /*else*/ {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1604
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1606
  *                             reason_for_failure = "Inside edges of preceding subphrase are not tight"
  *                 else:
  *                     gap_start = 1             # <<<<<<<<<<<<<<
@@ -54682,7 +54750,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         __pyx_v_gap_start = 1;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1605
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1607
  *                 else:
  *                     gap_start = 1
  *                     if self.tight_phrases and f_links_low[f_low] == -1:             # <<<<<<<<<<<<<<
@@ -54697,7 +54765,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         }
         if (__pyx_t_9) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1608
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1610
  *                         # this is not a hard error.    we can't extract this phrase
  *                         # but we still might be able to extract a superphrase
  *                         met_constraints = 0             # <<<<<<<<<<<<<<
@@ -54711,7 +54779,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       }
       __pyx_L35:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1610
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1612
  *                         met_constraints = 0
  * 
  *                 for i from 0 <= i < matching.size - 1:             # <<<<<<<<<<<<<<
@@ -54721,7 +54789,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       __pyx_t_12 = (__pyx_v_matching->size - 1);
       for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_12; __pyx_v_i++) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1611
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1613
  * 
  *                 for i from 0 <= i < matching.size - 1:
  *                     f_gap_low[1+i] = matching.arr[matching.start+i] + chunklen[i] - f_sent_start             # <<<<<<<<<<<<<<
@@ -54730,7 +54798,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         (__pyx_v_f_gap_low[(1 + __pyx_v_i)]) = (((__pyx_v_matching->arr[(__pyx_v_matching->start + __pyx_v_i)]) + (__pyx_v_chunklen[__pyx_v_i])) - __pyx_v_f_sent_start);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1612
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1614
  *                 for i from 0 <= i < matching.size - 1:
  *                     f_gap_low[1+i] = matching.arr[matching.start+i] + chunklen[i] - f_sent_start
  *                     f_gap_high[1+i] = matching.arr[matching.start+i+1] - f_sent_start             # <<<<<<<<<<<<<<
@@ -54739,7 +54807,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         (__pyx_v_f_gap_high[(1 + __pyx_v_i)]) = ((__pyx_v_matching->arr[((__pyx_v_matching->start + __pyx_v_i) + 1)]) - __pyx_v_f_sent_start);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1613
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1615
  *                     f_gap_low[1+i] = matching.arr[matching.start+i] + chunklen[i] - f_sent_start
  *                     f_gap_high[1+i] = matching.arr[matching.start+i+1] - f_sent_start
  *                     num_gaps = num_gaps + 1             # <<<<<<<<<<<<<<
@@ -54749,7 +54817,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         __pyx_v_num_gaps = (__pyx_v_num_gaps + 1);
       }
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1615
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1617
  *                     num_gaps = num_gaps + 1
  * 
  *                 if f_high < f_back_high:             # <<<<<<<<<<<<<<
@@ -54759,7 +54827,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       __pyx_t_9 = (__pyx_v_f_high < __pyx_v_f_back_high);
       if (__pyx_t_9) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1616
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1618
  * 
  *                 if f_high < f_back_high:
  *                     f_gap_low[gap_start+num_gaps] = f_high             # <<<<<<<<<<<<<<
@@ -54768,7 +54836,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         (__pyx_v_f_gap_low[(__pyx_v_gap_start + __pyx_v_num_gaps)]) = __pyx_v_f_high;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1617
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1619
  *                 if f_high < f_back_high:
  *                     f_gap_low[gap_start+num_gaps] = f_high
  *                     f_gap_high[gap_start+num_gaps] = f_back_high             # <<<<<<<<<<<<<<
@@ -54777,7 +54845,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         (__pyx_v_f_gap_high[(__pyx_v_gap_start + __pyx_v_num_gaps)]) = __pyx_v_f_back_high;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1618
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1620
  *                     f_gap_low[gap_start+num_gaps] = f_high
  *                     f_gap_high[gap_start+num_gaps] = f_back_high
  *                     num_gaps = num_gaps + 1             # <<<<<<<<<<<<<<
@@ -54786,7 +54854,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         __pyx_v_num_gaps = (__pyx_v_num_gaps + 1);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1619
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1621
  *                     f_gap_high[gap_start+num_gaps] = f_back_high
  *                     num_gaps = num_gaps + 1
  *                     phrase_len = phrase_len+1             # <<<<<<<<<<<<<<
@@ -54795,7 +54863,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         __pyx_v_phrase_len = (__pyx_v_phrase_len + 1);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1620
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1622
  *                     num_gaps = num_gaps + 1
  *                     phrase_len = phrase_len+1
  *                     if phrase_len > self.max_length:             # <<<<<<<<<<<<<<
@@ -54805,7 +54873,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         __pyx_t_9 = (__pyx_v_phrase_len > __pyx_v_self->max_length);
         if (__pyx_t_9) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1621
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1623
  *                     phrase_len = phrase_len+1
  *                     if phrase_len > self.max_length:
  *                         gap_error = 1             # <<<<<<<<<<<<<<
@@ -54817,7 +54885,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         }
         __pyx_L43:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1622
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1624
  *                     if phrase_len > self.max_length:
  *                         gap_error = 1
  *                     if self.tight_phrases:             # <<<<<<<<<<<<<<
@@ -54826,7 +54894,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         if (__pyx_v_self->tight_phrases) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1623
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1625
  *                         gap_error = 1
  *                     if self.tight_phrases:
  *                         if f_links_low[f_back_high-1] == -1 or f_links_low[f_high] == -1:             # <<<<<<<<<<<<<<
@@ -54842,7 +54910,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           }
           if (__pyx_t_7) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1624
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1626
  *                     if self.tight_phrases:
  *                         if f_links_low[f_back_high-1] == -1 or f_links_low[f_high] == -1:
  *                             gap_error = 1             # <<<<<<<<<<<<<<
@@ -54851,7 +54919,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             __pyx_v_gap_error = 1;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1625
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1627
  *                         if f_links_low[f_back_high-1] == -1 or f_links_low[f_high] == -1:
  *                             gap_error = 1
  *                             reason_for_failure = "Inside edges of following subphrase are not tight"             # <<<<<<<<<<<<<<
@@ -54871,7 +54939,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       }
       /*else*/ {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1627
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1629
  *                             reason_for_failure = "Inside edges of following subphrase are not tight"
  *                 else:
  *                     if self.tight_phrases and f_links_low[f_high-1] == -1:             # <<<<<<<<<<<<<<
@@ -54886,7 +54954,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         }
         if (__pyx_t_9) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1628
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1630
  *                 else:
  *                     if self.tight_phrases and f_links_low[f_high-1] == -1:
  *                         met_constraints = 0             # <<<<<<<<<<<<<<
@@ -54900,7 +54968,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       }
       __pyx_L42:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1630
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1632
  *                         met_constraints = 0
  * 
  *                 if gap_error == 0:             # <<<<<<<<<<<<<<
@@ -54910,7 +54978,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       __pyx_t_9 = (__pyx_v_gap_error == 0);
       if (__pyx_t_9) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1631
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1633
  * 
  *                 if gap_error == 0:
  *                     e_word_count = e_high - e_low             # <<<<<<<<<<<<<<
@@ -54919,7 +54987,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         __pyx_v_e_word_count = (__pyx_v_e_high - __pyx_v_e_low);
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1632
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1634
  *                 if gap_error == 0:
  *                     e_word_count = e_high - e_low
  *                     for i from 0 <= i < num_gaps: # check integrity of subphrases             # <<<<<<<<<<<<<<
@@ -54929,17 +54997,17 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         __pyx_t_3 = __pyx_v_num_gaps;
         for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_3; __pyx_v_i++) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1633
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1635
  *                     e_word_count = e_high - e_low
  *                     for i from 0 <= i < num_gaps: # check integrity of subphrases
  *                         if self.find_fixpoint(f_gap_low[gap_start+i], f_gap_high[gap_start+i],             # <<<<<<<<<<<<<<
  *                                             f_links_low, f_links_high, e_links_low, e_links_high,
  *                                             -1, -1, e_gap_low+gap_start+i, e_gap_high+gap_start+i,
  */
-          __pyx_t_10 = PyInt_FromLong((__pyx_v_f_gap_high[(__pyx_v_gap_start + __pyx_v_i)])); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_10 = PyInt_FromLong((__pyx_v_f_gap_high[(__pyx_v_gap_start + __pyx_v_i)])); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_10);
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1638
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1640
  *                                             f_gap_low+gap_start+i, f_gap_high+gap_start+i,
  *                                             f_sent_len, e_sent_len,
  *                                             self.train_max_initial_size, self.train_max_initial_size,             # <<<<<<<<<<<<<<
@@ -54950,7 +55018,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
           if (__pyx_t_9) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1640
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1642
  *                                             self.train_max_initial_size, self.train_max_initial_size,
  *                                             0, 0, 0, 0, 0, 0, 0) == 0:
  *                             gap_error = 1             # <<<<<<<<<<<<<<
@@ -54959,18 +55027,18 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             __pyx_v_gap_error = 1;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1641
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1643
  *                                             0, 0, 0, 0, 0, 0, 0) == 0:
  *                             gap_error = 1
  *                             reason_for_failure = "Subphrase [%d, %d] failed integrity check" % (f_gap_low[gap_start+i], f_gap_high[gap_start+i])             # <<<<<<<<<<<<<<
  *                             break
  * 
  */
-            __pyx_t_10 = PyInt_FromLong((__pyx_v_f_gap_low[(__pyx_v_gap_start + __pyx_v_i)])); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_10 = PyInt_FromLong((__pyx_v_f_gap_low[(__pyx_v_gap_start + __pyx_v_i)])); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1643; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_10);
-            __pyx_t_1 = PyInt_FromLong((__pyx_v_f_gap_high[(__pyx_v_gap_start + __pyx_v_i)])); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_1 = PyInt_FromLong((__pyx_v_f_gap_high[(__pyx_v_gap_start + __pyx_v_i)])); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1643; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_1);
-            __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1643; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_2);
             PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_10);
             __Pyx_GIVEREF(__pyx_t_10);
@@ -54978,14 +55046,14 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             __Pyx_GIVEREF(__pyx_t_1);
             __pyx_t_10 = 0;
             __pyx_t_1 = 0;
-            __pyx_t_1 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_131), ((PyObject *)__pyx_t_2)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_1 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_131), ((PyObject *)__pyx_t_2)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1643; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(((PyObject *)__pyx_t_1));
             __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
             __Pyx_DECREF(__pyx_v_reason_for_failure);
             __pyx_v_reason_for_failure = ((PyObject *)__pyx_t_1);
             __pyx_t_1 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1642
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1644
  *                             gap_error = 1
  *                             reason_for_failure = "Subphrase [%d, %d] failed integrity check" % (f_gap_low[gap_start+i], f_gap_high[gap_start+i])
  *                             break             # <<<<<<<<<<<<<<
@@ -55002,7 +55070,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       }
       __pyx_L47:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1644
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1646
  *                             break
  * 
  *                 if gap_error == 0:             # <<<<<<<<<<<<<<
@@ -55012,7 +55080,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
       __pyx_t_9 = (__pyx_v_gap_error == 0);
       if (__pyx_t_9) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1645
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1647
  * 
  *                 if gap_error == 0:
  *                     i = 1             # <<<<<<<<<<<<<<
@@ -55021,21 +55089,21 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         __pyx_v_i = 1;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1646
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1648
  *                 if gap_error == 0:
  *                     i = 1
  *                     self.findexes.reset()             # <<<<<<<<<<<<<<
  *                     if f_back_low < f_low:
  *                         fphr_arr._append(sym_setindex(self.category, i))
  */
-        __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__reset); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1646; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__reset); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1648; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
-        __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1646; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1648; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1647
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1649
  *                     i = 1
  *                     self.findexes.reset()
  *                     if f_back_low < f_low:             # <<<<<<<<<<<<<<
@@ -55045,7 +55113,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         __pyx_t_9 = (__pyx_v_f_back_low < __pyx_v_f_low);
         if (__pyx_t_9) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1648
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1650
  *                     self.findexes.reset()
  *                     if f_back_low < f_low:
  *                         fphr_arr._append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
@@ -55054,7 +55122,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
           ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_fphr_arr->__pyx_vtab)->_append(__pyx_v_fphr_arr, __pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i));
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1649
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1651
  *                     if f_back_low < f_low:
  *                         fphr_arr._append(sym_setindex(self.category, i))
  *                         i = i+1             # <<<<<<<<<<<<<<
@@ -55063,16 +55131,16 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
           __pyx_v_i = (__pyx_v_i + 1);
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1650
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1652
  *                         fphr_arr._append(sym_setindex(self.category, i))
  *                         i = i+1
  *                         self.findexes.append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
  *                     self.findexes.extend(self.findexes1)
  *                     for j from 0 <= j < phrase.n:
  */
-          __pyx_t_2 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1650; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_2 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_2);
-          __pyx_t_1 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1650; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_1 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_1);
           __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
           __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -55080,27 +55148,27 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         }
         __pyx_L52:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1651
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1653
  *                         i = i+1
  *                         self.findexes.append(sym_setindex(self.category, i))
  *                     self.findexes.extend(self.findexes1)             # <<<<<<<<<<<<<<
  *                     for j from 0 <= j < phrase.n:
  *                         if sym_isvar(phrase.syms[j]):
  */
-        __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__extend); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1651; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__extend); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1653; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
-        __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1651; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1653; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_INCREF(((PyObject *)__pyx_v_self->findexes1));
         PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_v_self->findexes1));
         __Pyx_GIVEREF(((PyObject *)__pyx_v_self->findexes1));
-        __pyx_t_10 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1651; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_10 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1653; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_10);
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
         __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1652
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1654
  *                         self.findexes.append(sym_setindex(self.category, i))
  *                     self.findexes.extend(self.findexes1)
  *                     for j from 0 <= j < phrase.n:             # <<<<<<<<<<<<<<
@@ -55110,7 +55178,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         __pyx_t_3 = __pyx_v_phrase->n;
         for (__pyx_v_j = 0; __pyx_v_j < __pyx_t_3; __pyx_v_j++) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1653
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1655
  *                     self.findexes.extend(self.findexes1)
  *                     for j from 0 <= j < phrase.n:
  *                         if sym_isvar(phrase.syms[j]):             # <<<<<<<<<<<<<<
@@ -55120,7 +55188,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           __pyx_t_4 = __pyx_f_3_sa_sym_isvar((__pyx_v_phrase->syms[__pyx_v_j]));
           if (__pyx_t_4) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1654
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1656
  *                     for j from 0 <= j < phrase.n:
  *                         if sym_isvar(phrase.syms[j]):
  *                             fphr_arr._append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
@@ -55129,7 +55197,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_fphr_arr->__pyx_vtab)->_append(__pyx_v_fphr_arr, __pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i));
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1655
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1657
  *                         if sym_isvar(phrase.syms[j]):
  *                             fphr_arr._append(sym_setindex(self.category, i))
  *                             i = i + 1             # <<<<<<<<<<<<<<
@@ -55141,7 +55209,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           }
           /*else*/ {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1657
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1659
  *                             i = i + 1
  *                         else:
  *                             fphr_arr._append(phrase.syms[j])             # <<<<<<<<<<<<<<
@@ -55153,7 +55221,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           __pyx_L55:;
         }
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1658
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1660
  *                         else:
  *                             fphr_arr._append(phrase.syms[j])
  *                     if f_back_high > f_high:             # <<<<<<<<<<<<<<
@@ -55163,7 +55231,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         __pyx_t_9 = (__pyx_v_f_back_high > __pyx_v_f_high);
         if (__pyx_t_9) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1659
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1661
  *                             fphr_arr._append(phrase.syms[j])
  *                     if f_back_high > f_high:
  *                         fphr_arr._append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
@@ -55172,16 +55240,16 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
           ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_fphr_arr->__pyx_vtab)->_append(__pyx_v_fphr_arr, __pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i));
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1660
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1662
  *                     if f_back_high > f_high:
  *                         fphr_arr._append(sym_setindex(self.category, i))
  *                         self.findexes.append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
  * 
  *                     fphr = Phrase(fphr_arr)
  */
-          __pyx_t_10 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_10 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1662; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_10);
-          __pyx_t_2 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_10); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_2 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_10); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1662; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
           __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -55189,25 +55257,25 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         }
         __pyx_L56:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1662
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1664
  *                         self.findexes.append(sym_setindex(self.category, i))
  * 
  *                     fphr = Phrase(fphr_arr)             # <<<<<<<<<<<<<<
  *                     if met_constraints:
  *                         phrase_list = self.extract_phrases(e_low, e_high, e_gap_low + gap_start, e_gap_high + gap_start, e_links_low, num_gaps,
  */
-        __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1662; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1664; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_INCREF(((PyObject *)__pyx_v_fphr_arr));
         PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_v_fphr_arr));
         __Pyx_GIVEREF(((PyObject *)__pyx_v_fphr_arr));
-        __pyx_t_10 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1662; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_10 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1664; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_10);
         __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
         __pyx_v_fphr = ((struct __pyx_obj_3_sa_Phrase *)__pyx_t_10);
         __pyx_t_10 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1663
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1665
  * 
  *                     fphr = Phrase(fphr_arr)
  *                     if met_constraints:             # <<<<<<<<<<<<<<
@@ -55216,47 +55284,47 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
         if (__pyx_v_met_constraints) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1666
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1668
  *                         phrase_list = self.extract_phrases(e_low, e_high, e_gap_low + gap_start, e_gap_high + gap_start, e_links_low, num_gaps,
  *                                             f_back_low, f_back_high, f_gap_low + gap_start, f_gap_high + gap_start, f_links_low,
  *                                             matching.sent_id, e_sent_len, e_sent_start)             # <<<<<<<<<<<<<<
  *                         if len(phrase_list) > 0:
  *                             pair_count = 1.0 / len(phrase_list)
  */
-          __pyx_t_10 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->extract_phrases(__pyx_v_self, __pyx_v_e_low, __pyx_v_e_high, (__pyx_v_e_gap_low + __pyx_v_gap_start), (__pyx_v_e_gap_high + __pyx_v_gap_start), __pyx_v_e_links_low, __pyx_v_num_gaps, __pyx_v_f_back_low, __pyx_v_f_back_high, (__pyx_v_f_gap_low + __pyx_v_gap_start), (__pyx_v_f_gap_high + __pyx_v_gap_start), __pyx_v_f_links_low, __pyx_v_matching->sent_id, __pyx_v_e_sent_len, __pyx_v_e_sent_start); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1664; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_10 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->extract_phrases(__pyx_v_self, __pyx_v_e_low, __pyx_v_e_high, (__pyx_v_e_gap_low + __pyx_v_gap_start), (__pyx_v_e_gap_high + __pyx_v_gap_start), __pyx_v_e_links_low, __pyx_v_num_gaps, __pyx_v_f_back_low, __pyx_v_f_back_high, (__pyx_v_f_gap_low + __pyx_v_gap_start), (__pyx_v_f_gap_high + __pyx_v_gap_start), __pyx_v_f_links_low, __pyx_v_matching->sent_id, __pyx_v_e_sent_len, __pyx_v_e_sent_start); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1666; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __Pyx_GOTREF(__pyx_t_10);
           __pyx_v_phrase_list = __pyx_t_10;
           __pyx_t_10 = 0;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1667
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1669
  *                                             f_back_low, f_back_high, f_gap_low + gap_start, f_gap_high + gap_start, f_links_low,
  *                                             matching.sent_id, e_sent_len, e_sent_start)
  *                         if len(phrase_list) > 0:             # <<<<<<<<<<<<<<
  *                             pair_count = 1.0 / len(phrase_list)
  *                         else:
  */
-          __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1667; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1669; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           __pyx_t_9 = (__pyx_t_13 > 0);
           if (__pyx_t_9) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1668
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1670
  *                                             matching.sent_id, e_sent_len, e_sent_start)
  *                         if len(phrase_list) > 0:
  *                             pair_count = 1.0 / len(phrase_list)             # <<<<<<<<<<<<<<
  *                         else:
  *                             pair_count = 0
  */
-            __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1668; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1670; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             if (unlikely(__pyx_t_13 == 0)) {
               PyErr_Format(PyExc_ZeroDivisionError, "float division");
-              {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1668; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1670; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             }
             __pyx_v_pair_count = (1.0 / __pyx_t_13);
             goto __pyx_L58;
           }
           /*else*/ {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1670
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1672
  *                             pair_count = 1.0 / len(phrase_list)
  *                         else:
  *                             pair_count = 0             # <<<<<<<<<<<<<<
@@ -55265,22 +55333,22 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             __pyx_v_pair_count = 0.0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1671
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1673
  *                         else:
  *                             pair_count = 0
  *                             reason_for_failure = "Didn't extract anything from [%d, %d] -> [%d, %d]" % (f_back_low, f_back_high, e_low, e_high)             # <<<<<<<<<<<<<<
  *                         for (phrase2,eindexes) in phrase_list:
  *                             als1 = self.create_alignments(sent_links,num_links,self.findexes,eindexes)
  */
-            __pyx_t_10 = PyInt_FromLong(__pyx_v_f_back_low); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1671; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_10 = PyInt_FromLong(__pyx_v_f_back_low); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1673; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_10);
-            __pyx_t_2 = PyInt_FromLong(__pyx_v_f_back_high); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1671; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_2 = PyInt_FromLong(__pyx_v_f_back_high); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1673; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_2);
-            __pyx_t_1 = PyInt_FromLong(__pyx_v_e_low); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1671; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_1 = PyInt_FromLong(__pyx_v_e_low); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1673; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_1);
-            __pyx_t_14 = PyInt_FromLong(__pyx_v_e_high); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1671; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_14 = PyInt_FromLong(__pyx_v_e_high); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1673; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_14);
-            __pyx_t_15 = PyTuple_New(4); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1671; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_15 = PyTuple_New(4); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1673; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_15);
             PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_t_10);
             __Pyx_GIVEREF(__pyx_t_10);
@@ -55294,7 +55362,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             __pyx_t_2 = 0;
             __pyx_t_1 = 0;
             __pyx_t_14 = 0;
-            __pyx_t_14 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_132), ((PyObject *)__pyx_t_15)); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1671; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_14 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_132), ((PyObject *)__pyx_t_15)); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1673; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(((PyObject *)__pyx_t_14));
             __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
             __Pyx_DECREF(__pyx_v_reason_for_failure);
@@ -55303,7 +55371,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           }
           __pyx_L58:;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1672
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1674
  *                             pair_count = 0
  *                             reason_for_failure = "Didn't extract anything from [%d, %d] -> [%d, %d]" % (f_back_low, f_back_high, e_low, e_high)
  *                         for (phrase2,eindexes) in phrase_list:             # <<<<<<<<<<<<<<
@@ -55314,7 +55382,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             __pyx_t_14 = __pyx_v_phrase_list; __Pyx_INCREF(__pyx_t_14); __pyx_t_13 = 0;
             __pyx_t_16 = NULL;
           } else {
-            __pyx_t_13 = -1; __pyx_t_14 = PyObject_GetIter(__pyx_v_phrase_list); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1672; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_13 = -1; __pyx_t_14 = PyObject_GetIter(__pyx_v_phrase_list); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_14);
             __pyx_t_16 = Py_TYPE(__pyx_t_14)->tp_iternext;
           }
@@ -55322,23 +55390,23 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             if (!__pyx_t_16 && PyList_CheckExact(__pyx_t_14)) {
               if (__pyx_t_13 >= PyList_GET_SIZE(__pyx_t_14)) break;
               #if CYTHON_COMPILING_IN_CPYTHON
-              __pyx_t_15 = PyList_GET_ITEM(__pyx_t_14, __pyx_t_13); __Pyx_INCREF(__pyx_t_15); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1672; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = PyList_GET_ITEM(__pyx_t_14, __pyx_t_13); __Pyx_INCREF(__pyx_t_15); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               #else
-              __pyx_t_15 = PySequence_ITEM(__pyx_t_14, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1672; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = PySequence_ITEM(__pyx_t_14, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               #endif
             } else if (!__pyx_t_16 && PyTuple_CheckExact(__pyx_t_14)) {
               if (__pyx_t_13 >= PyTuple_GET_SIZE(__pyx_t_14)) break;
               #if CYTHON_COMPILING_IN_CPYTHON
-              __pyx_t_15 = PyTuple_GET_ITEM(__pyx_t_14, __pyx_t_13); __Pyx_INCREF(__pyx_t_15); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1672; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = PyTuple_GET_ITEM(__pyx_t_14, __pyx_t_13); __Pyx_INCREF(__pyx_t_15); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               #else
-              __pyx_t_15 = PySequence_ITEM(__pyx_t_14, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1672; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = PySequence_ITEM(__pyx_t_14, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               #endif
             } else {
               __pyx_t_15 = __pyx_t_16(__pyx_t_14);
               if (unlikely(!__pyx_t_15)) {
                 if (PyErr_Occurred()) {
                   if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-                  else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1672; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 }
                 break;
               }
@@ -55354,7 +55422,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               if (unlikely(size != 2)) {
                 if (size > 2) __Pyx_RaiseTooManyValuesError(2);
                 else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-                {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1672; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               }
               #if CYTHON_COMPILING_IN_CPYTHON
               if (likely(PyTuple_CheckExact(sequence))) {
@@ -55367,14 +55435,14 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               __Pyx_INCREF(__pyx_t_1);
               __Pyx_INCREF(__pyx_t_2);
               #else
-              __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1672; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-              __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1672; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               #endif
               __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
             } else
             {
               Py_ssize_t index = -1;
-              __pyx_t_10 = PyObject_GetIter(__pyx_t_15); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1672; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_10 = PyObject_GetIter(__pyx_t_15); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_10);
               __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
               __pyx_t_17 = Py_TYPE(__pyx_t_10)->tp_iternext;
@@ -55382,7 +55450,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               __Pyx_GOTREF(__pyx_t_1);
               index = 1; __pyx_t_2 = __pyx_t_17(__pyx_t_10); if (unlikely(!__pyx_t_2)) goto __pyx_L61_unpacking_failed;
               __Pyx_GOTREF(__pyx_t_2);
-              if (__Pyx_IternextUnpackEndCheck(__pyx_t_17(__pyx_t_10), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1672; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              if (__Pyx_IternextUnpackEndCheck(__pyx_t_17(__pyx_t_10), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __pyx_t_17 = NULL;
               __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
               goto __pyx_L62_unpacking_done;
@@ -55390,7 +55458,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
               __pyx_t_17 = NULL;
               if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-              {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1672; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __pyx_L62_unpacking_done:;
             }
             __Pyx_XDECREF(__pyx_v_phrase2);
@@ -55400,7 +55468,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             __pyx_v_eindexes = __pyx_t_2;
             __pyx_t_2 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1673
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1675
  *                             reason_for_failure = "Didn't extract anything from [%d, %d] -> [%d, %d]" % (f_back_low, f_back_high, e_low, e_high)
  *                         for (phrase2,eindexes) in phrase_list:
  *                             als1 = self.create_alignments(sent_links,num_links,self.findexes,eindexes)             # <<<<<<<<<<<<<<
@@ -55409,31 +55477,31 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             __pyx_t_15 = ((PyObject *)__pyx_v_self->findexes);
             __Pyx_INCREF(__pyx_t_15);
-            __pyx_t_2 = ((PyObject *)((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->create_alignments(__pyx_v_self, __pyx_v_sent_links, __pyx_v_num_links, __pyx_t_15, __pyx_v_eindexes)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1673; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_2 = ((PyObject *)((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->create_alignments(__pyx_v_self, __pyx_v_sent_links, __pyx_v_num_links, __pyx_t_15, __pyx_v_eindexes)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1675; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_2);
             __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
             __Pyx_XDECREF(((PyObject *)__pyx_v_als1));
             __pyx_v_als1 = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_2);
             __pyx_t_2 = 0;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1674
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1676
  *                         for (phrase2,eindexes) in phrase_list:
  *                             als1 = self.create_alignments(sent_links,num_links,self.findexes,eindexes)
  *                             extracts.append((fphr, phrase2, pair_count, tuple(als1)))             # <<<<<<<<<<<<<<
  * 
  *                     if (num_gaps < self.max_nonterminals and
  */
-            __pyx_t_2 = PyFloat_FromDouble(__pyx_v_pair_count); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_2 = PyFloat_FromDouble(__pyx_v_pair_count); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1676; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_2);
-            __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1676; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_15);
             __Pyx_INCREF(((PyObject *)__pyx_v_als1));
             PyTuple_SET_ITEM(__pyx_t_15, 0, ((PyObject *)__pyx_v_als1));
             __Pyx_GIVEREF(((PyObject *)__pyx_v_als1));
-            __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1676; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_1);
             __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
-            __pyx_t_15 = PyTuple_New(4); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_15 = PyTuple_New(4); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1676; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_15);
             __Pyx_INCREF(((PyObject *)__pyx_v_fphr));
             PyTuple_SET_ITEM(__pyx_t_15, 0, ((PyObject *)__pyx_v_fphr));
@@ -55447,7 +55515,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             __Pyx_GIVEREF(__pyx_t_1);
             __pyx_t_2 = 0;
             __pyx_t_1 = 0;
-            __pyx_t_1 = __Pyx_PyObject_Append(__pyx_v_extracts, ((PyObject *)__pyx_t_15)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1674; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            __pyx_t_1 = __Pyx_PyObject_Append(__pyx_v_extracts, ((PyObject *)__pyx_t_15)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1676; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             __Pyx_GOTREF(__pyx_t_1);
             __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
             __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -55457,7 +55525,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         }
         __pyx_L57:;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1676
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1678
  *                             extracts.append((fphr, phrase2, pair_count, tuple(als1)))
  * 
  *                     if (num_gaps < self.max_nonterminals and             # <<<<<<<<<<<<<<
@@ -55467,7 +55535,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         __pyx_t_9 = (__pyx_v_num_gaps < __pyx_v_self->max_nonterminals);
         if (__pyx_t_9) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1677
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1679
  * 
  *                     if (num_gaps < self.max_nonterminals and
  *                         phrase_len < self.max_length and             # <<<<<<<<<<<<<<
@@ -55477,7 +55545,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           __pyx_t_7 = (__pyx_v_phrase_len < __pyx_v_self->max_length);
           if (__pyx_t_7) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1678
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1680
  *                     if (num_gaps < self.max_nonterminals and
  *                         phrase_len < self.max_length and
  *                         f_back_high - f_back_low + self.train_min_gap_size <= self.train_max_initial_size):             # <<<<<<<<<<<<<<
@@ -55495,7 +55563,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
         }
         if (__pyx_t_7) {
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1679
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1681
  *                         phrase_len < self.max_length and
  *                         f_back_high - f_back_low + self.train_min_gap_size <= self.train_max_initial_size):
  *                         if (f_back_low == f_low and             # <<<<<<<<<<<<<<
@@ -55505,7 +55573,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           __pyx_t_7 = (__pyx_v_f_back_low == __pyx_v_f_low);
           if (__pyx_t_7) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1680
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1682
  *                         f_back_high - f_back_low + self.train_min_gap_size <= self.train_max_initial_size):
  *                         if (f_back_low == f_low and
  *                                 f_low >= self.train_min_gap_size and             # <<<<<<<<<<<<<<
@@ -55515,7 +55583,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             __pyx_t_9 = (__pyx_v_f_low >= __pyx_v_self->train_min_gap_size);
             if (__pyx_t_9) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1681
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1683
  *                         if (f_back_low == f_low and
  *                                 f_low >= self.train_min_gap_size and
  *                                 ((not self.tight_phrases) or (f_links_low[f_low-1] != -1 and f_links_low[f_back_high-1] != -1))):             # <<<<<<<<<<<<<<
@@ -55545,7 +55613,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           }
           if (__pyx_t_9) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1682
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1684
  *                                 f_low >= self.train_min_gap_size and
  *                                 ((not self.tight_phrases) or (f_links_low[f_low-1] != -1 and f_links_low[f_back_high-1] != -1))):
  *                             f_x_low = f_low-self.train_min_gap_size             # <<<<<<<<<<<<<<
@@ -55554,7 +55622,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             __pyx_v_f_x_low = (__pyx_v_f_low - __pyx_v_self->train_min_gap_size);
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1683
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1685
  *                                 ((not self.tight_phrases) or (f_links_low[f_low-1] != -1 and f_links_low[f_back_high-1] != -1))):
  *                             f_x_low = f_low-self.train_min_gap_size
  *                             met_constraints = 1             # <<<<<<<<<<<<<<
@@ -55563,7 +55631,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             __pyx_v_met_constraints = 1;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1684
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1686
  *                             f_x_low = f_low-self.train_min_gap_size
  *                             met_constraints = 1
  *                             if self.tight_phrases:             # <<<<<<<<<<<<<<
@@ -55572,7 +55640,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             if (__pyx_v_self->tight_phrases) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1685
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1687
  *                             met_constraints = 1
  *                             if self.tight_phrases:
  *                                 while f_x_low >= 0 and f_links_low[f_x_low] == -1:             # <<<<<<<<<<<<<<
@@ -55589,7 +55657,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 }
                 if (!__pyx_t_18) break;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1686
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1688
  *                             if self.tight_phrases:
  *                                 while f_x_low >= 0 and f_links_low[f_x_low] == -1:
  *                                     f_x_low = f_x_low - 1             # <<<<<<<<<<<<<<
@@ -55602,7 +55670,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             }
             __pyx_L65:;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1687
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1689
  *                                 while f_x_low >= 0 and f_links_low[f_x_low] == -1:
  *                                     f_x_low = f_x_low - 1
  *                             if f_x_low < 0 or f_back_high - f_x_low > self.train_max_initial_size:             # <<<<<<<<<<<<<<
@@ -55618,7 +55686,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             }
             if (__pyx_t_7) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1688
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1690
  *                                     f_x_low = f_x_low - 1
  *                             if f_x_low < 0 or f_back_high - f_x_low > self.train_max_initial_size:
  *                                 met_constraints = 0             # <<<<<<<<<<<<<<
@@ -55630,7 +55698,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             }
             __pyx_L68:;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1690
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1692
  *                                 met_constraints = 0
  * 
  *                             if (met_constraints and             # <<<<<<<<<<<<<<
@@ -55639,17 +55707,17 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             if (__pyx_v_met_constraints) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1691
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1693
  * 
  *                             if (met_constraints and
  *                                 self.find_fixpoint(f_x_low, f_back_high,             # <<<<<<<<<<<<<<
  *                                             f_links_low, f_links_high, e_links_low, e_links_high,
  *                                             e_low, e_high, &e_x_low, &e_x_high, &f_x_low, &f_x_high,
  */
-              __pyx_t_14 = PyInt_FromLong(__pyx_v_f_back_high); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1691; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_14 = PyInt_FromLong(__pyx_v_f_back_high); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1693; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_14);
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1695
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1697
  *                                             e_low, e_high, &e_x_low, &e_x_high, &f_x_low, &f_x_high,
  *                                             f_sent_len, e_sent_len,
  *                                             self.train_max_initial_size, self.train_max_initial_size,             # <<<<<<<<<<<<<<
@@ -55659,7 +55727,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               if (((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->find_fixpoint(__pyx_v_self, __pyx_v_f_x_low, __pyx_t_14, __pyx_v_f_links_low, __pyx_v_f_links_high, __pyx_v_e_links_low, __pyx_v_e_links_high, __pyx_v_e_low, __pyx_v_e_high, (&__pyx_v_e_x_low), (&__pyx_v_e_x_high), (&__pyx_v_f_x_low), (&__pyx_v_f_x_high), __pyx_v_f_sent_len, __pyx_v_e_sent_len, __pyx_v_self->train_max_initial_size, __pyx_v_self->train_max_initial_size, 1, 1, 1, 1, 0, 1, 0)) {
                 __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1697
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1699
  *                                             self.train_max_initial_size, self.train_max_initial_size,
  *                                             1, 1, 1, 1, 0, 1, 0) and
  *                                 ((not self.tight_phrases) or f_links_low[f_x_low] != -1) and             # <<<<<<<<<<<<<<
@@ -55675,17 +55743,17 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 }
                 if (__pyx_t_9) {
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1698
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1700
  *                                             1, 1, 1, 1, 0, 1, 0) and
  *                                 ((not self.tight_phrases) or f_links_low[f_x_low] != -1) and
  *                                 self.find_fixpoint(f_x_low, f_low,    # check integrity of new subphrase             # <<<<<<<<<<<<<<
  *                                             f_links_low, f_links_high, e_links_low, e_links_high,
  *                                             -1, -1, e_gap_low, e_gap_high, f_gap_low, f_gap_high,
  */
-                  __pyx_t_1 = PyInt_FromLong(__pyx_v_f_low); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1698; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_1 = PyInt_FromLong(__pyx_v_f_low); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1700; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __Pyx_GOTREF(__pyx_t_1);
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1702
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1704
  *                                             -1, -1, e_gap_low, e_gap_high, f_gap_low, f_gap_high,
  *                                             f_sent_len, e_sent_len,
  *                                             self.train_max_initial_size, self.train_max_initial_size,             # <<<<<<<<<<<<<<
@@ -55708,7 +55776,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             }
             if (__pyx_t_7) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1704
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1706
  *                                             self.train_max_initial_size, self.train_max_initial_size,
  *                                             0, 0, 0, 0, 0, 0, 0)):
  *                                 fphr_arr._clear()             # <<<<<<<<<<<<<<
@@ -55717,7 +55785,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
               ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_fphr_arr->__pyx_vtab)->_clear(__pyx_v_fphr_arr);
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1705
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1707
  *                                             0, 0, 0, 0, 0, 0, 0)):
  *                                 fphr_arr._clear()
  *                                 i = 1             # <<<<<<<<<<<<<<
@@ -55726,35 +55794,35 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
               __pyx_v_i = 1;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1706
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1708
  *                                 fphr_arr._clear()
  *                                 i = 1
  *                                 self.findexes.reset()             # <<<<<<<<<<<<<<
  *                                 self.findexes.append(sym_setindex(self.category, i))
  *                                 fphr_arr._append(sym_setindex(self.category, i))
  */
-              __pyx_t_14 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__reset); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1706; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_14 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__reset); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1708; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_14);
-              __pyx_t_1 = PyObject_Call(__pyx_t_14, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1706; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_1 = PyObject_Call(__pyx_t_14, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1708; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_1);
               __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
               __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1707
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1709
  *                                 i = 1
  *                                 self.findexes.reset()
  *                                 self.findexes.append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
  *                                 fphr_arr._append(sym_setindex(self.category, i))
  *                                 i = i+1
  */
-              __pyx_t_1 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1707; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_1 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1709; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_1);
-              __pyx_t_14 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1707; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_14 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1709; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_14);
               __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
               __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1708
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1710
  *                                 self.findexes.reset()
  *                                 self.findexes.append(sym_setindex(self.category, i))
  *                                 fphr_arr._append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
@@ -55763,7 +55831,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
               ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_fphr_arr->__pyx_vtab)->_append(__pyx_v_fphr_arr, __pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i));
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1709
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1711
  *                                 self.findexes.append(sym_setindex(self.category, i))
  *                                 fphr_arr._append(sym_setindex(self.category, i))
  *                                 i = i+1             # <<<<<<<<<<<<<<
@@ -55772,27 +55840,27 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
               __pyx_v_i = (__pyx_v_i + 1);
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1710
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1712
  *                                 fphr_arr._append(sym_setindex(self.category, i))
  *                                 i = i+1
  *                                 self.findexes.extend(self.findexes1)             # <<<<<<<<<<<<<<
  *                                 for j from 0 <= j < phrase.n:
  *                                     if sym_isvar(phrase.syms[j]):
  */
-              __pyx_t_14 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__extend); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1710; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_14 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__extend); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1712; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_14);
-              __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1710; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1712; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_1);
               __Pyx_INCREF(((PyObject *)__pyx_v_self->findexes1));
               PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_v_self->findexes1));
               __Pyx_GIVEREF(((PyObject *)__pyx_v_self->findexes1));
-              __pyx_t_15 = PyObject_Call(__pyx_t_14, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1710; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = PyObject_Call(__pyx_t_14, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1712; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_15);
               __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
               __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
               __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1711
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1713
  *                                 i = i+1
  *                                 self.findexes.extend(self.findexes1)
  *                                 for j from 0 <= j < phrase.n:             # <<<<<<<<<<<<<<
@@ -55802,7 +55870,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               __pyx_t_3 = __pyx_v_phrase->n;
               for (__pyx_v_j = 0; __pyx_v_j < __pyx_t_3; __pyx_v_j++) {
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1712
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1714
  *                                 self.findexes.extend(self.findexes1)
  *                                 for j from 0 <= j < phrase.n:
  *                                     if sym_isvar(phrase.syms[j]):             # <<<<<<<<<<<<<<
@@ -55812,7 +55880,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __pyx_t_4 = __pyx_f_3_sa_sym_isvar((__pyx_v_phrase->syms[__pyx_v_j]));
                 if (__pyx_t_4) {
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1713
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1715
  *                                 for j from 0 <= j < phrase.n:
  *                                     if sym_isvar(phrase.syms[j]):
  *                                         fphr_arr._append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
@@ -55821,7 +55889,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
                   ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_fphr_arr->__pyx_vtab)->_append(__pyx_v_fphr_arr, __pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i));
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1714
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1716
  *                                     if sym_isvar(phrase.syms[j]):
  *                                         fphr_arr._append(sym_setindex(self.category, i))
  *                                         i = i + 1             # <<<<<<<<<<<<<<
@@ -55833,7 +55901,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 }
                 /*else*/ {
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1716
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1718
  *                                         i = i + 1
  *                                     else:
  *                                         fphr_arr._append(phrase.syms[j])             # <<<<<<<<<<<<<<
@@ -55845,7 +55913,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __pyx_L72:;
               }
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1717
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1719
  *                                     else:
  *                                         fphr_arr._append(phrase.syms[j])
  *                                 if f_back_high > f_high:             # <<<<<<<<<<<<<<
@@ -55855,7 +55923,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               __pyx_t_7 = (__pyx_v_f_back_high > __pyx_v_f_high);
               if (__pyx_t_7) {
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1718
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1720
  *                                         fphr_arr._append(phrase.syms[j])
  *                                 if f_back_high > f_high:
  *                                     fphr_arr._append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
@@ -55864,16 +55932,16 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
                 ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_fphr_arr->__pyx_vtab)->_append(__pyx_v_fphr_arr, __pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i));
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1719
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1721
  *                                 if f_back_high > f_high:
  *                                     fphr_arr._append(sym_setindex(self.category, i))
  *                                     self.findexes.append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
  *                                 fphr = Phrase(fphr_arr)
  *                                 phrase_list = self.extract_phrases(e_x_low, e_x_high, e_gap_low, e_gap_high, e_links_low, num_gaps+1,
  */
-                __pyx_t_15 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1721; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_15);
-                __pyx_t_1 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_15); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_1 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_15); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1721; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_1);
                 __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
                 __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -55881,67 +55949,67 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               }
               __pyx_L73:;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1720
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1722
  *                                     fphr_arr._append(sym_setindex(self.category, i))
  *                                     self.findexes.append(sym_setindex(self.category, i))
  *                                 fphr = Phrase(fphr_arr)             # <<<<<<<<<<<<<<
  *                                 phrase_list = self.extract_phrases(e_x_low, e_x_high, e_gap_low, e_gap_high, e_links_low, num_gaps+1,
  *                                                     f_x_low, f_x_high, f_gap_low, f_gap_high, f_links_low, matching.sent_id,
  */
-              __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1720; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1722; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_1);
               __Pyx_INCREF(((PyObject *)__pyx_v_fphr_arr));
               PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_v_fphr_arr));
               __Pyx_GIVEREF(((PyObject *)__pyx_v_fphr_arr));
-              __pyx_t_15 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1720; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1722; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_15);
               __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
               __Pyx_DECREF(((PyObject *)__pyx_v_fphr));
               __pyx_v_fphr = ((struct __pyx_obj_3_sa_Phrase *)__pyx_t_15);
               __pyx_t_15 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1723
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1725
  *                                 phrase_list = self.extract_phrases(e_x_low, e_x_high, e_gap_low, e_gap_high, e_links_low, num_gaps+1,
  *                                                     f_x_low, f_x_high, f_gap_low, f_gap_high, f_links_low, matching.sent_id,
  *                                                     e_sent_len, e_sent_start)             # <<<<<<<<<<<<<<
  *                                 if len(phrase_list) > 0:
  *                                     pair_count = 1.0 / len(phrase_list)
  */
-              __pyx_t_15 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->extract_phrases(__pyx_v_self, __pyx_v_e_x_low, __pyx_v_e_x_high, __pyx_v_e_gap_low, __pyx_v_e_gap_high, __pyx_v_e_links_low, (__pyx_v_num_gaps + 1), __pyx_v_f_x_low, __pyx_v_f_x_high, __pyx_v_f_gap_low, __pyx_v_f_gap_high, __pyx_v_f_links_low, __pyx_v_matching->sent_id, __pyx_v_e_sent_len, __pyx_v_e_sent_start); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1721; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->extract_phrases(__pyx_v_self, __pyx_v_e_x_low, __pyx_v_e_x_high, __pyx_v_e_gap_low, __pyx_v_e_gap_high, __pyx_v_e_links_low, (__pyx_v_num_gaps + 1), __pyx_v_f_x_low, __pyx_v_f_x_high, __pyx_v_f_gap_low, __pyx_v_f_gap_high, __pyx_v_f_links_low, __pyx_v_matching->sent_id, __pyx_v_e_sent_len, __pyx_v_e_sent_start); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1723; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_15);
               __Pyx_XDECREF(__pyx_v_phrase_list);
               __pyx_v_phrase_list = __pyx_t_15;
               __pyx_t_15 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1724
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1726
  *                                                     f_x_low, f_x_high, f_gap_low, f_gap_high, f_links_low, matching.sent_id,
  *                                                     e_sent_len, e_sent_start)
  *                                 if len(phrase_list) > 0:             # <<<<<<<<<<<<<<
  *                                     pair_count = 1.0 / len(phrase_list)
  *                                 else:
  */
-              __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1724; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1726; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __pyx_t_7 = (__pyx_t_13 > 0);
               if (__pyx_t_7) {
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1725
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1727
  *                                                     e_sent_len, e_sent_start)
  *                                 if len(phrase_list) > 0:
  *                                     pair_count = 1.0 / len(phrase_list)             # <<<<<<<<<<<<<<
  *                                 else:
  *                                     pair_count = 0
  */
-                __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1725; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1727; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 if (unlikely(__pyx_t_13 == 0)) {
                   PyErr_Format(PyExc_ZeroDivisionError, "float division");
-                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1725; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1727; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 }
                 __pyx_v_pair_count = (1.0 / __pyx_t_13);
                 goto __pyx_L74;
               }
               /*else*/ {
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1727
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1729
  *                                     pair_count = 1.0 / len(phrase_list)
  *                                 else:
  *                                     pair_count = 0             # <<<<<<<<<<<<<<
@@ -55952,7 +56020,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               }
               __pyx_L74:;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1728
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1730
  *                                 else:
  *                                     pair_count = 0
  *                                 for phrase2,eindexes in phrase_list:             # <<<<<<<<<<<<<<
@@ -55963,7 +56031,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __pyx_t_15 = __pyx_v_phrase_list; __Pyx_INCREF(__pyx_t_15); __pyx_t_13 = 0;
                 __pyx_t_16 = NULL;
               } else {
-                __pyx_t_13 = -1; __pyx_t_15 = PyObject_GetIter(__pyx_v_phrase_list); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1728; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_13 = -1; __pyx_t_15 = PyObject_GetIter(__pyx_v_phrase_list); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1730; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_15);
                 __pyx_t_16 = Py_TYPE(__pyx_t_15)->tp_iternext;
               }
@@ -55971,23 +56039,23 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 if (!__pyx_t_16 && PyList_CheckExact(__pyx_t_15)) {
                   if (__pyx_t_13 >= PyList_GET_SIZE(__pyx_t_15)) break;
                   #if CYTHON_COMPILING_IN_CPYTHON
-                  __pyx_t_1 = PyList_GET_ITEM(__pyx_t_15, __pyx_t_13); __Pyx_INCREF(__pyx_t_1); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1728; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_1 = PyList_GET_ITEM(__pyx_t_15, __pyx_t_13); __Pyx_INCREF(__pyx_t_1); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1730; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #else
-                  __pyx_t_1 = PySequence_ITEM(__pyx_t_15, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1728; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_1 = PySequence_ITEM(__pyx_t_15, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1730; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #endif
                 } else if (!__pyx_t_16 && PyTuple_CheckExact(__pyx_t_15)) {
                   if (__pyx_t_13 >= PyTuple_GET_SIZE(__pyx_t_15)) break;
                   #if CYTHON_COMPILING_IN_CPYTHON
-                  __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_15, __pyx_t_13); __Pyx_INCREF(__pyx_t_1); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1728; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_15, __pyx_t_13); __Pyx_INCREF(__pyx_t_1); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1730; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #else
-                  __pyx_t_1 = PySequence_ITEM(__pyx_t_15, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1728; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_1 = PySequence_ITEM(__pyx_t_15, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1730; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #endif
                 } else {
                   __pyx_t_1 = __pyx_t_16(__pyx_t_15);
                   if (unlikely(!__pyx_t_1)) {
                     if (PyErr_Occurred()) {
                       if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-                      else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1728; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                      else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1730; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                     }
                     break;
                   }
@@ -56003,7 +56071,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                   if (unlikely(size != 2)) {
                     if (size > 2) __Pyx_RaiseTooManyValuesError(2);
                     else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-                    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1728; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1730; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   }
                   #if CYTHON_COMPILING_IN_CPYTHON
                   if (likely(PyTuple_CheckExact(sequence))) {
@@ -56016,14 +56084,14 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                   __Pyx_INCREF(__pyx_t_14);
                   __Pyx_INCREF(__pyx_t_2);
                   #else
-                  __pyx_t_14 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1728; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-                  __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1728; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_14 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1730; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1730; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #endif
                   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
                 } else
                 {
                   Py_ssize_t index = -1;
-                  __pyx_t_10 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1728; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_10 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1730; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __Pyx_GOTREF(__pyx_t_10);
                   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
                   __pyx_t_17 = Py_TYPE(__pyx_t_10)->tp_iternext;
@@ -56031,7 +56099,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                   __Pyx_GOTREF(__pyx_t_14);
                   index = 1; __pyx_t_2 = __pyx_t_17(__pyx_t_10); if (unlikely(!__pyx_t_2)) goto __pyx_L77_unpacking_failed;
                   __Pyx_GOTREF(__pyx_t_2);
-                  if (__Pyx_IternextUnpackEndCheck(__pyx_t_17(__pyx_t_10), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1728; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  if (__Pyx_IternextUnpackEndCheck(__pyx_t_17(__pyx_t_10), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1730; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __pyx_t_17 = NULL;
                   __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
                   goto __pyx_L78_unpacking_done;
@@ -56039,7 +56107,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                   __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
                   __pyx_t_17 = NULL;
                   if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1728; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1730; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __pyx_L78_unpacking_done:;
                 }
                 __Pyx_XDECREF(__pyx_v_phrase2);
@@ -56049,7 +56117,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __pyx_v_eindexes = __pyx_t_2;
                 __pyx_t_2 = 0;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1729
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1731
  *                                     pair_count = 0
  *                                 for phrase2,eindexes in phrase_list:
  *                                     als2 = self.create_alignments(sent_links,num_links,self.findexes,eindexes)             # <<<<<<<<<<<<<<
@@ -56058,31 +56126,31 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
                 __pyx_t_1 = ((PyObject *)__pyx_v_self->findexes);
                 __Pyx_INCREF(__pyx_t_1);
-                __pyx_t_2 = ((PyObject *)((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->create_alignments(__pyx_v_self, __pyx_v_sent_links, __pyx_v_num_links, __pyx_t_1, __pyx_v_eindexes)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1729; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_2 = ((PyObject *)((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->create_alignments(__pyx_v_self, __pyx_v_sent_links, __pyx_v_num_links, __pyx_t_1, __pyx_v_eindexes)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1731; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_2);
                 __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
                 __Pyx_XDECREF(((PyObject *)__pyx_v_als2));
                 __pyx_v_als2 = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_2);
                 __pyx_t_2 = 0;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1730
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1732
  *                                 for phrase2,eindexes in phrase_list:
  *                                     als2 = self.create_alignments(sent_links,num_links,self.findexes,eindexes)
  *                                     extracts.append((fphr, phrase2, pair_count, tuple(als2)))             # <<<<<<<<<<<<<<
  * 
  *                         if (f_back_high == f_high and
  */
-                __pyx_t_2 = PyFloat_FromDouble(__pyx_v_pair_count); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1730; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_2 = PyFloat_FromDouble(__pyx_v_pair_count); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1732; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_2);
-                __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1730; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1732; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_1);
                 __Pyx_INCREF(((PyObject *)__pyx_v_als2));
                 PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_v_als2));
                 __Pyx_GIVEREF(((PyObject *)__pyx_v_als2));
-                __pyx_t_14 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1730; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_14 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1732; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_14);
                 __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-                __pyx_t_1 = PyTuple_New(4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1730; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_1 = PyTuple_New(4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1732; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_1);
                 __Pyx_INCREF(((PyObject *)__pyx_v_fphr));
                 PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_v_fphr));
@@ -56096,7 +56164,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __Pyx_GIVEREF(__pyx_t_14);
                 __pyx_t_2 = 0;
                 __pyx_t_14 = 0;
-                __pyx_t_14 = __Pyx_PyObject_Append(__pyx_v_extracts, ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1730; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_14 = __Pyx_PyObject_Append(__pyx_v_extracts, ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1732; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_14);
                 __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
                 __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
@@ -56109,7 +56177,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           }
           __pyx_L64:;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1732
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1734
  *                                     extracts.append((fphr, phrase2, pair_count, tuple(als2)))
  * 
  *                         if (f_back_high == f_high and             # <<<<<<<<<<<<<<
@@ -56119,7 +56187,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           __pyx_t_7 = (__pyx_v_f_back_high == __pyx_v_f_high);
           if (__pyx_t_7) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1733
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1735
  * 
  *                         if (f_back_high == f_high and
  *                             f_sent_len - f_high >= self.train_min_gap_size and             # <<<<<<<<<<<<<<
@@ -56129,7 +56197,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             __pyx_t_9 = ((__pyx_v_f_sent_len - __pyx_v_f_high) >= __pyx_v_self->train_min_gap_size);
             if (__pyx_t_9) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1734
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1736
  *                         if (f_back_high == f_high and
  *                             f_sent_len - f_high >= self.train_min_gap_size and
  *                             ((not self.tight_phrases) or (f_links_low[f_high] != -1 and f_links_low[f_back_low] != -1))):             # <<<<<<<<<<<<<<
@@ -56159,7 +56227,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           }
           if (__pyx_t_9) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1735
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1737
  *                             f_sent_len - f_high >= self.train_min_gap_size and
  *                             ((not self.tight_phrases) or (f_links_low[f_high] != -1 and f_links_low[f_back_low] != -1))):
  *                             f_x_high = f_high+self.train_min_gap_size             # <<<<<<<<<<<<<<
@@ -56168,7 +56236,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             __pyx_v_f_x_high = (__pyx_v_f_high + __pyx_v_self->train_min_gap_size);
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1736
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1738
  *                             ((not self.tight_phrases) or (f_links_low[f_high] != -1 and f_links_low[f_back_low] != -1))):
  *                             f_x_high = f_high+self.train_min_gap_size
  *                             met_constraints = 1             # <<<<<<<<<<<<<<
@@ -56177,7 +56245,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             __pyx_v_met_constraints = 1;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1737
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1739
  *                             f_x_high = f_high+self.train_min_gap_size
  *                             met_constraints = 1
  *                             if self.tight_phrases:             # <<<<<<<<<<<<<<
@@ -56186,7 +56254,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             if (__pyx_v_self->tight_phrases) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1738
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1740
  *                             met_constraints = 1
  *                             if self.tight_phrases:
  *                                 while f_x_high <= f_sent_len and f_links_low[f_x_high-1] == -1:             # <<<<<<<<<<<<<<
@@ -56203,7 +56271,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 }
                 if (!__pyx_t_18) break;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1739
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1741
  *                             if self.tight_phrases:
  *                                 while f_x_high <= f_sent_len and f_links_low[f_x_high-1] == -1:
  *                                     f_x_high = f_x_high + 1             # <<<<<<<<<<<<<<
@@ -56216,7 +56284,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             }
             __pyx_L80:;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1740
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1742
  *                                 while f_x_high <= f_sent_len and f_links_low[f_x_high-1] == -1:
  *                                     f_x_high = f_x_high + 1
  *                             if f_x_high > f_sent_len or f_x_high - f_back_low > self.train_max_initial_size:             # <<<<<<<<<<<<<<
@@ -56232,7 +56300,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             }
             if (__pyx_t_7) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1741
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1743
  *                                     f_x_high = f_x_high + 1
  *                             if f_x_high > f_sent_len or f_x_high - f_back_low > self.train_max_initial_size:
  *                                 met_constraints = 0             # <<<<<<<<<<<<<<
@@ -56244,7 +56312,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             }
             __pyx_L83:;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1743
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1745
  *                                 met_constraints = 0
  * 
  *                             if (met_constraints and             # <<<<<<<<<<<<<<
@@ -56253,17 +56321,17 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             if (__pyx_v_met_constraints) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1744
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1746
  * 
  *                             if (met_constraints and
  *                                 self.find_fixpoint(f_back_low, f_x_high,             # <<<<<<<<<<<<<<
  *                                             f_links_low, f_links_high, e_links_low, e_links_high,
  *                                             e_low, e_high, &e_x_low, &e_x_high, &f_x_low, &f_x_high,
  */
-              __pyx_t_15 = PyInt_FromLong(__pyx_v_f_x_high); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1744; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = PyInt_FromLong(__pyx_v_f_x_high); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1746; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_15);
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1748
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1750
  *                                             e_low, e_high, &e_x_low, &e_x_high, &f_x_low, &f_x_high,
  *                                             f_sent_len, e_sent_len,
  *                                             self.train_max_initial_size, self.train_max_initial_size,             # <<<<<<<<<<<<<<
@@ -56273,7 +56341,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               if (((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->find_fixpoint(__pyx_v_self, __pyx_v_f_back_low, __pyx_t_15, __pyx_v_f_links_low, __pyx_v_f_links_high, __pyx_v_e_links_low, __pyx_v_e_links_high, __pyx_v_e_low, __pyx_v_e_high, (&__pyx_v_e_x_low), (&__pyx_v_e_x_high), (&__pyx_v_f_x_low), (&__pyx_v_f_x_high), __pyx_v_f_sent_len, __pyx_v_e_sent_len, __pyx_v_self->train_max_initial_size, __pyx_v_self->train_max_initial_size, 1, 1, 1, 0, 1, 1, 0)) {
                 __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1750
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1752
  *                                             self.train_max_initial_size, self.train_max_initial_size,
  *                                             1, 1, 1, 0, 1, 1, 0) and
  *                                 ((not self.tight_phrases) or f_links_low[f_x_high-1] != -1) and             # <<<<<<<<<<<<<<
@@ -56289,17 +56357,17 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 }
                 if (__pyx_t_9) {
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1751
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1753
  *                                             1, 1, 1, 0, 1, 1, 0) and
  *                                 ((not self.tight_phrases) or f_links_low[f_x_high-1] != -1) and
  *                                 self.find_fixpoint(f_high, f_x_high,             # <<<<<<<<<<<<<<
  *                                             f_links_low, f_links_high, e_links_low, e_links_high,
  *                                             -1, -1, e_gap_low+gap_start+num_gaps, e_gap_high+gap_start+num_gaps,
  */
-                  __pyx_t_14 = PyInt_FromLong(__pyx_v_f_x_high); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1751; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_14 = PyInt_FromLong(__pyx_v_f_x_high); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1753; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __Pyx_GOTREF(__pyx_t_14);
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1756
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1758
  *                                             f_gap_low+gap_start+num_gaps, f_gap_high+gap_start+num_gaps,
  *                                             f_sent_len, e_sent_len,
  *                                             self.train_max_initial_size, self.train_max_initial_size,             # <<<<<<<<<<<<<<
@@ -56322,7 +56390,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             }
             if (__pyx_t_7) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1758
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1760
  *                                             self.train_max_initial_size, self.train_max_initial_size,
  *                                             0, 0, 0, 0, 0, 0, 0)):
  *                                 fphr_arr._clear()             # <<<<<<<<<<<<<<
@@ -56331,7 +56399,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
               ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_fphr_arr->__pyx_vtab)->_clear(__pyx_v_fphr_arr);
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1759
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1761
  *                                             0, 0, 0, 0, 0, 0, 0)):
  *                                 fphr_arr._clear()
  *                                 i = 1             # <<<<<<<<<<<<<<
@@ -56340,21 +56408,21 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
               __pyx_v_i = 1;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1760
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1762
  *                                 fphr_arr._clear()
  *                                 i = 1
  *                                 self.findexes.reset()             # <<<<<<<<<<<<<<
  *                                 if f_back_low < f_low:
  *                                     fphr_arr._append(sym_setindex(self.category, i))
  */
-              __pyx_t_15 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__reset); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1760; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__reset); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1762; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_15);
-              __pyx_t_14 = PyObject_Call(__pyx_t_15, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1760; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_14 = PyObject_Call(__pyx_t_15, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1762; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_14);
               __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
               __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1761
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1763
  *                                 i = 1
  *                                 self.findexes.reset()
  *                                 if f_back_low < f_low:             # <<<<<<<<<<<<<<
@@ -56364,7 +56432,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               __pyx_t_7 = (__pyx_v_f_back_low < __pyx_v_f_low);
               if (__pyx_t_7) {
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1762
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1764
  *                                 self.findexes.reset()
  *                                 if f_back_low < f_low:
  *                                     fphr_arr._append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
@@ -56373,7 +56441,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
                 ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_fphr_arr->__pyx_vtab)->_append(__pyx_v_fphr_arr, __pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i));
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1763
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1765
  *                                 if f_back_low < f_low:
  *                                     fphr_arr._append(sym_setindex(self.category, i))
  *                                     i = i+1             # <<<<<<<<<<<<<<
@@ -56382,16 +56450,16 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
                 __pyx_v_i = (__pyx_v_i + 1);
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1764
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1766
  *                                     fphr_arr._append(sym_setindex(self.category, i))
  *                                     i = i+1
  *                                     self.findexes.append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
  *                                 self.findexes.extend(self.findexes1)
  *                                 for j from 0 <= j < phrase.n:
  */
-                __pyx_t_14 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1764; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_14 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1766; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_14);
-                __pyx_t_15 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_14); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1764; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_14); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1766; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_15);
                 __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
                 __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
@@ -56399,27 +56467,27 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               }
               __pyx_L85:;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1765
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1767
  *                                     i = i+1
  *                                     self.findexes.append(sym_setindex(self.category, i))
  *                                 self.findexes.extend(self.findexes1)             # <<<<<<<<<<<<<<
  *                                 for j from 0 <= j < phrase.n:
  *                                     if sym_isvar(phrase.syms[j]):
  */
-              __pyx_t_15 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__extend); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1765; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__extend); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1767; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_15);
-              __pyx_t_14 = PyTuple_New(1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1765; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_14 = PyTuple_New(1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1767; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_14);
               __Pyx_INCREF(((PyObject *)__pyx_v_self->findexes1));
               PyTuple_SET_ITEM(__pyx_t_14, 0, ((PyObject *)__pyx_v_self->findexes1));
               __Pyx_GIVEREF(((PyObject *)__pyx_v_self->findexes1));
-              __pyx_t_1 = PyObject_Call(__pyx_t_15, ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1765; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_1 = PyObject_Call(__pyx_t_15, ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1767; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_1);
               __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
               __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
               __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1766
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1768
  *                                     self.findexes.append(sym_setindex(self.category, i))
  *                                 self.findexes.extend(self.findexes1)
  *                                 for j from 0 <= j < phrase.n:             # <<<<<<<<<<<<<<
@@ -56429,7 +56497,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               __pyx_t_3 = __pyx_v_phrase->n;
               for (__pyx_v_j = 0; __pyx_v_j < __pyx_t_3; __pyx_v_j++) {
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1767
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1769
  *                                 self.findexes.extend(self.findexes1)
  *                                 for j from 0 <= j < phrase.n:
  *                                     if sym_isvar(phrase.syms[j]):             # <<<<<<<<<<<<<<
@@ -56439,7 +56507,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __pyx_t_4 = __pyx_f_3_sa_sym_isvar((__pyx_v_phrase->syms[__pyx_v_j]));
                 if (__pyx_t_4) {
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1768
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1770
  *                                 for j from 0 <= j < phrase.n:
  *                                     if sym_isvar(phrase.syms[j]):
  *                                         fphr_arr._append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
@@ -56448,7 +56516,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
                   ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_fphr_arr->__pyx_vtab)->_append(__pyx_v_fphr_arr, __pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i));
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1769
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1771
  *                                     if sym_isvar(phrase.syms[j]):
  *                                         fphr_arr._append(sym_setindex(self.category, i))
  *                                         i = i + 1             # <<<<<<<<<<<<<<
@@ -56460,7 +56528,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 }
                 /*else*/ {
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1771
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1773
  *                                         i = i + 1
  *                                     else:
  *                                         fphr_arr._append(phrase.syms[j])             # <<<<<<<<<<<<<<
@@ -56472,7 +56540,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __pyx_L88:;
               }
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1772
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1774
  *                                     else:
  *                                         fphr_arr._append(phrase.syms[j])
  *                                 fphr_arr._append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
@@ -56481,81 +56549,81 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
               ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_fphr_arr->__pyx_vtab)->_append(__pyx_v_fphr_arr, __pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i));
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1773
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1775
  *                                         fphr_arr._append(phrase.syms[j])
  *                                 fphr_arr._append(sym_setindex(self.category, i))
  *                                 self.findexes.append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
  *                                 fphr = Phrase(fphr_arr)
  *                                 phrase_list = self.extract_phrases(e_x_low, e_x_high, e_gap_low+gap_start, e_gap_high+gap_start, e_links_low, num_gaps+1,
  */
-              __pyx_t_1 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1773; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_1 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1775; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_1);
-              __pyx_t_14 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1773; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_14 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1775; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_14);
               __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
               __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1774
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1776
  *                                 fphr_arr._append(sym_setindex(self.category, i))
  *                                 self.findexes.append(sym_setindex(self.category, i))
  *                                 fphr = Phrase(fphr_arr)             # <<<<<<<<<<<<<<
  *                                 phrase_list = self.extract_phrases(e_x_low, e_x_high, e_gap_low+gap_start, e_gap_high+gap_start, e_links_low, num_gaps+1,
  *                                                     f_x_low, f_x_high, f_gap_low+gap_start, f_gap_high+gap_start, f_links_low,
  */
-              __pyx_t_14 = PyTuple_New(1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1774; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_14 = PyTuple_New(1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1776; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_14);
               __Pyx_INCREF(((PyObject *)__pyx_v_fphr_arr));
               PyTuple_SET_ITEM(__pyx_t_14, 0, ((PyObject *)__pyx_v_fphr_arr));
               __Pyx_GIVEREF(((PyObject *)__pyx_v_fphr_arr));
-              __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1774; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1776; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_1);
               __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
               __Pyx_DECREF(((PyObject *)__pyx_v_fphr));
               __pyx_v_fphr = ((struct __pyx_obj_3_sa_Phrase *)__pyx_t_1);
               __pyx_t_1 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1777
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1779
  *                                 phrase_list = self.extract_phrases(e_x_low, e_x_high, e_gap_low+gap_start, e_gap_high+gap_start, e_links_low, num_gaps+1,
  *                                                     f_x_low, f_x_high, f_gap_low+gap_start, f_gap_high+gap_start, f_links_low,
  *                                                     matching.sent_id, e_sent_len, e_sent_start)             # <<<<<<<<<<<<<<
  *                                 if len(phrase_list) > 0:
  *                                     pair_count = 1.0 / len(phrase_list)
  */
-              __pyx_t_1 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->extract_phrases(__pyx_v_self, __pyx_v_e_x_low, __pyx_v_e_x_high, (__pyx_v_e_gap_low + __pyx_v_gap_start), (__pyx_v_e_gap_high + __pyx_v_gap_start), __pyx_v_e_links_low, (__pyx_v_num_gaps + 1), __pyx_v_f_x_low, __pyx_v_f_x_high, (__pyx_v_f_gap_low + __pyx_v_gap_start), (__pyx_v_f_gap_high + __pyx_v_gap_start), __pyx_v_f_links_low, __pyx_v_matching->sent_id, __pyx_v_e_sent_len, __pyx_v_e_sent_start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1775; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_1 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->extract_phrases(__pyx_v_self, __pyx_v_e_x_low, __pyx_v_e_x_high, (__pyx_v_e_gap_low + __pyx_v_gap_start), (__pyx_v_e_gap_high + __pyx_v_gap_start), __pyx_v_e_links_low, (__pyx_v_num_gaps + 1), __pyx_v_f_x_low, __pyx_v_f_x_high, (__pyx_v_f_gap_low + __pyx_v_gap_start), (__pyx_v_f_gap_high + __pyx_v_gap_start), __pyx_v_f_links_low, __pyx_v_matching->sent_id, __pyx_v_e_sent_len, __pyx_v_e_sent_start); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1777; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_1);
               __Pyx_XDECREF(__pyx_v_phrase_list);
               __pyx_v_phrase_list = __pyx_t_1;
               __pyx_t_1 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1778
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1780
  *                                                     f_x_low, f_x_high, f_gap_low+gap_start, f_gap_high+gap_start, f_links_low,
  *                                                     matching.sent_id, e_sent_len, e_sent_start)
  *                                 if len(phrase_list) > 0:             # <<<<<<<<<<<<<<
  *                                     pair_count = 1.0 / len(phrase_list)
  *                                 else:
  */
-              __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1778; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1780; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __pyx_t_7 = (__pyx_t_13 > 0);
               if (__pyx_t_7) {
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1779
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1781
  *                                                     matching.sent_id, e_sent_len, e_sent_start)
  *                                 if len(phrase_list) > 0:
  *                                     pair_count = 1.0 / len(phrase_list)             # <<<<<<<<<<<<<<
  *                                 else:
  *                                     pair_count = 0
  */
-                __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1779; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 if (unlikely(__pyx_t_13 == 0)) {
                   PyErr_Format(PyExc_ZeroDivisionError, "float division");
-                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1779; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 }
                 __pyx_v_pair_count = (1.0 / __pyx_t_13);
                 goto __pyx_L89;
               }
               /*else*/ {
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1781
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1783
  *                                     pair_count = 1.0 / len(phrase_list)
  *                                 else:
  *                                     pair_count = 0             # <<<<<<<<<<<<<<
@@ -56566,7 +56634,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               }
               __pyx_L89:;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1782
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1784
  *                                 else:
  *                                     pair_count = 0
  *                                 for phrase2, eindexes in phrase_list:             # <<<<<<<<<<<<<<
@@ -56577,7 +56645,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __pyx_t_1 = __pyx_v_phrase_list; __Pyx_INCREF(__pyx_t_1); __pyx_t_13 = 0;
                 __pyx_t_16 = NULL;
               } else {
-                __pyx_t_13 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_phrase_list); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1782; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_13 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_phrase_list); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1784; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_1);
                 __pyx_t_16 = Py_TYPE(__pyx_t_1)->tp_iternext;
               }
@@ -56585,23 +56653,23 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 if (!__pyx_t_16 && PyList_CheckExact(__pyx_t_1)) {
                   if (__pyx_t_13 >= PyList_GET_SIZE(__pyx_t_1)) break;
                   #if CYTHON_COMPILING_IN_CPYTHON
-                  __pyx_t_14 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_13); __Pyx_INCREF(__pyx_t_14); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1782; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_14 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_13); __Pyx_INCREF(__pyx_t_14); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1784; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #else
-                  __pyx_t_14 = PySequence_ITEM(__pyx_t_1, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1782; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_14 = PySequence_ITEM(__pyx_t_1, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1784; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #endif
                 } else if (!__pyx_t_16 && PyTuple_CheckExact(__pyx_t_1)) {
                   if (__pyx_t_13 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
                   #if CYTHON_COMPILING_IN_CPYTHON
-                  __pyx_t_14 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_13); __Pyx_INCREF(__pyx_t_14); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1782; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_14 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_13); __Pyx_INCREF(__pyx_t_14); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1784; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #else
-                  __pyx_t_14 = PySequence_ITEM(__pyx_t_1, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1782; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_14 = PySequence_ITEM(__pyx_t_1, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1784; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #endif
                 } else {
                   __pyx_t_14 = __pyx_t_16(__pyx_t_1);
                   if (unlikely(!__pyx_t_14)) {
                     if (PyErr_Occurred()) {
                       if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-                      else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1782; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                      else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1784; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                     }
                     break;
                   }
@@ -56617,7 +56685,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                   if (unlikely(size != 2)) {
                     if (size > 2) __Pyx_RaiseTooManyValuesError(2);
                     else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-                    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1782; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1784; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   }
                   #if CYTHON_COMPILING_IN_CPYTHON
                   if (likely(PyTuple_CheckExact(sequence))) {
@@ -56630,14 +56698,14 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                   __Pyx_INCREF(__pyx_t_15);
                   __Pyx_INCREF(__pyx_t_2);
                   #else
-                  __pyx_t_15 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1782; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-                  __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1782; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_15 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1784; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1784; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #endif
                   __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
                 } else
                 {
                   Py_ssize_t index = -1;
-                  __pyx_t_10 = PyObject_GetIter(__pyx_t_14); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1782; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_10 = PyObject_GetIter(__pyx_t_14); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1784; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __Pyx_GOTREF(__pyx_t_10);
                   __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
                   __pyx_t_17 = Py_TYPE(__pyx_t_10)->tp_iternext;
@@ -56645,7 +56713,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                   __Pyx_GOTREF(__pyx_t_15);
                   index = 1; __pyx_t_2 = __pyx_t_17(__pyx_t_10); if (unlikely(!__pyx_t_2)) goto __pyx_L92_unpacking_failed;
                   __Pyx_GOTREF(__pyx_t_2);
-                  if (__Pyx_IternextUnpackEndCheck(__pyx_t_17(__pyx_t_10), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1782; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  if (__Pyx_IternextUnpackEndCheck(__pyx_t_17(__pyx_t_10), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1784; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __pyx_t_17 = NULL;
                   __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
                   goto __pyx_L93_unpacking_done;
@@ -56653,7 +56721,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                   __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
                   __pyx_t_17 = NULL;
                   if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1782; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1784; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __pyx_L93_unpacking_done:;
                 }
                 __Pyx_XDECREF(__pyx_v_phrase2);
@@ -56663,7 +56731,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __pyx_v_eindexes = __pyx_t_2;
                 __pyx_t_2 = 0;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1783
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1785
  *                                     pair_count = 0
  *                                 for phrase2, eindexes in phrase_list:
  *                                     als3 = self.create_alignments(sent_links,num_links,self.findexes,eindexes)             # <<<<<<<<<<<<<<
@@ -56672,31 +56740,31 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
                 __pyx_t_14 = ((PyObject *)__pyx_v_self->findexes);
                 __Pyx_INCREF(__pyx_t_14);
-                __pyx_t_2 = ((PyObject *)((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->create_alignments(__pyx_v_self, __pyx_v_sent_links, __pyx_v_num_links, __pyx_t_14, __pyx_v_eindexes)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1783; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_2 = ((PyObject *)((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->create_alignments(__pyx_v_self, __pyx_v_sent_links, __pyx_v_num_links, __pyx_t_14, __pyx_v_eindexes)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1785; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_2);
                 __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
                 __Pyx_XDECREF(((PyObject *)__pyx_v_als3));
                 __pyx_v_als3 = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_2);
                 __pyx_t_2 = 0;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1784
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1786
  *                                 for phrase2, eindexes in phrase_list:
  *                                     als3 = self.create_alignments(sent_links,num_links,self.findexes,eindexes)
  *                                     extracts.append((fphr, phrase2, pair_count, tuple(als3)))             # <<<<<<<<<<<<<<
  *                         if (num_gaps < self.max_nonterminals - 1 and
  *                             phrase_len+1 < self.max_length and
  */
-                __pyx_t_2 = PyFloat_FromDouble(__pyx_v_pair_count); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1784; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_2 = PyFloat_FromDouble(__pyx_v_pair_count); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1786; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_2);
-                __pyx_t_14 = PyTuple_New(1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1784; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_14 = PyTuple_New(1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1786; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_14);
                 __Pyx_INCREF(((PyObject *)__pyx_v_als3));
                 PyTuple_SET_ITEM(__pyx_t_14, 0, ((PyObject *)__pyx_v_als3));
                 __Pyx_GIVEREF(((PyObject *)__pyx_v_als3));
-                __pyx_t_15 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1784; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1786; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_15);
                 __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
-                __pyx_t_14 = PyTuple_New(4); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1784; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_14 = PyTuple_New(4); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1786; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_14);
                 __Pyx_INCREF(((PyObject *)__pyx_v_fphr));
                 PyTuple_SET_ITEM(__pyx_t_14, 0, ((PyObject *)__pyx_v_fphr));
@@ -56710,7 +56778,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __Pyx_GIVEREF(__pyx_t_15);
                 __pyx_t_2 = 0;
                 __pyx_t_15 = 0;
-                __pyx_t_15 = __Pyx_PyObject_Append(__pyx_v_extracts, ((PyObject *)__pyx_t_14)); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1784; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = __Pyx_PyObject_Append(__pyx_v_extracts, ((PyObject *)__pyx_t_14)); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1786; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_15);
                 __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
                 __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
@@ -56723,7 +56791,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           }
           __pyx_L79:;
 
-          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1785
+          /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1787
  *                                     als3 = self.create_alignments(sent_links,num_links,self.findexes,eindexes)
  *                                     extracts.append((fphr, phrase2, pair_count, tuple(als3)))
  *                         if (num_gaps < self.max_nonterminals - 1 and             # <<<<<<<<<<<<<<
@@ -56733,7 +56801,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           __pyx_t_7 = (__pyx_v_num_gaps < (__pyx_v_self->max_nonterminals - 1));
           if (__pyx_t_7) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1786
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1788
  *                                     extracts.append((fphr, phrase2, pair_count, tuple(als3)))
  *                         if (num_gaps < self.max_nonterminals - 1 and
  *                             phrase_len+1 < self.max_length and             # <<<<<<<<<<<<<<
@@ -56743,7 +56811,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             __pyx_t_9 = ((__pyx_v_phrase_len + 1) < __pyx_v_self->max_length);
             if (__pyx_t_9) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1787
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1789
  *                         if (num_gaps < self.max_nonterminals - 1 and
  *                             phrase_len+1 < self.max_length and
  *                             f_back_high == f_high and             # <<<<<<<<<<<<<<
@@ -56753,7 +56821,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               __pyx_t_18 = (__pyx_v_f_back_high == __pyx_v_f_high);
               if (__pyx_t_18) {
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1788
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1790
  *                             phrase_len+1 < self.max_length and
  *                             f_back_high == f_high and
  *                             f_back_low == f_low and             # <<<<<<<<<<<<<<
@@ -56763,7 +56831,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __pyx_t_8 = (__pyx_v_f_back_low == __pyx_v_f_low);
                 if (__pyx_t_8) {
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1789
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1791
  *                             f_back_high == f_high and
  *                             f_back_low == f_low and
  *                             f_back_high - f_back_low + (2*self.train_min_gap_size) <= self.train_max_initial_size and             # <<<<<<<<<<<<<<
@@ -56773,7 +56841,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                   __pyx_t_19 = (((__pyx_v_f_back_high - __pyx_v_f_back_low) + (2 * __pyx_v_self->train_min_gap_size)) <= __pyx_v_self->train_max_initial_size);
                   if (__pyx_t_19) {
 
-                    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1790
+                    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1792
  *                             f_back_low == f_low and
  *                             f_back_high - f_back_low + (2*self.train_min_gap_size) <= self.train_max_initial_size and
  *                             f_low >= self.train_min_gap_size and             # <<<<<<<<<<<<<<
@@ -56783,7 +56851,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                     __pyx_t_20 = (__pyx_v_f_low >= __pyx_v_self->train_min_gap_size);
                     if (__pyx_t_20) {
 
-                      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1791
+                      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1793
  *                             f_back_high - f_back_low + (2*self.train_min_gap_size) <= self.train_max_initial_size and
  *                             f_low >= self.train_min_gap_size and
  *                             f_high <= f_sent_len - self.train_min_gap_size and             # <<<<<<<<<<<<<<
@@ -56793,7 +56861,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                       __pyx_t_21 = (__pyx_v_f_high <= (__pyx_v_f_sent_len - __pyx_v_self->train_min_gap_size));
                       if (__pyx_t_21) {
 
-                        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1792
+                        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1794
  *                             f_low >= self.train_min_gap_size and
  *                             f_high <= f_sent_len - self.train_min_gap_size and
  *                             ((not self.tight_phrases) or (f_links_low[f_low-1] != -1 and f_links_low[f_high] != -1))):             # <<<<<<<<<<<<<<
@@ -56843,7 +56911,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
           }
           if (__pyx_t_9) {
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1794
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1796
  *                             ((not self.tight_phrases) or (f_links_low[f_low-1] != -1 and f_links_low[f_high] != -1))):
  * 
  *                             met_constraints = 1             # <<<<<<<<<<<<<<
@@ -56852,7 +56920,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             __pyx_v_met_constraints = 1;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1795
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1797
  * 
  *                             met_constraints = 1
  *                             f_x_low = f_low-self.train_min_gap_size             # <<<<<<<<<<<<<<
@@ -56861,7 +56929,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             __pyx_v_f_x_low = (__pyx_v_f_low - __pyx_v_self->train_min_gap_size);
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1796
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1798
  *                             met_constraints = 1
  *                             f_x_low = f_low-self.train_min_gap_size
  *                             if self.tight_phrases:             # <<<<<<<<<<<<<<
@@ -56870,7 +56938,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             if (__pyx_v_self->tight_phrases) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1797
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1799
  *                             f_x_low = f_low-self.train_min_gap_size
  *                             if self.tight_phrases:
  *                                 while f_x_low >= 0 and f_links_low[f_x_low] == -1:             # <<<<<<<<<<<<<<
@@ -56887,7 +56955,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 }
                 if (!__pyx_t_18) break;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1798
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1800
  *                             if self.tight_phrases:
  *                                 while f_x_low >= 0 and f_links_low[f_x_low] == -1:
  *                                     f_x_low = f_x_low - 1             # <<<<<<<<<<<<<<
@@ -56900,7 +56968,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             }
             __pyx_L95:;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1799
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1801
  *                                 while f_x_low >= 0 and f_links_low[f_x_low] == -1:
  *                                     f_x_low = f_x_low - 1
  *                             if f_x_low < 0:             # <<<<<<<<<<<<<<
@@ -56910,7 +56978,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             __pyx_t_18 = (__pyx_v_f_x_low < 0);
             if (__pyx_t_18) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1800
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1802
  *                                     f_x_low = f_x_low - 1
  *                             if f_x_low < 0:
  *                                 met_constraints = 0             # <<<<<<<<<<<<<<
@@ -56922,7 +56990,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             }
             __pyx_L98:;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1802
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1804
  *                                 met_constraints = 0
  * 
  *                             f_x_high = f_high+self.train_min_gap_size             # <<<<<<<<<<<<<<
@@ -56931,7 +56999,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             __pyx_v_f_x_high = (__pyx_v_f_high + __pyx_v_self->train_min_gap_size);
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1803
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1805
  * 
  *                             f_x_high = f_high+self.train_min_gap_size
  *                             if self.tight_phrases:             # <<<<<<<<<<<<<<
@@ -56940,7 +57008,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             if (__pyx_v_self->tight_phrases) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1804
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1806
  *                             f_x_high = f_high+self.train_min_gap_size
  *                             if self.tight_phrases:
  *                                 while f_x_high <= f_sent_len and f_links_low[f_x_high-1] == -1:             # <<<<<<<<<<<<<<
@@ -56957,7 +57025,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 }
                 if (!__pyx_t_7) break;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1805
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1807
  *                             if self.tight_phrases:
  *                                 while f_x_high <= f_sent_len and f_links_low[f_x_high-1] == -1:
  *                                     f_x_high = f_x_high + 1             # <<<<<<<<<<<<<<
@@ -56970,7 +57038,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             }
             __pyx_L99:;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1806
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1808
  *                                 while f_x_high <= f_sent_len and f_links_low[f_x_high-1] == -1:
  *                                     f_x_high = f_x_high + 1
  *                             if f_x_high > f_sent_len or f_x_high - f_x_low > self.train_max_initial_size:             # <<<<<<<<<<<<<<
@@ -56986,7 +57054,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             }
             if (__pyx_t_9) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1807
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1809
  *                                     f_x_high = f_x_high + 1
  *                             if f_x_high > f_sent_len or f_x_high - f_x_low > self.train_max_initial_size:
  *                                 met_constraints = 0             # <<<<<<<<<<<<<<
@@ -56998,7 +57066,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             }
             __pyx_L102:;
 
-            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1809
+            /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1811
  *                                 met_constraints = 0
  * 
  *                             if (met_constraints and             # <<<<<<<<<<<<<<
@@ -57007,17 +57075,17 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
             if (__pyx_v_met_constraints) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1810
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1812
  * 
  *                             if (met_constraints and
  *                                 self.find_fixpoint(f_x_low, f_x_high,             # <<<<<<<<<<<<<<
  *                                                 f_links_low, f_links_high, e_links_low, e_links_high,
  *                                                 e_low, e_high, &e_x_low, &e_x_high, &f_x_low, &f_x_high,
  */
-              __pyx_t_1 = PyInt_FromLong(__pyx_v_f_x_high); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1810; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_1 = PyInt_FromLong(__pyx_v_f_x_high); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1812; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_1);
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1814
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1816
  *                                                 e_low, e_high, &e_x_low, &e_x_high, &f_x_low, &f_x_high,
  *                                                 f_sent_len, e_sent_len,
  *                                                 self.train_max_initial_size, self.train_max_initial_size,             # <<<<<<<<<<<<<<
@@ -57027,7 +57095,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               if (((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->find_fixpoint(__pyx_v_self, __pyx_v_f_x_low, __pyx_t_1, __pyx_v_f_links_low, __pyx_v_f_links_high, __pyx_v_e_links_low, __pyx_v_e_links_high, __pyx_v_e_low, __pyx_v_e_high, (&__pyx_v_e_x_low), (&__pyx_v_e_x_high), (&__pyx_v_f_x_low), (&__pyx_v_f_x_high), __pyx_v_f_sent_len, __pyx_v_e_sent_len, __pyx_v_self->train_max_initial_size, __pyx_v_self->train_max_initial_size, 1, 1, 2, 1, 1, 1, 1)) {
                 __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1816
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1818
  *                                                 self.train_max_initial_size, self.train_max_initial_size,
  *                                                 1, 1, 2, 1, 1, 1, 1) and
  *                                 ((not self.tight_phrases) or (f_links_low[f_x_low] != -1 and f_links_low[f_x_high-1] != -1)) and             # <<<<<<<<<<<<<<
@@ -57049,17 +57117,17 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 }
                 if (__pyx_t_7) {
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1817
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1819
  *                                                 1, 1, 2, 1, 1, 1, 1) and
  *                                 ((not self.tight_phrases) or (f_links_low[f_x_low] != -1 and f_links_low[f_x_high-1] != -1)) and
  *                                 self.find_fixpoint(f_x_low, f_low,             # <<<<<<<<<<<<<<
  *                                                 f_links_low, f_links_high, e_links_low, e_links_high,
  *                                                 -1, -1, e_gap_low, e_gap_high, f_gap_low, f_gap_high,
  */
-                  __pyx_t_15 = PyInt_FromLong(__pyx_v_f_low); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1817; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_15 = PyInt_FromLong(__pyx_v_f_low); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1819; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __Pyx_GOTREF(__pyx_t_15);
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1821
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1823
  *                                                 -1, -1, e_gap_low, e_gap_high, f_gap_low, f_gap_high,
  *                                                 f_sent_len, e_sent_len,
  *                                                 self.train_max_initial_size, self.train_max_initial_size,             # <<<<<<<<<<<<<<
@@ -57070,17 +57138,17 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                   __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
                   if (__pyx_t_3) {
 
-                    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1823
+                    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1825
  *                                                 self.train_max_initial_size, self.train_max_initial_size,
  *                                                 0, 0, 0, 0, 0, 0, 0) and
  *                                 self.find_fixpoint(f_high, f_x_high,             # <<<<<<<<<<<<<<
  *                                                 f_links_low, f_links_high, e_links_low, e_links_high,
  *                                                 -1, -1, e_gap_low+1+num_gaps, e_gap_high+1+num_gaps,
  */
-                    __pyx_t_15 = PyInt_FromLong(__pyx_v_f_x_high); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                    __pyx_t_15 = PyInt_FromLong(__pyx_v_f_x_high); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1825; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                     __Pyx_GOTREF(__pyx_t_15);
 
-                    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1828
+                    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1830
  *                                                 f_gap_low+1+num_gaps, f_gap_high+1+num_gaps,
  *                                                 f_sent_len, e_sent_len,
  *                                                 self.train_max_initial_size, self.train_max_initial_size,             # <<<<<<<<<<<<<<
@@ -57108,7 +57176,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
             }
             if (__pyx_t_8) {
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1830
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1832
  *                                                 self.train_max_initial_size, self.train_max_initial_size,
  *                                                 0, 0, 0, 0, 0, 0, 0)):
  *                                 fphr_arr._clear()             # <<<<<<<<<<<<<<
@@ -57117,7 +57185,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
               ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_fphr_arr->__pyx_vtab)->_clear(__pyx_v_fphr_arr);
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1831
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1833
  *                                                 0, 0, 0, 0, 0, 0, 0)):
  *                                 fphr_arr._clear()
  *                                 i = 1             # <<<<<<<<<<<<<<
@@ -57126,35 +57194,35 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
               __pyx_v_i = 1;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1832
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1834
  *                                 fphr_arr._clear()
  *                                 i = 1
  *                                 self.findexes.reset()             # <<<<<<<<<<<<<<
  *                                 self.findexes.append(sym_setindex(self.category, i))
  *                                 fphr_arr._append(sym_setindex(self.category, i))
  */
-              __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__reset); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__reset); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_1);
-              __pyx_t_15 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_15);
               __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
               __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1833
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1835
  *                                 i = 1
  *                                 self.findexes.reset()
  *                                 self.findexes.append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
  *                                 fphr_arr._append(sym_setindex(self.category, i))
  *                                 i = i+1
  */
-              __pyx_t_15 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_15);
-              __pyx_t_1 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_15); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_1 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_15); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_1);
               __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
               __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1834
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1836
  *                                 self.findexes.reset()
  *                                 self.findexes.append(sym_setindex(self.category, i))
  *                                 fphr_arr._append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
@@ -57163,7 +57231,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
               ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_fphr_arr->__pyx_vtab)->_append(__pyx_v_fphr_arr, __pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i));
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1835
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1837
  *                                 self.findexes.append(sym_setindex(self.category, i))
  *                                 fphr_arr._append(sym_setindex(self.category, i))
  *                                 i = i+1             # <<<<<<<<<<<<<<
@@ -57172,27 +57240,27 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
               __pyx_v_i = (__pyx_v_i + 1);
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1836
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1838
  *                                 fphr_arr._append(sym_setindex(self.category, i))
  *                                 i = i+1
  *                                 self.findexes.extend(self.findexes1)             # <<<<<<<<<<<<<<
  *                                 for j from 0 <= j < phrase.n:
  *                                     if sym_isvar(phrase.syms[j]):
  */
-              __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__extend); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self->findexes), __pyx_n_s__extend); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_1);
-              __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_15);
               __Pyx_INCREF(((PyObject *)__pyx_v_self->findexes1));
               PyTuple_SET_ITEM(__pyx_t_15, 0, ((PyObject *)__pyx_v_self->findexes1));
               __Pyx_GIVEREF(((PyObject *)__pyx_v_self->findexes1));
-              __pyx_t_14 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_14 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_14);
               __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
               __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
               __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1837
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1839
  *                                 i = i+1
  *                                 self.findexes.extend(self.findexes1)
  *                                 for j from 0 <= j < phrase.n:             # <<<<<<<<<<<<<<
@@ -57202,7 +57270,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               __pyx_t_3 = __pyx_v_phrase->n;
               for (__pyx_v_j = 0; __pyx_v_j < __pyx_t_3; __pyx_v_j++) {
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1838
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1840
  *                                 self.findexes.extend(self.findexes1)
  *                                 for j from 0 <= j < phrase.n:
  *                                     if sym_isvar(phrase.syms[j]):             # <<<<<<<<<<<<<<
@@ -57212,7 +57280,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __pyx_t_4 = __pyx_f_3_sa_sym_isvar((__pyx_v_phrase->syms[__pyx_v_j]));
                 if (__pyx_t_4) {
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1839
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1841
  *                                 for j from 0 <= j < phrase.n:
  *                                     if sym_isvar(phrase.syms[j]):
  *                                         fphr_arr._append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
@@ -57221,7 +57289,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
                   ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_fphr_arr->__pyx_vtab)->_append(__pyx_v_fphr_arr, __pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i));
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1840
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1842
  *                                     if sym_isvar(phrase.syms[j]):
  *                                         fphr_arr._append(sym_setindex(self.category, i))
  *                                         i = i + 1             # <<<<<<<<<<<<<<
@@ -57233,7 +57301,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 }
                 /*else*/ {
 
-                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1842
+                  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1844
  *                                         i = i + 1
  *                                     else:
  *                                         fphr_arr._append(phrase.syms[j])             # <<<<<<<<<<<<<<
@@ -57245,7 +57313,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __pyx_L106:;
               }
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1843
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1845
  *                                     else:
  *                                         fphr_arr._append(phrase.syms[j])
  *                                 fphr_arr._append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
@@ -57254,81 +57322,81 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
               ((struct __pyx_vtabstruct_3_sa_IntList *)__pyx_v_fphr_arr->__pyx_vtab)->_append(__pyx_v_fphr_arr, __pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i));
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1844
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1846
  *                                         fphr_arr._append(phrase.syms[j])
  *                                 fphr_arr._append(sym_setindex(self.category, i))
  *                                 self.findexes.append(sym_setindex(self.category, i))             # <<<<<<<<<<<<<<
  *                                 fphr = Phrase(fphr_arr)
  *                                 phrase_list = self.extract_phrases(e_x_low, e_x_high, e_gap_low, e_gap_high, e_links_low, num_gaps+2,
  */
-              __pyx_t_14 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_14 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_v_self->category, __pyx_v_i)); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1846; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_14);
-              __pyx_t_15 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_14); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = __Pyx_PyObject_Append(((PyObject *)__pyx_v_self->findexes), __pyx_t_14); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1846; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_15);
               __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
               __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1845
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1847
  *                                 fphr_arr._append(sym_setindex(self.category, i))
  *                                 self.findexes.append(sym_setindex(self.category, i))
  *                                 fphr = Phrase(fphr_arr)             # <<<<<<<<<<<<<<
  *                                 phrase_list = self.extract_phrases(e_x_low, e_x_high, e_gap_low, e_gap_high, e_links_low, num_gaps+2,
  *                                                     f_x_low, f_x_high, f_gap_low, f_gap_high, f_links_low,
  */
-              __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1845; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1847; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_15);
               __Pyx_INCREF(((PyObject *)__pyx_v_fphr_arr));
               PyTuple_SET_ITEM(__pyx_t_15, 0, ((PyObject *)__pyx_v_fphr_arr));
               __Pyx_GIVEREF(((PyObject *)__pyx_v_fphr_arr));
-              __pyx_t_14 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1845; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_14 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1847; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_14);
               __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
               __Pyx_DECREF(((PyObject *)__pyx_v_fphr));
               __pyx_v_fphr = ((struct __pyx_obj_3_sa_Phrase *)__pyx_t_14);
               __pyx_t_14 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1848
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1850
  *                                 phrase_list = self.extract_phrases(e_x_low, e_x_high, e_gap_low, e_gap_high, e_links_low, num_gaps+2,
  *                                                     f_x_low, f_x_high, f_gap_low, f_gap_high, f_links_low,
  *                                                     matching.sent_id, e_sent_len, e_sent_start)             # <<<<<<<<<<<<<<
  *                                 if len(phrase_list) > 0:
  *                                     pair_count = 1.0 / len(phrase_list)
  */
-              __pyx_t_14 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->extract_phrases(__pyx_v_self, __pyx_v_e_x_low, __pyx_v_e_x_high, __pyx_v_e_gap_low, __pyx_v_e_gap_high, __pyx_v_e_links_low, (__pyx_v_num_gaps + 2), __pyx_v_f_x_low, __pyx_v_f_x_high, __pyx_v_f_gap_low, __pyx_v_f_gap_high, __pyx_v_f_links_low, __pyx_v_matching->sent_id, __pyx_v_e_sent_len, __pyx_v_e_sent_start); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1846; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_14 = ((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->extract_phrases(__pyx_v_self, __pyx_v_e_x_low, __pyx_v_e_x_high, __pyx_v_e_gap_low, __pyx_v_e_gap_high, __pyx_v_e_links_low, (__pyx_v_num_gaps + 2), __pyx_v_f_x_low, __pyx_v_f_x_high, __pyx_v_f_gap_low, __pyx_v_f_gap_high, __pyx_v_f_links_low, __pyx_v_matching->sent_id, __pyx_v_e_sent_len, __pyx_v_e_sent_start); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1848; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __Pyx_GOTREF(__pyx_t_14);
               __Pyx_XDECREF(__pyx_v_phrase_list);
               __pyx_v_phrase_list = __pyx_t_14;
               __pyx_t_14 = 0;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1849
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1851
  *                                                     f_x_low, f_x_high, f_gap_low, f_gap_high, f_links_low,
  *                                                     matching.sent_id, e_sent_len, e_sent_start)
  *                                 if len(phrase_list) > 0:             # <<<<<<<<<<<<<<
  *                                     pair_count = 1.0 / len(phrase_list)
  *                                 else:
  */
-              __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1849; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1851; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
               __pyx_t_8 = (__pyx_t_13 > 0);
               if (__pyx_t_8) {
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1850
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1852
  *                                                     matching.sent_id, e_sent_len, e_sent_start)
  *                                 if len(phrase_list) > 0:
  *                                     pair_count = 1.0 / len(phrase_list)             # <<<<<<<<<<<<<<
  *                                 else:
  *                                     pair_count = 0
  */
-                __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1850; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_13 = PyObject_Length(__pyx_v_phrase_list); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1852; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 if (unlikely(__pyx_t_13 == 0)) {
                   PyErr_Format(PyExc_ZeroDivisionError, "float division");
-                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1850; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1852; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 }
                 __pyx_v_pair_count = (1.0 / __pyx_t_13);
                 goto __pyx_L107;
               }
               /*else*/ {
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1852
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1854
  *                                     pair_count = 1.0 / len(phrase_list)
  *                                 else:
  *                                     pair_count = 0             # <<<<<<<<<<<<<<
@@ -57339,7 +57407,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
               }
               __pyx_L107:;
 
-              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1853
+              /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1855
  *                                 else:
  *                                     pair_count = 0
  *                                 for phrase2, eindexes in phrase_list:             # <<<<<<<<<<<<<<
@@ -57350,7 +57418,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __pyx_t_14 = __pyx_v_phrase_list; __Pyx_INCREF(__pyx_t_14); __pyx_t_13 = 0;
                 __pyx_t_16 = NULL;
               } else {
-                __pyx_t_13 = -1; __pyx_t_14 = PyObject_GetIter(__pyx_v_phrase_list); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_13 = -1; __pyx_t_14 = PyObject_GetIter(__pyx_v_phrase_list); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_14);
                 __pyx_t_16 = Py_TYPE(__pyx_t_14)->tp_iternext;
               }
@@ -57358,23 +57426,23 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 if (!__pyx_t_16 && PyList_CheckExact(__pyx_t_14)) {
                   if (__pyx_t_13 >= PyList_GET_SIZE(__pyx_t_14)) break;
                   #if CYTHON_COMPILING_IN_CPYTHON
-                  __pyx_t_15 = PyList_GET_ITEM(__pyx_t_14, __pyx_t_13); __Pyx_INCREF(__pyx_t_15); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_15 = PyList_GET_ITEM(__pyx_t_14, __pyx_t_13); __Pyx_INCREF(__pyx_t_15); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #else
-                  __pyx_t_15 = PySequence_ITEM(__pyx_t_14, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_15 = PySequence_ITEM(__pyx_t_14, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #endif
                 } else if (!__pyx_t_16 && PyTuple_CheckExact(__pyx_t_14)) {
                   if (__pyx_t_13 >= PyTuple_GET_SIZE(__pyx_t_14)) break;
                   #if CYTHON_COMPILING_IN_CPYTHON
-                  __pyx_t_15 = PyTuple_GET_ITEM(__pyx_t_14, __pyx_t_13); __Pyx_INCREF(__pyx_t_15); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_15 = PyTuple_GET_ITEM(__pyx_t_14, __pyx_t_13); __Pyx_INCREF(__pyx_t_15); __pyx_t_13++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #else
-                  __pyx_t_15 = PySequence_ITEM(__pyx_t_14, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_15 = PySequence_ITEM(__pyx_t_14, __pyx_t_13); __pyx_t_13++; if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #endif
                 } else {
                   __pyx_t_15 = __pyx_t_16(__pyx_t_14);
                   if (unlikely(!__pyx_t_15)) {
                     if (PyErr_Occurred()) {
                       if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-                      else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                      else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                     }
                     break;
                   }
@@ -57390,7 +57458,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                   if (unlikely(size != 2)) {
                     if (size > 2) __Pyx_RaiseTooManyValuesError(2);
                     else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-                    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                    {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   }
                   #if CYTHON_COMPILING_IN_CPYTHON
                   if (likely(PyTuple_CheckExact(sequence))) {
@@ -57403,14 +57471,14 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                   __Pyx_INCREF(__pyx_t_1);
                   __Pyx_INCREF(__pyx_t_2);
                   #else
-                  __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-                  __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   #endif
                   __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
                 } else
                 {
                   Py_ssize_t index = -1;
-                  __pyx_t_10 = PyObject_GetIter(__pyx_t_15); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  __pyx_t_10 = PyObject_GetIter(__pyx_t_15); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __Pyx_GOTREF(__pyx_t_10);
                   __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
                   __pyx_t_17 = Py_TYPE(__pyx_t_10)->tp_iternext;
@@ -57418,7 +57486,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                   __Pyx_GOTREF(__pyx_t_1);
                   index = 1; __pyx_t_2 = __pyx_t_17(__pyx_t_10); if (unlikely(!__pyx_t_2)) goto __pyx_L110_unpacking_failed;
                   __Pyx_GOTREF(__pyx_t_2);
-                  if (__Pyx_IternextUnpackEndCheck(__pyx_t_17(__pyx_t_10), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  if (__Pyx_IternextUnpackEndCheck(__pyx_t_17(__pyx_t_10), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __pyx_t_17 = NULL;
                   __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
                   goto __pyx_L111_unpacking_done;
@@ -57426,7 +57494,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                   __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
                   __pyx_t_17 = NULL;
                   if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1853; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                  {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                   __pyx_L111_unpacking_done:;
                 }
                 __Pyx_XDECREF(__pyx_v_phrase2);
@@ -57436,7 +57504,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __pyx_v_eindexes = __pyx_t_2;
                 __pyx_t_2 = 0;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1854
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1856
  *                                     pair_count = 0
  *                                 for phrase2, eindexes in phrase_list:
  *                                     als4 = self.create_alignments(sent_links,num_links,self.findexes,eindexes)             # <<<<<<<<<<<<<<
@@ -57445,31 +57513,31 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
                 __pyx_t_15 = ((PyObject *)__pyx_v_self->findexes);
                 __Pyx_INCREF(__pyx_t_15);
-                __pyx_t_2 = ((PyObject *)((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->create_alignments(__pyx_v_self, __pyx_v_sent_links, __pyx_v_num_links, __pyx_t_15, __pyx_v_eindexes)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1854; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_2 = ((PyObject *)((struct __pyx_vtabstruct_3_sa_HieroCachingRuleFactory *)__pyx_v_self->__pyx_vtab)->create_alignments(__pyx_v_self, __pyx_v_sent_links, __pyx_v_num_links, __pyx_t_15, __pyx_v_eindexes)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1856; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_2);
                 __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
                 __Pyx_XDECREF(((PyObject *)__pyx_v_als4));
                 __pyx_v_als4 = ((struct __pyx_obj_3_sa_IntList *)__pyx_t_2);
                 __pyx_t_2 = 0;
 
-                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1855
+                /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1857
  *                                 for phrase2, eindexes in phrase_list:
  *                                     als4 = self.create_alignments(sent_links,num_links,self.findexes,eindexes)
  *                                     extracts.append((fphr, phrase2, pair_count, tuple(als4)))             # <<<<<<<<<<<<<<
  *             else:
  *                 reason_for_failure = "Unable to extract basic phrase"
  */
-                __pyx_t_2 = PyFloat_FromDouble(__pyx_v_pair_count); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_2 = PyFloat_FromDouble(__pyx_v_pair_count); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1857; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_2);
-                __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1857; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_15);
                 __Pyx_INCREF(((PyObject *)__pyx_v_als4));
                 PyTuple_SET_ITEM(__pyx_t_15, 0, ((PyObject *)__pyx_v_als4));
                 __Pyx_GIVEREF(((PyObject *)__pyx_v_als4));
-                __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1857; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_1);
                 __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
-                __pyx_t_15 = PyTuple_New(4); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_15 = PyTuple_New(4); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1857; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_15);
                 __Pyx_INCREF(((PyObject *)__pyx_v_fphr));
                 PyTuple_SET_ITEM(__pyx_t_15, 0, ((PyObject *)__pyx_v_fphr));
@@ -57483,7 +57551,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
                 __Pyx_GIVEREF(__pyx_t_1);
                 __pyx_t_2 = 0;
                 __pyx_t_1 = 0;
-                __pyx_t_1 = __Pyx_PyObject_Append(__pyx_v_extracts, ((PyObject *)__pyx_t_15)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+                __pyx_t_1 = __Pyx_PyObject_Append(__pyx_v_extracts, ((PyObject *)__pyx_t_15)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1857; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
                 __Pyx_GOTREF(__pyx_t_1);
                 __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
                 __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -57505,7 +57573,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
     }
     /*else*/ {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1857
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1859
  *                                     extracts.append((fphr, phrase2, pair_count, tuple(als4)))
  *             else:
  *                 reason_for_failure = "Unable to extract basic phrase"             # <<<<<<<<<<<<<<
@@ -57521,7 +57589,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
   }
   __pyx_L33:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1859
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1861
  *                 reason_for_failure = "Unable to extract basic phrase"
  * 
  *         free(sent_links)             # <<<<<<<<<<<<<<
@@ -57530,7 +57598,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   free(__pyx_v_sent_links);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1860
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1862
  * 
  *         free(sent_links)
  *         free(f_links_low)             # <<<<<<<<<<<<<<
@@ -57539,7 +57607,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   free(__pyx_v_f_links_low);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1861
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1863
  *         free(sent_links)
  *         free(f_links_low)
  *         free(f_links_high)             # <<<<<<<<<<<<<<
@@ -57548,7 +57616,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   free(__pyx_v_f_links_high);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1862
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1864
  *         free(f_links_low)
  *         free(f_links_high)
  *         free(e_links_low)             # <<<<<<<<<<<<<<
@@ -57557,7 +57625,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   free(__pyx_v_e_links_low);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1863
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1865
  *         free(f_links_high)
  *         free(e_links_low)
  *         free(e_links_high)             # <<<<<<<<<<<<<<
@@ -57566,7 +57634,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   free(__pyx_v_e_links_high);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1864
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1866
  *         free(e_links_low)
  *         free(e_links_high)
  *         free(f_gap_low)             # <<<<<<<<<<<<<<
@@ -57575,7 +57643,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   free(__pyx_v_f_gap_low);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1865
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1867
  *         free(e_links_high)
  *         free(f_gap_low)
  *         free(f_gap_high)             # <<<<<<<<<<<<<<
@@ -57584,7 +57652,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   free(__pyx_v_f_gap_high);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1866
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1868
  *         free(f_gap_low)
  *         free(f_gap_high)
  *         free(e_gap_low)             # <<<<<<<<<<<<<<
@@ -57593,7 +57661,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   free(__pyx_v_e_gap_low);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1867
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1869
  *         free(f_gap_high)
  *         free(e_gap_low)
  *         free(e_gap_high)             # <<<<<<<<<<<<<<
@@ -57602,7 +57670,7 @@ static PyObject *__pyx_f_3_sa_23HieroCachingRuleFactory_extract(struct __pyx_obj
  */
   free(__pyx_v_e_gap_high);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1869
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1871
  *         free(e_gap_high)
  * 
  *         return extracts             # <<<<<<<<<<<<<<
@@ -57674,16 +57742,16 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_26add_instance(PyObject
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__e_words)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("add_instance", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1877; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("add_instance", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1879; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__alignment)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("add_instance", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1877; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("add_instance", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1879; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add_instance") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1877; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add_instance") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1879; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
       goto __pyx_L5_argtuple_error;
@@ -57698,7 +57766,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_26add_instance(PyObject
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("add_instance", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1877; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("add_instance", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1879; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.add_instance", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -57752,46 +57820,46 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_12add_instance_1extract
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__f_j)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__e_i)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  3:
         if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__e_j)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 3); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 3); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  4:
         if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__min_bound)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 4); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 4); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  5:
         if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__wc)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 5); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 5); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  6:
         if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__links)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 6); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 6); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  7:
         if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__nt)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 7); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 7); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  8:
         if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__nt_open)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 8); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, 8); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "extract") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "extract") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
       goto __pyx_L5_argtuple_error;
@@ -57818,7 +57886,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_12add_instance_1extract
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("extract", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.add_instance.extract", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -57829,7 +57897,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_12add_instance_1extract
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1911
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1913
  *         # f_ i and j are current, e_ i and j are previous
  *         # We care _considering_ f_j, so it is not yet in counts
  *         def extract(f_i, f_j, e_i, e_j, min_bound, wc, links, nt, nt_open):             # <<<<<<<<<<<<<<
@@ -57875,33 +57943,33 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   __pyx_outer_scope = (struct __pyx_obj_3_sa___pyx_scope_struct_21_add_instance *) __Pyx_CyFunction_GetClosure(__pyx_self);
   __pyx_cur_scope = __pyx_outer_scope;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1913
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1915
  *         def extract(f_i, f_j, e_i, e_j, min_bound, wc, links, nt, nt_open):
  *             # Phrase extraction limits
  *             if f_j > (f_len - 1) or (f_j - f_i) + 1 > self.max_initial_size:             # <<<<<<<<<<<<<<
  *                 return
  *             # Unaligned word
  */
-  if (unlikely(!__pyx_cur_scope->__pyx_v_f_len)) { __Pyx_RaiseClosureNameError("f_len"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-  __pyx_t_1 = PyNumber_Subtract(__pyx_cur_scope->__pyx_v_f_len, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__pyx_cur_scope->__pyx_v_f_len)) { __Pyx_RaiseClosureNameError("f_len"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1915; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+  __pyx_t_1 = PyNumber_Subtract(__pyx_cur_scope->__pyx_v_f_len, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1915; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_RichCompare(__pyx_v_f_j, __pyx_t_1, Py_GT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_RichCompare(__pyx_v_f_j, __pyx_t_1, Py_GT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1915; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1915; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   if (!__pyx_t_3) {
-    __pyx_t_2 = PyNumber_Subtract(__pyx_v_f_j, __pyx_v_f_i); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyNumber_Subtract(__pyx_v_f_j, __pyx_v_f_i); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1915; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1915; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    if (unlikely(!__pyx_cur_scope->__pyx_v_self)) { __Pyx_RaiseClosureNameError("self"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-    __pyx_t_2 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_initial_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_cur_scope->__pyx_v_self)) { __Pyx_RaiseClosureNameError("self"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1915; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+    __pyx_t_2 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_initial_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1915; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_4 = PyObject_RichCompare(__pyx_t_1, __pyx_t_2, Py_GT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_RichCompare(__pyx_t_1, __pyx_t_2, Py_GT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1915; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1915; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __pyx_t_6 = __pyx_t_5;
   } else {
@@ -57909,7 +57977,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   }
   if (__pyx_t_6) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1914
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1916
  *             # Phrase extraction limits
  *             if f_j > (f_len - 1) or (f_j - f_i) + 1 > self.max_initial_size:
  *                 return             # <<<<<<<<<<<<<<
@@ -57923,41 +57991,41 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1916
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1918
  *                 return
  *             # Unaligned word
  *             if not al[f_j]:             # <<<<<<<<<<<<<<
  *                 # Adjacent to non-terminal: extend (non-terminal now open)
  *                 if nt and nt[-1][2] == f_j - 1:
  */
-  if (unlikely(!__pyx_cur_scope->__pyx_v_al)) { __Pyx_RaiseClosureNameError("al"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1916; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-  __pyx_t_4 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_al, __pyx_v_f_j); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1916; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__pyx_cur_scope->__pyx_v_al)) { __Pyx_RaiseClosureNameError("al"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1918; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+  __pyx_t_4 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_al, __pyx_v_f_j); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1916; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_3 = (!__pyx_t_6);
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1918
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1920
  *             if not al[f_j]:
  *                 # Adjacent to non-terminal: extend (non-terminal now open)
  *                 if nt and nt[-1][2] == f_j - 1:             # <<<<<<<<<<<<<<
  *                     nt[-1][2] += 1
  *                     extract(f_i, f_j + 1, e_i, e_j, min_bound, wc, links, nt, True)
  */
-    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_nt); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_nt); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1920; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     if (__pyx_t_3) {
-      __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1920; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_4, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_4, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1920; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_4 = PyNumber_Subtract(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyNumber_Subtract(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1920; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1920; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1920; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       __pyx_t_5 = __pyx_t_6;
     } else {
@@ -57965,38 +58033,38 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     }
     if (__pyx_t_5) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1919
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1921
  *                 # Adjacent to non-terminal: extend (non-terminal now open)
  *                 if nt and nt[-1][2] == f_j - 1:
  *                     nt[-1][2] += 1             # <<<<<<<<<<<<<<
  *                     extract(f_i, f_j + 1, e_i, e_j, min_bound, wc, links, nt, True)
  *                     nt[-1][2] -= 1
  */
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1919; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __pyx_t_7 = 2;
-      __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_1, __pyx_t_7, sizeof(Py_ssize_t), PyInt_FromSsize_t); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1919; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_1, __pyx_t_7, sizeof(Py_ssize_t), PyInt_FromSsize_t); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1919; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      if (__Pyx_SetItemInt(__pyx_t_1, __pyx_t_7, __pyx_t_2, sizeof(Py_ssize_t), PyInt_FromSsize_t) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1919; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (__Pyx_SetItemInt(__pyx_t_1, __pyx_t_7, __pyx_t_2, sizeof(Py_ssize_t), PyInt_FromSsize_t) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1920
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1922
  *                 if nt and nt[-1][2] == f_j - 1:
  *                     nt[-1][2] += 1
  *                     extract(f_i, f_j + 1, e_i, e_j, min_bound, wc, links, nt, True)             # <<<<<<<<<<<<<<
  *                     nt[-1][2] -= 1
  *                 # Unless non-terminal already open, always extend with word
  */
-      if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1920; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_1 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1920; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1922; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_1 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_2 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1920; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_4 = PyTuple_New(9); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1920; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyTuple_New(9); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_INCREF(__pyx_v_f_i);
       PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_f_i);
@@ -58025,48 +58093,48 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       __Pyx_GIVEREF(__pyx_t_2);
       __pyx_t_1 = 0;
       __pyx_t_2 = 0;
-      __pyx_t_2 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1920; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1921
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1923
  *                     nt[-1][2] += 1
  *                     extract(f_i, f_j + 1, e_i, e_j, min_bound, wc, links, nt, True)
  *                     nt[-1][2] -= 1             # <<<<<<<<<<<<<<
  *                 # Unless non-terminal already open, always extend with word
  *                 # Make sure adding a word doesn't exceed length
  */
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __pyx_t_7 = 2;
-      __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_2, __pyx_t_7, sizeof(Py_ssize_t), PyInt_FromSsize_t); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_2, __pyx_t_7, sizeof(Py_ssize_t), PyInt_FromSsize_t); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_1 = PyNumber_InPlaceSubtract(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyNumber_InPlaceSubtract(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      if (__Pyx_SetItemInt(__pyx_t_2, __pyx_t_7, __pyx_t_1, sizeof(Py_ssize_t), PyInt_FromSsize_t) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (__Pyx_SetItemInt(__pyx_t_2, __pyx_t_7, __pyx_t_1, sizeof(Py_ssize_t), PyInt_FromSsize_t) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       goto __pyx_L5;
     }
     __pyx_L5:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1924
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1926
  *                 # Unless non-terminal already open, always extend with word
  *                 # Make sure adding a word doesn't exceed length
  *                 if not nt_open and wc < self.max_length:             # <<<<<<<<<<<<<<
  *                     extract(f_i, f_j + 1, e_i, e_j, min_bound, wc + 1, links, nt, False)
  *                 return
  */
-    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_nt_open); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_nt_open); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1926; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __pyx_t_3 = (!__pyx_t_5);
     if (__pyx_t_3) {
-      __pyx_t_2 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_length); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_length); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1926; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_1 = PyObject_RichCompare(__pyx_v_wc, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_RichCompare(__pyx_v_wc, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1926; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1926; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       __pyx_t_6 = __pyx_t_5;
     } else {
@@ -58074,21 +58142,21 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     }
     if (__pyx_t_6) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1925
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1927
  *                 # Make sure adding a word doesn't exceed length
  *                 if not nt_open and wc < self.max_length:
  *                     extract(f_i, f_j + 1, e_i, e_j, min_bound, wc + 1, links, nt, False)             # <<<<<<<<<<<<<<
  *                 return
  *             # Aligned word
  */
-      if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1925; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_1 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1927; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_1 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1927; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_2 = PyNumber_Add(__pyx_v_wc, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_Add(__pyx_v_wc, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1927; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_4 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1927; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_8 = PyTuple_New(9); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyTuple_New(9); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1927; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_INCREF(__pyx_v_f_i);
       PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_f_i);
@@ -58117,7 +58185,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       __pyx_t_1 = 0;
       __pyx_t_2 = 0;
       __pyx_t_4 = 0;
-      __pyx_t_4 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1927; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(((PyObject *)__pyx_t_8)); __pyx_t_8 = 0;
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
@@ -58125,7 +58193,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     }
     __pyx_L6:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1926
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1928
  *                 if not nt_open and wc < self.max_length:
  *                     extract(f_i, f_j + 1, e_i, e_j, min_bound, wc + 1, links, nt, False)
  *                 return             # <<<<<<<<<<<<<<
@@ -58139,38 +58207,38 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   }
   __pyx_L4:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1928
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1930
  *                 return
  *             # Aligned word
  *             link_i = fe_span[f_j][0]             # <<<<<<<<<<<<<<
  *             link_j = fe_span[f_j][1]
  *             new_e_i = min(link_i, e_i)
  */
-  if (unlikely(!__pyx_cur_scope->__pyx_v_fe_span)) { __Pyx_RaiseClosureNameError("fe_span"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1928; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-  __pyx_t_4 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fe_span, __pyx_v_f_j); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1928; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__pyx_cur_scope->__pyx_v_fe_span)) { __Pyx_RaiseClosureNameError("fe_span"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1930; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+  __pyx_t_4 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fe_span, __pyx_v_f_j); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1930; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_8 = __Pyx_GetItemInt(__pyx_t_4, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1928; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_8 = __Pyx_GetItemInt(__pyx_t_4, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1930; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_8);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_v_link_i = __pyx_t_8;
   __pyx_t_8 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1929
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1931
  *             # Aligned word
  *             link_i = fe_span[f_j][0]
  *             link_j = fe_span[f_j][1]             # <<<<<<<<<<<<<<
  *             new_e_i = min(link_i, e_i)
  *             new_e_j = max(link_j, e_j)
  */
-  __pyx_t_8 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fe_span, __pyx_v_f_j); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_8 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fe_span, __pyx_v_f_j); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_8);
-  __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_8, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_8, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
   __pyx_v_link_j = __pyx_t_4;
   __pyx_t_4 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1930
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1932
  *             link_i = fe_span[f_j][0]
  *             link_j = fe_span[f_j][1]
  *             new_e_i = min(link_i, e_i)             # <<<<<<<<<<<<<<
@@ -58181,8 +58249,8 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   __pyx_t_4 = __pyx_v_e_i;
   __Pyx_INCREF(__pyx_v_link_i);
   __pyx_t_8 = __pyx_v_link_i;
-  __pyx_t_1 = PyObject_RichCompare(__pyx_t_4, __pyx_t_8, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1930; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1930; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_RichCompare(__pyx_t_4, __pyx_t_8, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1932; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1932; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   if (__pyx_t_6) {
     __Pyx_INCREF(__pyx_t_4);
@@ -58197,7 +58265,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   __pyx_v_new_e_i = __pyx_t_2;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1931
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1933
  *             link_j = fe_span[f_j][1]
  *             new_e_i = min(link_i, e_i)
  *             new_e_j = max(link_j, e_j)             # <<<<<<<<<<<<<<
@@ -58208,8 +58276,8 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   __pyx_t_2 = __pyx_v_e_j;
   __Pyx_INCREF(__pyx_v_link_j);
   __pyx_t_4 = __pyx_v_link_j;
-  __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_4, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_4, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1933; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1933; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   if (__pyx_t_6) {
     __Pyx_INCREF(__pyx_t_2);
@@ -58224,7 +58292,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   __pyx_v_new_e_j = __pyx_t_8;
   __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1934
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1936
  *             # Check reverse links of newly covered words to see if they violate left
  *             # bound (return) or extend minimum right bound for chunk
  *             new_min_bound = min_bound             # <<<<<<<<<<<<<<
@@ -58234,54 +58302,54 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   __Pyx_INCREF(__pyx_v_min_bound);
   __pyx_v_new_min_bound = __pyx_v_min_bound;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1936
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1938
  *             new_min_bound = min_bound
  *             # First aligned word creates span
  *             if e_j == -1:             # <<<<<<<<<<<<<<
  *                 for i from new_e_i <= i <= new_e_j:
  *                     if ef_span[i][0] < f_i:
  */
-  __pyx_t_8 = PyObject_RichCompare(__pyx_v_e_j, __pyx_int_neg_1, Py_EQ); __Pyx_XGOTREF(__pyx_t_8); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1936; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1936; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_8 = PyObject_RichCompare(__pyx_v_e_j, __pyx_int_neg_1, Py_EQ); __Pyx_XGOTREF(__pyx_t_8); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
   if (__pyx_t_6) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1937
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1939
  *             # First aligned word creates span
  *             if e_j == -1:
  *                 for i from new_e_i <= i <= new_e_j:             # <<<<<<<<<<<<<<
  *                     if ef_span[i][0] < f_i:
  *                         return
  */
-    __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_v_new_e_i); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1937; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_10 = __Pyx_PyInt_AsInt(__pyx_v_new_e_j); if (unlikely((__pyx_t_10 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1937; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_v_new_e_i); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1939; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = __Pyx_PyInt_AsInt(__pyx_v_new_e_j); if (unlikely((__pyx_t_10 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1939; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     for (__pyx_t_11 = __pyx_t_9; __pyx_t_11 <= __pyx_t_10; __pyx_t_11++) {
-      __pyx_t_8 = PyInt_FromLong(__pyx_t_11); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1937; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyInt_FromLong(__pyx_t_11); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1939; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_XDECREF(__pyx_v_i);
       __pyx_v_i = __pyx_t_8;
       __pyx_t_8 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1938
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1940
  *             if e_j == -1:
  *                 for i from new_e_i <= i <= new_e_j:
  *                     if ef_span[i][0] < f_i:             # <<<<<<<<<<<<<<
  *                         return
  *                     new_min_bound = max(new_min_bound, ef_span[i][1])
  */
-      if (unlikely(!__pyx_cur_scope->__pyx_v_ef_span)) { __Pyx_RaiseClosureNameError("ef_span"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1938; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_8 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_i); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_ef_span)) { __Pyx_RaiseClosureNameError("ef_span"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1940; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_8 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_i); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_8, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_8, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-      __pyx_t_8 = PyObject_RichCompare(__pyx_t_2, __pyx_v_f_i, Py_LT); __Pyx_XGOTREF(__pyx_t_8); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyObject_RichCompare(__pyx_t_2, __pyx_v_f_i, Py_LT); __Pyx_XGOTREF(__pyx_t_8); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       if (__pyx_t_6) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1939
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1941
  *                 for i from new_e_i <= i <= new_e_j:
  *                     if ef_span[i][0] < f_i:
  *                         return             # <<<<<<<<<<<<<<
@@ -58295,22 +58363,22 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       }
       __pyx_L10:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1940
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1942
  *                     if ef_span[i][0] < f_i:
  *                         return
  *                     new_min_bound = max(new_min_bound, ef_span[i][1])             # <<<<<<<<<<<<<<
  *             # Other aligned words extend span
  *             else:
  */
-      __pyx_t_8 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_i); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_i); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1942; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_8, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_8, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1942; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       __Pyx_INCREF(__pyx_v_new_min_bound);
       __pyx_t_8 = __pyx_v_new_min_bound;
-      __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_8, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_8, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1942; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1942; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       if (__pyx_t_6) {
         __Pyx_INCREF(__pyx_t_2);
@@ -58325,17 +58393,17 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       __Pyx_DECREF(__pyx_v_new_min_bound);
       __pyx_v_new_min_bound = __pyx_t_4;
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_11 = __Pyx_PyInt_AsInt(__pyx_v_i); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1937; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_11 = __Pyx_PyInt_AsInt(__pyx_v_i); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1939; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1937
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1939
  *             # First aligned word creates span
  *             if e_j == -1:
  *                 for i from new_e_i <= i <= new_e_j:             # <<<<<<<<<<<<<<
  *                     if ef_span[i][0] < f_i:
  *                         return
  */
-    __pyx_t_4 = PyInt_FromLong(__pyx_t_11); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1937; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyInt_FromLong(__pyx_t_11); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1939; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_XDECREF(__pyx_v_i);
     __pyx_v_i = __pyx_t_4;
@@ -58344,42 +58412,42 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   }
   /*else*/ {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1943
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1945
  *             # Other aligned words extend span
  *             else:
  *                 for i from new_e_i <= i < e_i:             # <<<<<<<<<<<<<<
  *                     if ef_span[i][0] < f_i:
  *                         return
  */
-    __pyx_t_11 = __Pyx_PyInt_AsInt(__pyx_v_new_e_i); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_10 = __Pyx_PyInt_AsInt(__pyx_v_e_i); if (unlikely((__pyx_t_10 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_11 = __Pyx_PyInt_AsInt(__pyx_v_new_e_i); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = __Pyx_PyInt_AsInt(__pyx_v_e_i); if (unlikely((__pyx_t_10 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     for (__pyx_t_9 = __pyx_t_11; __pyx_t_9 < __pyx_t_10; __pyx_t_9++) {
-      __pyx_t_4 = PyInt_FromLong(__pyx_t_9); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyInt_FromLong(__pyx_t_9); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_XDECREF(__pyx_v_i);
       __pyx_v_i = __pyx_t_4;
       __pyx_t_4 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1944
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1946
  *             else:
  *                 for i from new_e_i <= i < e_i:
  *                     if ef_span[i][0] < f_i:             # <<<<<<<<<<<<<<
  *                         return
  *                     new_min_bound = max(new_min_bound, ef_span[i][1])
  */
-      if (unlikely(!__pyx_cur_scope->__pyx_v_ef_span)) { __Pyx_RaiseClosureNameError("ef_span"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1944; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_4 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_i); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_ef_span)) { __Pyx_RaiseClosureNameError("ef_span"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1946; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_4 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_i); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_4, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_4, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_4 = PyObject_RichCompare(__pyx_t_2, __pyx_v_f_i, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_RichCompare(__pyx_t_2, __pyx_v_f_i, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       if (__pyx_t_6) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1945
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1947
  *                 for i from new_e_i <= i < e_i:
  *                     if ef_span[i][0] < f_i:
  *                         return             # <<<<<<<<<<<<<<
@@ -58393,22 +58461,22 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       }
       __pyx_L13:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1946
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1948
  *                     if ef_span[i][0] < f_i:
  *                         return
  *                     new_min_bound = max(new_min_bound, ef_span[i][1])             # <<<<<<<<<<<<<<
  *                 for i from e_j < i <= new_e_j:
  *                     if ef_span[i][0] < f_i:
  */
-      __pyx_t_4 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_i); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_i); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1948; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_4, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_4, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1948; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_INCREF(__pyx_v_new_min_bound);
       __pyx_t_4 = __pyx_v_new_min_bound;
-      __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_4, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_4, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1948; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1948; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       if (__pyx_t_6) {
         __Pyx_INCREF(__pyx_t_2);
@@ -58423,58 +58491,58 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       __Pyx_DECREF(__pyx_v_new_min_bound);
       __pyx_v_new_min_bound = __pyx_t_8;
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-      __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_v_i); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_v_i); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1943
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1945
  *             # Other aligned words extend span
  *             else:
  *                 for i from new_e_i <= i < e_i:             # <<<<<<<<<<<<<<
  *                     if ef_span[i][0] < f_i:
  *                         return
  */
-    __pyx_t_8 = PyInt_FromLong(__pyx_t_9); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1943; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyInt_FromLong(__pyx_t_9); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
     __Pyx_XDECREF(__pyx_v_i);
     __pyx_v_i = __pyx_t_8;
     __pyx_t_8 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1947
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1949
  *                         return
  *                     new_min_bound = max(new_min_bound, ef_span[i][1])
  *                 for i from e_j < i <= new_e_j:             # <<<<<<<<<<<<<<
  *                     if ef_span[i][0] < f_i:
  *                         return
  */
-    __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_v_e_j); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_10 = __Pyx_PyInt_AsInt(__pyx_v_new_e_j); if (unlikely((__pyx_t_10 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_v_e_j); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1949; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = __Pyx_PyInt_AsInt(__pyx_v_new_e_j); if (unlikely((__pyx_t_10 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1949; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     for (__pyx_t_11 = __pyx_t_9+1; __pyx_t_11 <= __pyx_t_10; __pyx_t_11++) {
-      __pyx_t_8 = PyInt_FromLong(__pyx_t_11); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyInt_FromLong(__pyx_t_11); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1949; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_XDECREF(__pyx_v_i);
       __pyx_v_i = __pyx_t_8;
       __pyx_t_8 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1948
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1950
  *                     new_min_bound = max(new_min_bound, ef_span[i][1])
  *                 for i from e_j < i <= new_e_j:
  *                     if ef_span[i][0] < f_i:             # <<<<<<<<<<<<<<
  *                         return
  *                     new_min_bound = max(new_min_bound, ef_span[i][1])
  */
-      if (unlikely(!__pyx_cur_scope->__pyx_v_ef_span)) { __Pyx_RaiseClosureNameError("ef_span"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1948; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_8 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_i); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1948; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_ef_span)) { __Pyx_RaiseClosureNameError("ef_span"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1950; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_8 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_i); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1950; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_8, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1948; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_8, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1950; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-      __pyx_t_8 = PyObject_RichCompare(__pyx_t_2, __pyx_v_f_i, Py_LT); __Pyx_XGOTREF(__pyx_t_8); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1948; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyObject_RichCompare(__pyx_t_2, __pyx_v_f_i, Py_LT); __Pyx_XGOTREF(__pyx_t_8); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1950; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1948; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1950; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       if (__pyx_t_6) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1949
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1951
  *                 for i from e_j < i <= new_e_j:
  *                     if ef_span[i][0] < f_i:
  *                         return             # <<<<<<<<<<<<<<
@@ -58488,22 +58556,22 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       }
       __pyx_L16:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1950
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1952
  *                     if ef_span[i][0] < f_i:
  *                         return
  *                     new_min_bound = max(new_min_bound, ef_span[i][1])             # <<<<<<<<<<<<<<
  *             # Extract, extend with word (unless non-terminal open)
  *             if not nt_open:
  */
-      __pyx_t_8 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_i); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1950; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_i); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1952; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_8, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1950; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_8, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1952; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       __Pyx_INCREF(__pyx_v_new_min_bound);
       __pyx_t_8 = __pyx_v_new_min_bound;
-      __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_8, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1950; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1950; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_8, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1952; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1952; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       if (__pyx_t_6) {
         __Pyx_INCREF(__pyx_t_2);
@@ -58518,17 +58586,17 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       __Pyx_DECREF(__pyx_v_new_min_bound);
       __pyx_v_new_min_bound = __pyx_t_4;
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_11 = __Pyx_PyInt_AsInt(__pyx_v_i); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_11 = __Pyx_PyInt_AsInt(__pyx_v_i); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1949; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1947
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1949
  *                         return
  *                     new_min_bound = max(new_min_bound, ef_span[i][1])
  *                 for i from e_j < i <= new_e_j:             # <<<<<<<<<<<<<<
  *                     if ef_span[i][0] < f_i:
  *                         return
  */
-    __pyx_t_4 = PyInt_FromLong(__pyx_t_11); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyInt_FromLong(__pyx_t_11); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1949; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_XDECREF(__pyx_v_i);
     __pyx_v_i = __pyx_t_4;
@@ -58536,18 +58604,18 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   }
   __pyx_L7:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1952
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1954
  *                     new_min_bound = max(new_min_bound, ef_span[i][1])
  *             # Extract, extend with word (unless non-terminal open)
  *             if not nt_open:             # <<<<<<<<<<<<<<
  *                 nt_collision = False
  *                 for link in al[f_j]:
  */
-  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_nt_open); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1952; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_nt_open); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1954; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_t_3 = (!__pyx_t_6);
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1953
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1955
  *             # Extract, extend with word (unless non-terminal open)
  *             if not nt_open:
  *                 nt_collision = False             # <<<<<<<<<<<<<<
@@ -58556,20 +58624,20 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
  */
     __pyx_v_nt_collision = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1954
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1956
  *             if not nt_open:
  *                 nt_collision = False
  *                 for link in al[f_j]:             # <<<<<<<<<<<<<<
  *                     if e_nt_cover[link]:
  *                         nt_collision = True
  */
-    __pyx_t_4 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_al, __pyx_v_f_j); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1954; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_al, __pyx_v_f_j); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     if (PyList_CheckExact(__pyx_t_4) || PyTuple_CheckExact(__pyx_t_4)) {
       __pyx_t_2 = __pyx_t_4; __Pyx_INCREF(__pyx_t_2); __pyx_t_7 = 0;
       __pyx_t_12 = NULL;
     } else {
-      __pyx_t_7 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1954; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __pyx_t_12 = Py_TYPE(__pyx_t_2)->tp_iternext;
     }
@@ -58578,23 +58646,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       if (!__pyx_t_12 && PyList_CheckExact(__pyx_t_2)) {
         if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_2)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_4 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_7); __Pyx_INCREF(__pyx_t_4); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1954; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_7); __Pyx_INCREF(__pyx_t_4); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1954; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else if (!__pyx_t_12 && PyTuple_CheckExact(__pyx_t_2)) {
         if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_7); __Pyx_INCREF(__pyx_t_4); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1954; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_7); __Pyx_INCREF(__pyx_t_4); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1954; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else {
         __pyx_t_4 = __pyx_t_12(__pyx_t_2);
         if (unlikely(!__pyx_t_4)) {
           if (PyErr_Occurred()) {
             if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1954; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           }
           break;
         }
@@ -58604,21 +58672,21 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       __pyx_v_link = __pyx_t_4;
       __pyx_t_4 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1955
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1957
  *                 nt_collision = False
  *                 for link in al[f_j]:
  *                     if e_nt_cover[link]:             # <<<<<<<<<<<<<<
  *                         nt_collision = True
  *                 # Non-terminal collisions block word extraction and extension, but
  */
-      if (unlikely(!__pyx_cur_scope->__pyx_v_e_nt_cover)) { __Pyx_RaiseClosureNameError("e_nt_cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1955; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_4 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_e_nt_cover, __pyx_v_link); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1955; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_e_nt_cover)) { __Pyx_RaiseClosureNameError("e_nt_cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1957; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_4 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_e_nt_cover, __pyx_v_link); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1955; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       if (__pyx_t_3) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1956
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1958
  *                 for link in al[f_j]:
  *                     if e_nt_cover[link]:
  *                         nt_collision = True             # <<<<<<<<<<<<<<
@@ -58632,7 +58700,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     }
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1959
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1961
  *                 # Non-terminal collisions block word extraction and extension, but
  *                 # may be okay for continuing non-terminals
  *                 if not nt_collision and wc < self.max_length:             # <<<<<<<<<<<<<<
@@ -58641,11 +58709,11 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
  */
     __pyx_t_3 = (!__pyx_v_nt_collision);
     if (__pyx_t_3) {
-      __pyx_t_2 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_length); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1959; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_length); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_4 = PyObject_RichCompare(__pyx_v_wc, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1959; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_wc, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1959; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __pyx_t_5 = __pyx_t_6;
     } else {
@@ -58653,32 +58721,32 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     }
     if (__pyx_t_5) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1960
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1962
  *                 # may be okay for continuing non-terminals
  *                 if not nt_collision and wc < self.max_length:
  *                     plus_links = []             # <<<<<<<<<<<<<<
  *                     for link in al[f_j]:
  *                         plus_links.append((f_j, link))
  */
-      __pyx_t_4 = PyList_New(0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1960; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyList_New(0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1962; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __pyx_v_plus_links = __pyx_t_4;
       __pyx_t_4 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1961
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1963
  *                 if not nt_collision and wc < self.max_length:
  *                     plus_links = []
  *                     for link in al[f_j]:             # <<<<<<<<<<<<<<
  *                         plus_links.append((f_j, link))
  *                         cover[link] += 1
  */
-      __pyx_t_4 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_al, __pyx_v_f_j); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_al, __pyx_v_f_j); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1963; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       if (PyList_CheckExact(__pyx_t_4) || PyTuple_CheckExact(__pyx_t_4)) {
         __pyx_t_2 = __pyx_t_4; __Pyx_INCREF(__pyx_t_2); __pyx_t_7 = 0;
         __pyx_t_12 = NULL;
       } else {
-        __pyx_t_7 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1963; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
         __pyx_t_12 = Py_TYPE(__pyx_t_2)->tp_iternext;
       }
@@ -58687,23 +58755,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
         if (!__pyx_t_12 && PyList_CheckExact(__pyx_t_2)) {
           if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_2)) break;
           #if CYTHON_COMPILING_IN_CPYTHON
-          __pyx_t_4 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_7); __Pyx_INCREF(__pyx_t_4); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_4 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_7); __Pyx_INCREF(__pyx_t_4); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1963; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           #else
-          __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1963; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           #endif
         } else if (!__pyx_t_12 && PyTuple_CheckExact(__pyx_t_2)) {
           if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
           #if CYTHON_COMPILING_IN_CPYTHON
-          __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_7); __Pyx_INCREF(__pyx_t_4); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_7); __Pyx_INCREF(__pyx_t_4); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1963; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           #else
-          __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1963; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           #endif
         } else {
           __pyx_t_4 = __pyx_t_12(__pyx_t_2);
           if (unlikely(!__pyx_t_4)) {
             if (PyErr_Occurred()) {
               if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-              else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1961; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1963; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             }
             break;
           }
@@ -58713,14 +58781,14 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
         __pyx_v_link = __pyx_t_4;
         __pyx_t_4 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1962
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1964
  *                     plus_links = []
  *                     for link in al[f_j]:
  *                         plus_links.append((f_j, link))             # <<<<<<<<<<<<<<
  *                         cover[link] += 1
  *                     links.append(plus_links)
  */
-        __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1962; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1964; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_INCREF(__pyx_v_f_j);
         PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_f_j);
@@ -58728,10 +58796,10 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
         __Pyx_INCREF(__pyx_v_link);
         PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_v_link);
         __Pyx_GIVEREF(__pyx_v_link);
-        __pyx_t_13 = PyList_Append(__pyx_v_plus_links, ((PyObject *)__pyx_t_4)); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1962; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_13 = PyList_Append(__pyx_v_plus_links, ((PyObject *)__pyx_t_4)); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1964; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1963
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1965
  *                     for link in al[f_j]:
  *                         plus_links.append((f_j, link))
  *                         cover[link] += 1             # <<<<<<<<<<<<<<
@@ -58740,41 +58808,41 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
  */
         __Pyx_INCREF(__pyx_v_link);
         __pyx_t_4 = __pyx_v_link;
-        if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1963; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-        __pyx_t_8 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_cover, __pyx_t_4); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1963; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1965; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+        __pyx_t_8 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_cover, __pyx_t_4); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1965; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_8);
-        __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_t_8, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1963; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_t_8, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1965; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-        if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1963; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-        if (PyObject_SetItem(__pyx_cur_scope->__pyx_v_cover, __pyx_t_4, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1963; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1965; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+        if (PyObject_SetItem(__pyx_cur_scope->__pyx_v_cover, __pyx_t_4, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1965; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       }
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1964
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1966
  *                         plus_links.append((f_j, link))
  *                         cover[link] += 1
  *                     links.append(plus_links)             # <<<<<<<<<<<<<<
  *                     if links and f_j >= new_min_bound:
  *                         rules.add(self.form_rule(f_i, new_e_i, f_words[f_i:f_j + 1], e_words[new_e_i:new_e_j + 1], nt, links))
  */
-      __pyx_t_2 = __Pyx_PyObject_Append(__pyx_v_links, ((PyObject *)__pyx_v_plus_links)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1964; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_PyObject_Append(__pyx_v_links, ((PyObject *)__pyx_v_plus_links)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1965
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1967
  *                         cover[link] += 1
  *                     links.append(plus_links)
  *                     if links and f_j >= new_min_bound:             # <<<<<<<<<<<<<<
  *                         rules.add(self.form_rule(f_i, new_e_i, f_words[f_i:f_j + 1], e_words[new_e_i:new_e_j + 1], nt, links))
  *                     extract(f_i, f_j + 1, new_e_i, new_e_j, new_min_bound, wc + 1, links, nt, False)
  */
-      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_links); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1965; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_links); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       if (__pyx_t_5) {
-        __pyx_t_2 = PyObject_RichCompare(__pyx_v_f_j, __pyx_v_new_min_bound, Py_GE); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1965; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1965; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_2 = PyObject_RichCompare(__pyx_v_f_j, __pyx_v_new_min_bound, Py_GE); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_t_6 = __pyx_t_3;
       } else {
@@ -58782,35 +58850,35 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       }
       if (__pyx_t_6) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1966
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1968
  *                     links.append(plus_links)
  *                     if links and f_j >= new_min_bound:
  *                         rules.add(self.form_rule(f_i, new_e_i, f_words[f_i:f_j + 1], e_words[new_e_i:new_e_j + 1], nt, links))             # <<<<<<<<<<<<<<
  *                     extract(f_i, f_j + 1, new_e_i, new_e_j, new_min_bound, wc + 1, links, nt, False)
  *                     links.pop()
  */
-        if (unlikely(!__pyx_cur_scope->__pyx_v_rules)) { __Pyx_RaiseClosureNameError("rules"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-        __pyx_t_2 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_rules, __pyx_n_s__add); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (unlikely(!__pyx_cur_scope->__pyx_v_rules)) { __Pyx_RaiseClosureNameError("rules"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1968; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+        __pyx_t_2 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_rules, __pyx_n_s__add); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
-        __pyx_t_4 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__form_rule); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__form_rule); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_4);
-        if (unlikely(!__pyx_cur_scope->__pyx_v_f_words)) { __Pyx_RaiseClosureNameError("f_words"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-        __pyx_t_7 = __Pyx_PyIndex_AsSsize_t(__pyx_v_f_i); if (unlikely((__pyx_t_7 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __pyx_t_1 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (unlikely(!__pyx_cur_scope->__pyx_v_f_words)) { __Pyx_RaiseClosureNameError("f_words"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1968; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+        __pyx_t_7 = __Pyx_PyIndex_AsSsize_t(__pyx_v_f_i); if (unlikely((__pyx_t_7 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
-        __pyx_t_14 = __Pyx_PyIndex_AsSsize_t(__pyx_t_1); if (unlikely((__pyx_t_14 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_14 = __Pyx_PyIndex_AsSsize_t(__pyx_t_1); if (unlikely((__pyx_t_14 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-        __pyx_t_1 = __Pyx_PySequence_GetSlice(__pyx_cur_scope->__pyx_v_f_words, __pyx_t_7, __pyx_t_14); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = __Pyx_PySequence_GetSlice(__pyx_cur_scope->__pyx_v_f_words, __pyx_t_7, __pyx_t_14); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
-        if (unlikely(!__pyx_cur_scope->__pyx_v_e_words)) { __Pyx_RaiseClosureNameError("e_words"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-        __pyx_t_14 = __Pyx_PyIndex_AsSsize_t(__pyx_v_new_e_i); if (unlikely((__pyx_t_14 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __pyx_t_8 = PyNumber_Add(__pyx_v_new_e_j, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (unlikely(!__pyx_cur_scope->__pyx_v_e_words)) { __Pyx_RaiseClosureNameError("e_words"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1968; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+        __pyx_t_14 = __Pyx_PyIndex_AsSsize_t(__pyx_v_new_e_i); if (unlikely((__pyx_t_14 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_8 = PyNumber_Add(__pyx_v_new_e_j, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_8);
-        __pyx_t_7 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_7 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_7 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-        __pyx_t_8 = __Pyx_PySequence_GetSlice(__pyx_cur_scope->__pyx_v_e_words, __pyx_t_14, __pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_8 = __Pyx_PySequence_GetSlice(__pyx_cur_scope->__pyx_v_e_words, __pyx_t_14, __pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_8);
-        __pyx_t_15 = PyTuple_New(6); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_15 = PyTuple_New(6); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_15);
         __Pyx_INCREF(__pyx_v_f_i);
         PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_v_f_i);
@@ -58830,16 +58898,16 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
         __Pyx_GIVEREF(__pyx_v_links);
         __pyx_t_1 = 0;
         __pyx_t_8 = 0;
-        __pyx_t_8 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_8 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
         __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
-        __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_15);
         PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_8);
         __pyx_t_8 = 0;
-        __pyx_t_8 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1966; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_8 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
@@ -58848,21 +58916,21 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       }
       __pyx_L24:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1967
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1969
  *                     if links and f_j >= new_min_bound:
  *                         rules.add(self.form_rule(f_i, new_e_i, f_words[f_i:f_j + 1], e_words[new_e_i:new_e_j + 1], nt, links))
  *                     extract(f_i, f_j + 1, new_e_i, new_e_j, new_min_bound, wc + 1, links, nt, False)             # <<<<<<<<<<<<<<
  *                     links.pop()
  *                     for link in al[f_j]:
  */
-      if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1967; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_8 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1969; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_8 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
-      __pyx_t_15 = PyNumber_Add(__pyx_v_wc, __pyx_int_1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = PyNumber_Add(__pyx_v_wc, __pyx_int_1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
-      __pyx_t_2 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_4 = PyTuple_New(9); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyTuple_New(9); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_INCREF(__pyx_v_f_i);
       PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_f_i);
@@ -58891,36 +58959,36 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       __pyx_t_8 = 0;
       __pyx_t_15 = 0;
       __pyx_t_2 = 0;
-      __pyx_t_2 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1968
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1970
  *                         rules.add(self.form_rule(f_i, new_e_i, f_words[f_i:f_j + 1], e_words[new_e_i:new_e_j + 1], nt, links))
  *                     extract(f_i, f_j + 1, new_e_i, new_e_j, new_min_bound, wc + 1, links, nt, False)
  *                     links.pop()             # <<<<<<<<<<<<<<
  *                     for link in al[f_j]:
  *                         cover[link] -= 1
  */
-      __pyx_t_2 = __Pyx_PyObject_Pop(__pyx_v_links); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_PyObject_Pop(__pyx_v_links); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1970; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1969
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1971
  *                     extract(f_i, f_j + 1, new_e_i, new_e_j, new_min_bound, wc + 1, links, nt, False)
  *                     links.pop()
  *                     for link in al[f_j]:             # <<<<<<<<<<<<<<
  *                         cover[link] -= 1
  *             # Try to add a word to current non-terminal (if any), extract, extend
  */
-      __pyx_t_2 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_al, __pyx_v_f_j); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_al, __pyx_v_f_j); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1971; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       if (PyList_CheckExact(__pyx_t_2) || PyTuple_CheckExact(__pyx_t_2)) {
         __pyx_t_4 = __pyx_t_2; __Pyx_INCREF(__pyx_t_4); __pyx_t_7 = 0;
         __pyx_t_12 = NULL;
       } else {
-        __pyx_t_7 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1971; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_4);
         __pyx_t_12 = Py_TYPE(__pyx_t_4)->tp_iternext;
       }
@@ -58929,23 +58997,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
         if (!__pyx_t_12 && PyList_CheckExact(__pyx_t_4)) {
           if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_4)) break;
           #if CYTHON_COMPILING_IN_CPYTHON
-          __pyx_t_2 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_7); __Pyx_INCREF(__pyx_t_2); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_2 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_7); __Pyx_INCREF(__pyx_t_2); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1971; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           #else
-          __pyx_t_2 = PySequence_ITEM(__pyx_t_4, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_2 = PySequence_ITEM(__pyx_t_4, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1971; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           #endif
         } else if (!__pyx_t_12 && PyTuple_CheckExact(__pyx_t_4)) {
           if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
           #if CYTHON_COMPILING_IN_CPYTHON
-          __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_7); __Pyx_INCREF(__pyx_t_2); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_7); __Pyx_INCREF(__pyx_t_2); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1971; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           #else
-          __pyx_t_2 = PySequence_ITEM(__pyx_t_4, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __pyx_t_2 = PySequence_ITEM(__pyx_t_4, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1971; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           #endif
         } else {
           __pyx_t_2 = __pyx_t_12(__pyx_t_4);
           if (unlikely(!__pyx_t_2)) {
             if (PyErr_Occurred()) {
               if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-              else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+              else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1971; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
             }
             break;
           }
@@ -58955,7 +59023,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
         __pyx_v_link = __pyx_t_2;
         __pyx_t_2 = 0;
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1970
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1972
  *                     links.pop()
  *                     for link in al[f_j]:
  *                         cover[link] -= 1             # <<<<<<<<<<<<<<
@@ -58964,14 +59032,14 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
  */
         __Pyx_INCREF(__pyx_v_link);
         __pyx_t_2 = __pyx_v_link;
-        if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1970; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-        __pyx_t_15 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_cover, __pyx_t_2); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1970; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1972; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+        __pyx_t_15 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_cover, __pyx_t_2); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_15);
-        __pyx_t_8 = PyNumber_InPlaceSubtract(__pyx_t_15, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1970; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_8 = PyNumber_InPlaceSubtract(__pyx_t_15, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
-        if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1970; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-        if (PyObject_SetItem(__pyx_cur_scope->__pyx_v_cover, __pyx_t_2, __pyx_t_8) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1970; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1972; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+        if (PyObject_SetItem(__pyx_cur_scope->__pyx_v_cover, __pyx_t_2, __pyx_t_8) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       }
@@ -58983,26 +59051,26 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   }
   __pyx_L17:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1972
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1974
  *                         cover[link] -= 1
  *             # Try to add a word to current non-terminal (if any), extract, extend
  *             if nt and nt[-1][2] == f_j - 1:             # <<<<<<<<<<<<<<
  *                 # Add to non-terminal, checking for collisions
  *                 old_last_nt = nt[-1][:]
  */
-  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_nt); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_nt); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1974; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   if (__pyx_t_6) {
-    __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1974; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_4, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_4, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1974; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = PyNumber_Subtract(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyNumber_Subtract(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1974; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_8 = PyObject_RichCompare(__pyx_t_2, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_8); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyObject_RichCompare(__pyx_t_2, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_8); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1974; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1974; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
     __pyx_t_3 = __pyx_t_5;
   } else {
@@ -59010,70 +59078,70 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   }
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1974
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1976
  *             if nt and nt[-1][2] == f_j - 1:
  *                 # Add to non-terminal, checking for collisions
  *                 old_last_nt = nt[-1][:]             # <<<<<<<<<<<<<<
  *                 nt[-1][2] = f_j
  *                 if link_i < nt[-1][3]:
  */
-    __pyx_t_8 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1974; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1976; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
-    __pyx_t_4 = __Pyx_PySequence_GetSlice(__pyx_t_8, 0, PY_SSIZE_T_MAX); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1974; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_PySequence_GetSlice(__pyx_t_8, 0, PY_SSIZE_T_MAX); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1976; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
     __pyx_v_old_last_nt = __pyx_t_4;
     __pyx_t_4 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1975
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1977
  *                 # Add to non-terminal, checking for collisions
  *                 old_last_nt = nt[-1][:]
  *                 nt[-1][2] = f_j             # <<<<<<<<<<<<<<
  *                 if link_i < nt[-1][3]:
  *                     if not span_check(cover, link_i, nt[-1][3] - 1):
  */
-    __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1975; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    if (__Pyx_SetItemInt(__pyx_t_4, 2, __pyx_v_f_j, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1975; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (__Pyx_SetItemInt(__pyx_t_4, 2, __pyx_v_f_j, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1976
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1978
  *                 old_last_nt = nt[-1][:]
  *                 nt[-1][2] = f_j
  *                 if link_i < nt[-1][3]:             # <<<<<<<<<<<<<<
  *                     if not span_check(cover, link_i, nt[-1][3] - 1):
  *                         nt[-1] = old_last_nt
  */
-    __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1976; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1978; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_8 = __Pyx_GetItemInt(__pyx_t_4, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1976; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = __Pyx_GetItemInt(__pyx_t_4, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1978; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = PyObject_RichCompare(__pyx_v_link_i, __pyx_t_8, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1976; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_RichCompare(__pyx_v_link_i, __pyx_t_8, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1978; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1976; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1978; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     if (__pyx_t_3) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1977
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1979
  *                 nt[-1][2] = f_j
  *                 if link_i < nt[-1][3]:
  *                     if not span_check(cover, link_i, nt[-1][3] - 1):             # <<<<<<<<<<<<<<
  *                         nt[-1] = old_last_nt
  *                         return
  */
-      __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_check); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_check); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1979; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_8 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1979; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_8 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1979; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_8, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_8, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1979; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-      __pyx_t_8 = PyNumber_Subtract(__pyx_t_2, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyNumber_Subtract(__pyx_t_2, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1979; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1979; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_INCREF(__pyx_cur_scope->__pyx_v_cover);
       PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_cur_scope->__pyx_v_cover);
@@ -59084,25 +59152,25 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_t_8);
       __Pyx_GIVEREF(__pyx_t_8);
       __pyx_t_8 = 0;
-      __pyx_t_8 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1979; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
-      __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1979; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       __pyx_t_6 = (!__pyx_t_3);
       if (__pyx_t_6) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1978
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1980
  *                 if link_i < nt[-1][3]:
  *                     if not span_check(cover, link_i, nt[-1][3] - 1):
  *                         nt[-1] = old_last_nt             # <<<<<<<<<<<<<<
  *                         return
  *                     span_inc(cover, link_i, nt[-1][3] - 1)
  */
-        if (__Pyx_SetItemInt(__pyx_v_nt, -1, __pyx_v_old_last_nt, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1978; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (__Pyx_SetItemInt(__pyx_v_nt, -1, __pyx_v_old_last_nt, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1979
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1981
  *                     if not span_check(cover, link_i, nt[-1][3] - 1):
  *                         nt[-1] = old_last_nt
  *                         return             # <<<<<<<<<<<<<<
@@ -59116,24 +59184,24 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       }
       __pyx_L29:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1980
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1982
  *                         nt[-1] = old_last_nt
  *                         return
  *                     span_inc(cover, link_i, nt[-1][3] - 1)             # <<<<<<<<<<<<<<
  *                     span_inc(e_nt_cover, link_i, nt[-1][3] - 1)
  *                     nt[-1][3] = link_i
  */
-      __pyx_t_8 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_inc); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_inc); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_2, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_2, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_2 = PyNumber_Subtract(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_Subtract(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_INCREF(__pyx_cur_scope->__pyx_v_cover);
       PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_cur_scope->__pyx_v_cover);
@@ -59144,31 +59212,31 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_t_2);
       __Pyx_GIVEREF(__pyx_t_2);
       __pyx_t_2 = 0;
-      __pyx_t_2 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1981
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1983
  *                         return
  *                     span_inc(cover, link_i, nt[-1][3] - 1)
  *                     span_inc(e_nt_cover, link_i, nt[-1][3] - 1)             # <<<<<<<<<<<<<<
  *                     nt[-1][3] = link_i
  *                 if link_j > nt[-1][4]:
  */
-      __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_inc); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_inc); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1983; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      if (unlikely(!__pyx_cur_scope->__pyx_v_e_nt_cover)) { __Pyx_RaiseClosureNameError("e_nt_cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1981; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_e_nt_cover)) { __Pyx_RaiseClosureNameError("e_nt_cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1983; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1983; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_8 = __Pyx_GetItemInt(__pyx_t_4, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = __Pyx_GetItemInt(__pyx_t_4, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1983; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_4 = PyNumber_Subtract(__pyx_t_8, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyNumber_Subtract(__pyx_t_8, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1983; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-      __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1983; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e_nt_cover);
       PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_cur_scope->__pyx_v_e_nt_cover);
@@ -59179,64 +59247,64 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_t_4);
       __Pyx_GIVEREF(__pyx_t_4);
       __pyx_t_4 = 0;
-      __pyx_t_4 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1983; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_8)); __pyx_t_8 = 0;
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1982
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1984
  *                     span_inc(cover, link_i, nt[-1][3] - 1)
  *                     span_inc(e_nt_cover, link_i, nt[-1][3] - 1)
  *                     nt[-1][3] = link_i             # <<<<<<<<<<<<<<
  *                 if link_j > nt[-1][4]:
  *                     if not span_check(cover, nt[-1][4] + 1, link_j):
  */
-      __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      if (__Pyx_SetItemInt(__pyx_t_4, 3, __pyx_v_link_i, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (__Pyx_SetItemInt(__pyx_t_4, 3, __pyx_v_link_i, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       goto __pyx_L28;
     }
     __pyx_L28:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1983
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1985
  *                     span_inc(e_nt_cover, link_i, nt[-1][3] - 1)
  *                     nt[-1][3] = link_i
  *                 if link_j > nt[-1][4]:             # <<<<<<<<<<<<<<
  *                     if not span_check(cover, nt[-1][4] + 1, link_j):
  *                         nt[-1] = old_last_nt
  */
-    __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1983; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1985; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_8 = __Pyx_GetItemInt(__pyx_t_4, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1983; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = __Pyx_GetItemInt(__pyx_t_4, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1985; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = PyObject_RichCompare(__pyx_v_link_j, __pyx_t_8, Py_GT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1983; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_RichCompare(__pyx_v_link_j, __pyx_t_8, Py_GT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1985; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-    __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1983; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1985; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     if (__pyx_t_6) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1984
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1986
  *                     nt[-1][3] = link_i
  *                 if link_j > nt[-1][4]:
  *                     if not span_check(cover, nt[-1][4] + 1, link_j):             # <<<<<<<<<<<<<<
  *                         nt[-1] = old_last_nt
  *                         return
  */
-      __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_check); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_check); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1986; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1984; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_8 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1986; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_8 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1986; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_8, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_8, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1986; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-      __pyx_t_8 = PyNumber_Add(__pyx_t_2, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyNumber_Add(__pyx_t_2, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1986; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1986; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_INCREF(__pyx_cur_scope->__pyx_v_cover);
       PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_cur_scope->__pyx_v_cover);
@@ -59247,25 +59315,25 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_v_link_j);
       __Pyx_GIVEREF(__pyx_v_link_j);
       __pyx_t_8 = 0;
-      __pyx_t_8 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1986; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1986; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       __pyx_t_3 = (!__pyx_t_6);
       if (__pyx_t_3) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1985
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1987
  *                 if link_j > nt[-1][4]:
  *                     if not span_check(cover, nt[-1][4] + 1, link_j):
  *                         nt[-1] = old_last_nt             # <<<<<<<<<<<<<<
  *                         return
  *                     span_inc(cover, nt[-1][4] + 1, link_j)
  */
-        if (__Pyx_SetItemInt(__pyx_v_nt, -1, __pyx_v_old_last_nt, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1985; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (__Pyx_SetItemInt(__pyx_v_nt, -1, __pyx_v_old_last_nt, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1987; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1986
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1988
  *                     if not span_check(cover, nt[-1][4] + 1, link_j):
  *                         nt[-1] = old_last_nt
  *                         return             # <<<<<<<<<<<<<<
@@ -59279,24 +59347,24 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       }
       __pyx_L31:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1987
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1989
  *                         nt[-1] = old_last_nt
  *                         return
  *                     span_inc(cover, nt[-1][4] + 1, link_j)             # <<<<<<<<<<<<<<
  *                     span_inc(e_nt_cover, nt[-1][4] + 1, link_j)
  *                     nt[-1][4] = link_j
  */
-      __pyx_t_8 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_inc); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1987; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_inc); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1987; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_2, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1987; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_2, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_2 = PyNumber_Add(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1987; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_Add(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1987; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_INCREF(__pyx_cur_scope->__pyx_v_cover);
       PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_cur_scope->__pyx_v_cover);
@@ -59307,31 +59375,31 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_v_link_j);
       __Pyx_GIVEREF(__pyx_v_link_j);
       __pyx_t_2 = 0;
-      __pyx_t_2 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1987; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1988
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1990
  *                         return
  *                     span_inc(cover, nt[-1][4] + 1, link_j)
  *                     span_inc(e_nt_cover, nt[-1][4] + 1, link_j)             # <<<<<<<<<<<<<<
  *                     nt[-1][4] = link_j
  *                 if links and f_j >= new_min_bound:
  */
-      __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_inc); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1988; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_inc); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1990; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      if (unlikely(!__pyx_cur_scope->__pyx_v_e_nt_cover)) { __Pyx_RaiseClosureNameError("e_nt_cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1988; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1988; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_e_nt_cover)) { __Pyx_RaiseClosureNameError("e_nt_cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1990; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1990; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_8 = __Pyx_GetItemInt(__pyx_t_4, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1988; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = __Pyx_GetItemInt(__pyx_t_4, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1990; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_4 = PyNumber_Add(__pyx_t_8, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1988; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyNumber_Add(__pyx_t_8, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1990; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-      __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1988; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1990; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e_nt_cover);
       PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_cur_scope->__pyx_v_e_nt_cover);
@@ -59342,38 +59410,38 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_v_link_j);
       __Pyx_GIVEREF(__pyx_v_link_j);
       __pyx_t_4 = 0;
-      __pyx_t_4 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1988; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1990; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_8)); __pyx_t_8 = 0;
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1989
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1991
  *                     span_inc(cover, nt[-1][4] + 1, link_j)
  *                     span_inc(e_nt_cover, nt[-1][4] + 1, link_j)
  *                     nt[-1][4] = link_j             # <<<<<<<<<<<<<<
  *                 if links and f_j >= new_min_bound:
  *                     rules.add(self.form_rule(f_i, new_e_i, f_words[f_i:f_j + 1], e_words[new_e_i:new_e_j + 1], nt, links))
  */
-      __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      if (__Pyx_SetItemInt(__pyx_t_4, 4, __pyx_v_link_j, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (__Pyx_SetItemInt(__pyx_t_4, 4, __pyx_v_link_j, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       goto __pyx_L30;
     }
     __pyx_L30:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1990
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1992
  *                     span_inc(e_nt_cover, nt[-1][4] + 1, link_j)
  *                     nt[-1][4] = link_j
  *                 if links and f_j >= new_min_bound:             # <<<<<<<<<<<<<<
  *                     rules.add(self.form_rule(f_i, new_e_i, f_words[f_i:f_j + 1], e_words[new_e_i:new_e_j + 1], nt, links))
  *                 extract(f_i, f_j + 1, new_e_i, new_e_j, new_min_bound, wc, links, nt, False)
  */
-    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_links); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1990; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_links); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1992; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     if (__pyx_t_3) {
-      __pyx_t_4 = PyObject_RichCompare(__pyx_v_f_j, __pyx_v_new_min_bound, Py_GE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1990; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1990; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_f_j, __pyx_v_new_min_bound, Py_GE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1992; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1992; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __pyx_t_5 = __pyx_t_6;
     } else {
@@ -59381,35 +59449,35 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     }
     if (__pyx_t_5) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1991
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1993
  *                     nt[-1][4] = link_j
  *                 if links and f_j >= new_min_bound:
  *                     rules.add(self.form_rule(f_i, new_e_i, f_words[f_i:f_j + 1], e_words[new_e_i:new_e_j + 1], nt, links))             # <<<<<<<<<<<<<<
  *                 extract(f_i, f_j + 1, new_e_i, new_e_j, new_min_bound, wc, links, nt, False)
  *                 nt[-1] = old_last_nt
  */
-      if (unlikely(!__pyx_cur_scope->__pyx_v_rules)) { __Pyx_RaiseClosureNameError("rules"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_4 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_rules, __pyx_n_s__add); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_rules)) { __Pyx_RaiseClosureNameError("rules"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1993; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_4 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_rules, __pyx_n_s__add); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_8 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__form_rule); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__form_rule); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
-      if (unlikely(!__pyx_cur_scope->__pyx_v_f_words)) { __Pyx_RaiseClosureNameError("f_words"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_7 = __Pyx_PyIndex_AsSsize_t(__pyx_v_f_i); if (unlikely((__pyx_t_7 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_2 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_f_words)) { __Pyx_RaiseClosureNameError("f_words"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1993; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_7 = __Pyx_PyIndex_AsSsize_t(__pyx_v_f_i); if (unlikely((__pyx_t_7 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_14 = __Pyx_PyIndex_AsSsize_t(__pyx_t_2); if (unlikely((__pyx_t_14 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_14 = __Pyx_PyIndex_AsSsize_t(__pyx_t_2); if (unlikely((__pyx_t_14 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_2 = __Pyx_PySequence_GetSlice(__pyx_cur_scope->__pyx_v_f_words, __pyx_t_7, __pyx_t_14); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_PySequence_GetSlice(__pyx_cur_scope->__pyx_v_f_words, __pyx_t_7, __pyx_t_14); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      if (unlikely(!__pyx_cur_scope->__pyx_v_e_words)) { __Pyx_RaiseClosureNameError("e_words"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_14 = __Pyx_PyIndex_AsSsize_t(__pyx_v_new_e_i); if (unlikely((__pyx_t_14 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_15 = PyNumber_Add(__pyx_v_new_e_j, __pyx_int_1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_e_words)) { __Pyx_RaiseClosureNameError("e_words"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1993; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_14 = __Pyx_PyIndex_AsSsize_t(__pyx_v_new_e_i); if (unlikely((__pyx_t_14 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = PyNumber_Add(__pyx_v_new_e_j, __pyx_int_1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
-      __pyx_t_7 = __Pyx_PyIndex_AsSsize_t(__pyx_t_15); if (unlikely((__pyx_t_7 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = __Pyx_PyIndex_AsSsize_t(__pyx_t_15); if (unlikely((__pyx_t_7 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
-      __pyx_t_15 = __Pyx_PySequence_GetSlice(__pyx_cur_scope->__pyx_v_e_words, __pyx_t_14, __pyx_t_7); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = __Pyx_PySequence_GetSlice(__pyx_cur_scope->__pyx_v_e_words, __pyx_t_14, __pyx_t_7); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
-      __pyx_t_1 = PyTuple_New(6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyTuple_New(6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_INCREF(__pyx_v_f_i);
       PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_f_i);
@@ -59429,16 +59497,16 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       __Pyx_GIVEREF(__pyx_v_links);
       __pyx_t_2 = 0;
       __pyx_t_15 = 0;
-      __pyx_t_15 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-      __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_15);
       __Pyx_GIVEREF(__pyx_t_15);
       __pyx_t_15 = 0;
-      __pyx_t_15 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
@@ -59447,19 +59515,19 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     }
     __pyx_L32:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1992
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1994
  *                 if links and f_j >= new_min_bound:
  *                     rules.add(self.form_rule(f_i, new_e_i, f_words[f_i:f_j + 1], e_words[new_e_i:new_e_j + 1], nt, links))
  *                 extract(f_i, f_j + 1, new_e_i, new_e_j, new_min_bound, wc, links, nt, False)             # <<<<<<<<<<<<<<
  *                 nt[-1] = old_last_nt
  *                 if link_i < nt[-1][3]:
  */
-    if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1992; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-    __pyx_t_15 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1992; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1994; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+    __pyx_t_15 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_15);
-    __pyx_t_1 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1992; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_4 = PyTuple_New(9); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1992; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyTuple_New(9); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_INCREF(__pyx_v_f_i);
     PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_f_i);
@@ -59488,57 +59556,57 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     __Pyx_GIVEREF(__pyx_t_1);
     __pyx_t_15 = 0;
     __pyx_t_1 = 0;
-    __pyx_t_1 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1992; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1993
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1995
  *                     rules.add(self.form_rule(f_i, new_e_i, f_words[f_i:f_j + 1], e_words[new_e_i:new_e_j + 1], nt, links))
  *                 extract(f_i, f_j + 1, new_e_i, new_e_j, new_min_bound, wc, links, nt, False)
  *                 nt[-1] = old_last_nt             # <<<<<<<<<<<<<<
  *                 if link_i < nt[-1][3]:
  *                     span_dec(cover, link_i, nt[-1][3] - 1)
  */
-    if (__Pyx_SetItemInt(__pyx_v_nt, -1, __pyx_v_old_last_nt, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (__Pyx_SetItemInt(__pyx_v_nt, -1, __pyx_v_old_last_nt, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1994
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1996
  *                 extract(f_i, f_j + 1, new_e_i, new_e_j, new_min_bound, wc, links, nt, False)
  *                 nt[-1] = old_last_nt
  *                 if link_i < nt[-1][3]:             # <<<<<<<<<<<<<<
  *                     span_dec(cover, link_i, nt[-1][3] - 1)
  *                     span_dec(e_nt_cover, link_i, nt[-1][3] - 1)
  */
-    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_1, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_1, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __pyx_t_1 = PyObject_RichCompare(__pyx_v_link_i, __pyx_t_4, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_RichCompare(__pyx_v_link_i, __pyx_t_4, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1994; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     if (__pyx_t_5) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1995
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1997
  *                 nt[-1] = old_last_nt
  *                 if link_i < nt[-1][3]:
  *                     span_dec(cover, link_i, nt[-1][3] - 1)             # <<<<<<<<<<<<<<
  *                     span_dec(e_nt_cover, link_i, nt[-1][3] - 1)
  *                 if link_j > nt[-1][4]:
  */
-      __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_dec); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_dec); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1997; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1995; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1997; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1997; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_15 = __Pyx_GetItemInt(__pyx_t_4, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = __Pyx_GetItemInt(__pyx_t_4, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1997; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_4 = PyNumber_Subtract(__pyx_t_15, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyNumber_Subtract(__pyx_t_15, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1997; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
-      __pyx_t_15 = PyTuple_New(3); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = PyTuple_New(3); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1997; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
       __Pyx_INCREF(__pyx_cur_scope->__pyx_v_cover);
       PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_cur_scope->__pyx_v_cover);
@@ -59549,31 +59617,31 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       PyTuple_SET_ITEM(__pyx_t_15, 2, __pyx_t_4);
       __Pyx_GIVEREF(__pyx_t_4);
       __pyx_t_4 = 0;
-      __pyx_t_4 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1995; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1997; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1996
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1998
  *                 if link_i < nt[-1][3]:
  *                     span_dec(cover, link_i, nt[-1][3] - 1)
  *                     span_dec(e_nt_cover, link_i, nt[-1][3] - 1)             # <<<<<<<<<<<<<<
  *                 if link_j > nt[-1][4]:
  *                     span_dec(cover, nt[-1][4] + 1, link_j)
  */
-      __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_dec); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_dec); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      if (unlikely(!__pyx_cur_scope->__pyx_v_e_nt_cover)) { __Pyx_RaiseClosureNameError("e_nt_cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_15 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_e_nt_cover)) { __Pyx_RaiseClosureNameError("e_nt_cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1998; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_15 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_15, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_15, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
-      __pyx_t_15 = PyNumber_Subtract(__pyx_t_1, __pyx_int_1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = PyNumber_Subtract(__pyx_t_1, __pyx_int_1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e_nt_cover);
       PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_cur_scope->__pyx_v_e_nt_cover);
@@ -59584,7 +59652,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_t_15);
       __Pyx_GIVEREF(__pyx_t_15);
       __pyx_t_15 = 0;
-      __pyx_t_15 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1996; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
@@ -59593,43 +59661,43 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     }
     __pyx_L33:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1997
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1999
  *                     span_dec(cover, link_i, nt[-1][3] - 1)
  *                     span_dec(e_nt_cover, link_i, nt[-1][3] - 1)
  *                 if link_j > nt[-1][4]:             # <<<<<<<<<<<<<<
  *                     span_dec(cover, nt[-1][4] + 1, link_j)
  *                     span_dec(e_nt_cover, nt[-1][4] + 1, link_j)
  */
-    __pyx_t_15 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1997; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_15 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_15);
-    __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_15, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1997; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_15, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
-    __pyx_t_15 = PyObject_RichCompare(__pyx_v_link_j, __pyx_t_1, Py_GT); __Pyx_XGOTREF(__pyx_t_15); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1997; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_15 = PyObject_RichCompare(__pyx_v_link_j, __pyx_t_1, Py_GT); __Pyx_XGOTREF(__pyx_t_15); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_15); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1997; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_15); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
     if (__pyx_t_5) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1998
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2000
  *                     span_dec(e_nt_cover, link_i, nt[-1][3] - 1)
  *                 if link_j > nt[-1][4]:
  *                     span_dec(cover, nt[-1][4] + 1, link_j)             # <<<<<<<<<<<<<<
  *                     span_dec(e_nt_cover, nt[-1][4] + 1, link_j)
  *             # Try to start a new non-terminal, extract, extend
  */
-      __pyx_t_15 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_dec); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_dec); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2000; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
-      if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1998; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2000; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2000; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_1, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_1, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2000; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_1 = PyNumber_Add(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyNumber_Add(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2000; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2000; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_INCREF(__pyx_cur_scope->__pyx_v_cover);
       PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_cur_scope->__pyx_v_cover);
@@ -59640,31 +59708,31 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_v_link_j);
       __Pyx_GIVEREF(__pyx_v_link_j);
       __pyx_t_1 = 0;
-      __pyx_t_1 = PyObject_Call(__pyx_t_15, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_Call(__pyx_t_15, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2000; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1999
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2001
  *                 if link_j > nt[-1][4]:
  *                     span_dec(cover, nt[-1][4] + 1, link_j)
  *                     span_dec(e_nt_cover, nt[-1][4] + 1, link_j)             # <<<<<<<<<<<<<<
  *             # Try to start a new non-terminal, extract, extend
  *             if (not nt or f_j - nt[-1][2] > 1) and wc < self.max_length and len(nt) < self.max_nonterminals:
  */
-      __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_dec); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_dec); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      if (unlikely(!__pyx_cur_scope->__pyx_v_e_nt_cover)) { __Pyx_RaiseClosureNameError("e_nt_cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1999; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_e_nt_cover)) { __Pyx_RaiseClosureNameError("e_nt_cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2001; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_15 = __Pyx_GetItemInt(__pyx_t_4, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = __Pyx_GetItemInt(__pyx_t_4, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_4 = PyNumber_Add(__pyx_t_15, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyNumber_Add(__pyx_t_15, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
-      __pyx_t_15 = PyTuple_New(3); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = PyTuple_New(3); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
       __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e_nt_cover);
       PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_cur_scope->__pyx_v_e_nt_cover);
@@ -59675,7 +59743,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       PyTuple_SET_ITEM(__pyx_t_15, 2, __pyx_v_link_j);
       __Pyx_GIVEREF(__pyx_v_link_j);
       __pyx_t_4 = 0;
-      __pyx_t_4 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1999; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
@@ -59687,41 +59755,41 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   }
   __pyx_L27:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2001
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2003
  *                     span_dec(e_nt_cover, nt[-1][4] + 1, link_j)
  *             # Try to start a new non-terminal, extract, extend
  *             if (not nt or f_j - nt[-1][2] > 1) and wc < self.max_length and len(nt) < self.max_nonterminals:             # <<<<<<<<<<<<<<
  *                 # Check for collisions
  *                 if not span_check(cover, link_i, link_j):
  */
-  __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_nt); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_nt); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2003; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_t_3 = (!__pyx_t_5);
   if (!__pyx_t_3) {
-    __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2003; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_15 = __Pyx_GetItemInt(__pyx_t_4, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_15 = __Pyx_GetItemInt(__pyx_t_4, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2003; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_15);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = PyNumber_Subtract(__pyx_v_f_j, __pyx_t_15); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyNumber_Subtract(__pyx_v_f_j, __pyx_t_15); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2003; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
-    __pyx_t_15 = PyObject_RichCompare(__pyx_t_4, __pyx_int_1, Py_GT); __Pyx_XGOTREF(__pyx_t_15); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_15 = PyObject_RichCompare(__pyx_t_4, __pyx_int_1, Py_GT); __Pyx_XGOTREF(__pyx_t_15); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2003; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_15); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_15); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2003; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
     __pyx_t_6 = __pyx_t_5;
   } else {
     __pyx_t_6 = __pyx_t_3;
   }
   if (__pyx_t_6) {
-    __pyx_t_15 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_length); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_15 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_length); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2003; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_15);
-    __pyx_t_4 = PyObject_RichCompare(__pyx_v_wc, __pyx_t_15, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_RichCompare(__pyx_v_wc, __pyx_t_15, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2003; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
-    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2003; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     if (__pyx_t_3) {
-      __pyx_t_7 = PyObject_Length(__pyx_v_nt); if (unlikely(__pyx_t_7 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyObject_Length(__pyx_v_nt); if (unlikely(__pyx_t_7 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2003; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_t_5 = (__pyx_t_7 < __pyx_cur_scope->__pyx_v_self->max_nonterminals);
       __pyx_t_16 = __pyx_t_5;
     } else {
@@ -59733,17 +59801,17 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   }
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2003
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2005
  *             if (not nt or f_j - nt[-1][2] > 1) and wc < self.max_length and len(nt) < self.max_nonterminals:
  *                 # Check for collisions
  *                 if not span_check(cover, link_i, link_j):             # <<<<<<<<<<<<<<
  *                     return
  *                 span_inc(cover, link_i, link_j)
  */
-    __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_check); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2003; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_check); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2005; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2003; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-    __pyx_t_15 = PyTuple_New(3); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2003; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_cur_scope->__pyx_v_cover)) { __Pyx_RaiseClosureNameError("cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2005; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+    __pyx_t_15 = PyTuple_New(3); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2005; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_15);
     __Pyx_INCREF(__pyx_cur_scope->__pyx_v_cover);
     PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_cur_scope->__pyx_v_cover);
@@ -59754,16 +59822,16 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     __Pyx_INCREF(__pyx_v_link_j);
     PyTuple_SET_ITEM(__pyx_t_15, 2, __pyx_v_link_j);
     __Pyx_GIVEREF(__pyx_v_link_j);
-    __pyx_t_1 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2003; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2005; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
-    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2003; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2005; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __pyx_t_6 = (!__pyx_t_3);
     if (__pyx_t_6) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2004
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2006
  *                 # Check for collisions
  *                 if not span_check(cover, link_i, link_j):
  *                     return             # <<<<<<<<<<<<<<
@@ -59777,16 +59845,16 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     }
     __pyx_L36:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2005
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2007
  *                 if not span_check(cover, link_i, link_j):
  *                     return
  *                 span_inc(cover, link_i, link_j)             # <<<<<<<<<<<<<<
  *                 span_inc(e_nt_cover, link_i, link_j)
  *                 nt.append([(nt[-1][0] + 1) if nt else 1, f_j, f_j, link_i, link_j])
  */
-    __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_inc); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2005; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_inc); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_15 = PyTuple_New(3); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2005; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_15 = PyTuple_New(3); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_15);
     __Pyx_INCREF(__pyx_cur_scope->__pyx_v_cover);
     PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_cur_scope->__pyx_v_cover);
@@ -59797,23 +59865,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     __Pyx_INCREF(__pyx_v_link_j);
     PyTuple_SET_ITEM(__pyx_t_15, 2, __pyx_v_link_j);
     __Pyx_GIVEREF(__pyx_v_link_j);
-    __pyx_t_4 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2005; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2006
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2008
  *                     return
  *                 span_inc(cover, link_i, link_j)
  *                 span_inc(e_nt_cover, link_i, link_j)             # <<<<<<<<<<<<<<
  *                 nt.append([(nt[-1][0] + 1) if nt else 1, f_j, f_j, link_i, link_j])
  *                 # Require at least one word in phrase
  */
-    __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_inc); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2006; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_inc); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2008; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    if (unlikely(!__pyx_cur_scope->__pyx_v_e_nt_cover)) { __Pyx_RaiseClosureNameError("e_nt_cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2006; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-    __pyx_t_15 = PyTuple_New(3); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2006; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_cur_scope->__pyx_v_e_nt_cover)) { __Pyx_RaiseClosureNameError("e_nt_cover"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2008; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+    __pyx_t_15 = PyTuple_New(3); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2008; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_15);
     __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e_nt_cover);
     PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_cur_scope->__pyx_v_e_nt_cover);
@@ -59824,27 +59892,27 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     __Pyx_INCREF(__pyx_v_link_j);
     PyTuple_SET_ITEM(__pyx_t_15, 2, __pyx_v_link_j);
     __Pyx_GIVEREF(__pyx_v_link_j);
-    __pyx_t_1 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2006; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2008; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2007
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2009
  *                 span_inc(cover, link_i, link_j)
  *                 span_inc(e_nt_cover, link_i, link_j)
  *                 nt.append([(nt[-1][0] + 1) if nt else 1, f_j, f_j, link_i, link_j])             # <<<<<<<<<<<<<<
  *                 # Require at least one word in phrase
  *                 if links and f_j >= new_min_bound:
  */
-    __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_nt); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_nt); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2009; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     if (__pyx_t_6) {
-      __pyx_t_15 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_15) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2009; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
-      __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_15, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_15, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2009; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
-      __pyx_t_15 = PyNumber_Add(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = PyNumber_Add(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2009; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __pyx_t_1 = __pyx_t_15;
@@ -59853,7 +59921,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       __Pyx_INCREF(__pyx_int_1);
       __pyx_t_1 = __pyx_int_1;
     }
-    __pyx_t_15 = PyList_New(5); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_15 = PyList_New(5); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2009; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_15);
     PyList_SET_ITEM(__pyx_t_15, 0, __pyx_t_1);
     __Pyx_GIVEREF(__pyx_t_1);
@@ -59870,22 +59938,22 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     PyList_SET_ITEM(__pyx_t_15, 4, __pyx_v_link_j);
     __Pyx_GIVEREF(__pyx_v_link_j);
     __pyx_t_1 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Append(__pyx_v_nt, ((PyObject *)__pyx_t_15)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_PyObject_Append(__pyx_v_nt, ((PyObject *)__pyx_t_15)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2009; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2009
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2011
  *                 nt.append([(nt[-1][0] + 1) if nt else 1, f_j, f_j, link_i, link_j])
  *                 # Require at least one word in phrase
  *                 if links and f_j >= new_min_bound:             # <<<<<<<<<<<<<<
  *                     rules.add(self.form_rule(f_i, new_e_i, f_words[f_i:f_j + 1], e_words[new_e_i:new_e_j + 1], nt, links))
  *                 extract(f_i, f_j + 1, new_e_i, new_e_j, new_min_bound, wc + 1, links, nt, False)
  */
-    __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_links); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2009; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_links); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     if (__pyx_t_6) {
-      __pyx_t_1 = PyObject_RichCompare(__pyx_v_f_j, __pyx_v_new_min_bound, Py_GE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2009; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2009; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_RichCompare(__pyx_v_f_j, __pyx_v_new_min_bound, Py_GE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       __pyx_t_16 = __pyx_t_3;
     } else {
@@ -59893,35 +59961,35 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     }
     if (__pyx_t_16) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2010
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2012
  *                 # Require at least one word in phrase
  *                 if links and f_j >= new_min_bound:
  *                     rules.add(self.form_rule(f_i, new_e_i, f_words[f_i:f_j + 1], e_words[new_e_i:new_e_j + 1], nt, links))             # <<<<<<<<<<<<<<
  *                 extract(f_i, f_j + 1, new_e_i, new_e_j, new_min_bound, wc + 1, links, nt, False)
  *                 nt.pop()
  */
-      if (unlikely(!__pyx_cur_scope->__pyx_v_rules)) { __Pyx_RaiseClosureNameError("rules"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_1 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_rules, __pyx_n_s__add); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_rules)) { __Pyx_RaiseClosureNameError("rules"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2012; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_1 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_rules, __pyx_n_s__add); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_15 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__form_rule); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__form_rule); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_15);
-      if (unlikely(!__pyx_cur_scope->__pyx_v_f_words)) { __Pyx_RaiseClosureNameError("f_words"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_7 = __Pyx_PyIndex_AsSsize_t(__pyx_v_f_i); if (unlikely((__pyx_t_7 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_4 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_f_words)) { __Pyx_RaiseClosureNameError("f_words"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2012; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_7 = __Pyx_PyIndex_AsSsize_t(__pyx_v_f_i); if (unlikely((__pyx_t_7 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_14 = __Pyx_PyIndex_AsSsize_t(__pyx_t_4); if (unlikely((__pyx_t_14 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_14 = __Pyx_PyIndex_AsSsize_t(__pyx_t_4); if (unlikely((__pyx_t_14 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_4 = __Pyx_PySequence_GetSlice(__pyx_cur_scope->__pyx_v_f_words, __pyx_t_7, __pyx_t_14); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_PySequence_GetSlice(__pyx_cur_scope->__pyx_v_f_words, __pyx_t_7, __pyx_t_14); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      if (unlikely(!__pyx_cur_scope->__pyx_v_e_words)) { __Pyx_RaiseClosureNameError("e_words"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_14 = __Pyx_PyIndex_AsSsize_t(__pyx_v_new_e_i); if (unlikely((__pyx_t_14 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_8 = PyNumber_Add(__pyx_v_new_e_j, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_e_words)) { __Pyx_RaiseClosureNameError("e_words"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2012; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_14 = __Pyx_PyIndex_AsSsize_t(__pyx_v_new_e_i); if (unlikely((__pyx_t_14 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyNumber_Add(__pyx_v_new_e_j, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
-      __pyx_t_7 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_7 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_7 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-      __pyx_t_8 = __Pyx_PySequence_GetSlice(__pyx_cur_scope->__pyx_v_e_words, __pyx_t_14, __pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = __Pyx_PySequence_GetSlice(__pyx_cur_scope->__pyx_v_e_words, __pyx_t_14, __pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
-      __pyx_t_2 = PyTuple_New(6); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyTuple_New(6); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_INCREF(__pyx_v_f_i);
       PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_f_i);
@@ -59941,16 +60009,16 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
       __Pyx_GIVEREF(__pyx_v_links);
       __pyx_t_4 = 0;
       __pyx_t_8 = 0;
-      __pyx_t_8 = PyObject_Call(__pyx_t_15, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyObject_Call(__pyx_t_15, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
-      __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_8);
       __Pyx_GIVEREF(__pyx_t_8);
       __pyx_t_8 = 0;
-      __pyx_t_8 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
@@ -59959,21 +60027,21 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     }
     __pyx_L37:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2011
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2013
  *                 if links and f_j >= new_min_bound:
  *                     rules.add(self.form_rule(f_i, new_e_i, f_words[f_i:f_j + 1], e_words[new_e_i:new_e_j + 1], nt, links))
  *                 extract(f_i, f_j + 1, new_e_i, new_e_j, new_min_bound, wc + 1, links, nt, False)             # <<<<<<<<<<<<<<
  *                 nt.pop()
  *                 span_dec(cover, link_i, link_j)
  */
-    if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2011; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-    __pyx_t_8 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2013; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+    __pyx_t_8 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
-    __pyx_t_2 = PyNumber_Add(__pyx_v_wc, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyNumber_Add(__pyx_v_wc, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_1 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_15 = PyTuple_New(9); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_15 = PyTuple_New(9); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_15);
     __Pyx_INCREF(__pyx_v_f_i);
     PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_v_f_i);
@@ -60002,32 +60070,32 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     __pyx_t_8 = 0;
     __pyx_t_2 = 0;
     __pyx_t_1 = 0;
-    __pyx_t_1 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2012
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2014
  *                     rules.add(self.form_rule(f_i, new_e_i, f_words[f_i:f_j + 1], e_words[new_e_i:new_e_j + 1], nt, links))
  *                 extract(f_i, f_j + 1, new_e_i, new_e_j, new_min_bound, wc + 1, links, nt, False)
  *                 nt.pop()             # <<<<<<<<<<<<<<
  *                 span_dec(cover, link_i, link_j)
  *                 span_dec(e_nt_cover, link_i, link_j)
  */
-    __pyx_t_1 = __Pyx_PyObject_Pop(__pyx_v_nt); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_PyObject_Pop(__pyx_v_nt); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2014; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2013
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2015
  *                 extract(f_i, f_j + 1, new_e_i, new_e_j, new_min_bound, wc + 1, links, nt, False)
  *                 nt.pop()
  *                 span_dec(cover, link_i, link_j)             # <<<<<<<<<<<<<<
  *                 span_dec(e_nt_cover, link_i, link_j)
  * 
  */
-    __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_dec); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_dec); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2015; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_15 = PyTuple_New(3); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_15 = PyTuple_New(3); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2015; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_15);
     __Pyx_INCREF(__pyx_cur_scope->__pyx_v_cover);
     PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_cur_scope->__pyx_v_cover);
@@ -60038,22 +60106,22 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     __Pyx_INCREF(__pyx_v_link_j);
     PyTuple_SET_ITEM(__pyx_t_15, 2, __pyx_v_link_j);
     __Pyx_GIVEREF(__pyx_v_link_j);
-    __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2013; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2015; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2014
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2016
  *                 nt.pop()
  *                 span_dec(cover, link_i, link_j)
  *                 span_dec(e_nt_cover, link_i, link_j)             # <<<<<<<<<<<<<<
  * 
  *         # Try to extract phrases from every f index
  */
-    __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_dec); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2014; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__span_dec); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2016; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_15 = PyTuple_New(3); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2014; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_15 = PyTuple_New(3); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2016; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_15);
     __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e_nt_cover);
     PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_cur_scope->__pyx_v_e_nt_cover);
@@ -60064,7 +60132,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
     __Pyx_INCREF(__pyx_v_link_j);
     PyTuple_SET_ITEM(__pyx_t_15, 2, __pyx_v_link_j);
     __Pyx_GIVEREF(__pyx_v_link_j);
-    __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2014; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_15), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2016; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_15)); __pyx_t_15 = 0;
@@ -60098,7 +60166,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_12add_instance_extract(
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1877
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1879
  *     # Aggregate stats from a training instance
  *     # (Extract rules, update counts)
  *     def add_instance(self, f_words, e_words, alignment):             # <<<<<<<<<<<<<<
@@ -60159,7 +60227,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
   __Pyx_INCREF(__pyx_cur_scope->__pyx_v_e_words);
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_e_words);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1879
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1881
  *     def add_instance(self, f_words, e_words, alignment):
  * 
  *         self.online = True             # <<<<<<<<<<<<<<
@@ -60168,20 +60236,20 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
  */
   __pyx_cur_scope->__pyx_v_self->online = 1;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1886
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1888
  *         # span more than once.
  *         # (f, e, al, lex_f_i, lex_f_j)
  *         rules = set()             # <<<<<<<<<<<<<<
  * 
  *         f_len = len(f_words)
  */
-  __pyx_t_1 = PySet_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1886; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PySet_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
   __pyx_cur_scope->__pyx_v_rules = ((PyObject *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1888
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1890
  *         rules = set()
  * 
  *         f_len = len(f_words)             # <<<<<<<<<<<<<<
@@ -60190,15 +60258,15 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
  */
   __pyx_t_1 = __pyx_cur_scope->__pyx_v_f_words;
   __Pyx_INCREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1890; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1890; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_1);
   __pyx_cur_scope->__pyx_v_f_len = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1889
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1891
  * 
  *         f_len = len(f_words)
  *         e_len = len(e_words)             # <<<<<<<<<<<<<<
@@ -60207,35 +60275,35 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
  */
   __pyx_t_1 = __pyx_cur_scope->__pyx_v_e_words;
   __Pyx_INCREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1889; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1891; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1889; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1891; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_e_len = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1892
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1894
  * 
  *         # Pre-compute alignment info
  *         al = [[] for i in range(f_len)]             # <<<<<<<<<<<<<<
  *         fe_span = [[e_len + 1, -1] for i in range(f_len)]
  *         ef_span = [[f_len + 1, -1] for i in range(e_len)]
  */
-  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1892; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1892; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f_len);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_cur_scope->__pyx_v_f_len);
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_f_len);
-  __pyx_t_4 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1892; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
   if (PyList_CheckExact(__pyx_t_4) || PyTuple_CheckExact(__pyx_t_4)) {
     __pyx_t_3 = __pyx_t_4; __Pyx_INCREF(__pyx_t_3); __pyx_t_2 = 0;
     __pyx_t_5 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1892; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_5 = Py_TYPE(__pyx_t_3)->tp_iternext;
   }
@@ -60244,23 +60312,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_3)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_3)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_4 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1892; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_3, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1892; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_3, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_3)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1892; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_3, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1892; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_3, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_4 = __pyx_t_5(__pyx_t_3);
       if (unlikely(!__pyx_t_4)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1892; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -60269,9 +60337,9 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     __Pyx_XDECREF(__pyx_v_i);
     __pyx_v_i = __pyx_t_4;
     __pyx_t_4 = 0;
-    __pyx_t_4 = PyList_New(0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1892; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyList_New(0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    if (unlikely(__Pyx_PyList_Append(__pyx_t_1, (PyObject*)__pyx_t_4))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1892; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(__Pyx_PyList_Append(__pyx_t_1, (PyObject*)__pyx_t_4))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
   }
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -60280,28 +60348,28 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
   __pyx_cur_scope->__pyx_v_al = ((PyObject *)__pyx_t_1);
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1893
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1895
  *         # Pre-compute alignment info
  *         al = [[] for i in range(f_len)]
  *         fe_span = [[e_len + 1, -1] for i in range(f_len)]             # <<<<<<<<<<<<<<
  *         ef_span = [[f_len + 1, -1] for i in range(e_len)]
  *         for (f, e) in alignment:
  */
-  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f_len);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_cur_scope->__pyx_v_f_len);
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_f_len);
-  __pyx_t_4 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
   if (PyList_CheckExact(__pyx_t_4) || PyTuple_CheckExact(__pyx_t_4)) {
     __pyx_t_3 = __pyx_t_4; __Pyx_INCREF(__pyx_t_3); __pyx_t_2 = 0;
     __pyx_t_5 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_5 = Py_TYPE(__pyx_t_3)->tp_iternext;
   }
@@ -60310,23 +60378,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_3)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_3)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_4 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_3, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_3, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_3)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_3, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_3, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_4 = __pyx_t_5(__pyx_t_3);
       if (unlikely(!__pyx_t_4)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -60335,9 +60403,9 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     __Pyx_XDECREF(__pyx_v_i);
     __pyx_v_i = __pyx_t_4;
     __pyx_t_4 = 0;
-    __pyx_t_4 = PyNumber_Add(__pyx_v_e_len, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyNumber_Add(__pyx_v_e_len, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = PyList_New(2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyList_New(2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     PyList_SET_ITEM(__pyx_t_6, 0, __pyx_t_4);
     __Pyx_GIVEREF(__pyx_t_4);
@@ -60345,7 +60413,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     PyList_SET_ITEM(__pyx_t_6, 1, __pyx_int_neg_1);
     __Pyx_GIVEREF(__pyx_int_neg_1);
     __pyx_t_4 = 0;
-    if (unlikely(__Pyx_PyList_Append(__pyx_t_1, (PyObject*)__pyx_t_6))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(__Pyx_PyList_Append(__pyx_t_1, (PyObject*)__pyx_t_6))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
   }
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -60354,28 +60422,28 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
   __pyx_cur_scope->__pyx_v_fe_span = ((PyObject *)__pyx_t_1);
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1894
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1896
  *         al = [[] for i in range(f_len)]
  *         fe_span = [[e_len + 1, -1] for i in range(f_len)]
  *         ef_span = [[f_len + 1, -1] for i in range(e_len)]             # <<<<<<<<<<<<<<
  *         for (f, e) in alignment:
  *             al[f].append(e)
  */
-  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1896; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1896; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_INCREF(__pyx_v_e_len);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_e_len);
   __Pyx_GIVEREF(__pyx_v_e_len);
-  __pyx_t_6 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_6 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1896; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_6);
   __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
   if (PyList_CheckExact(__pyx_t_6) || PyTuple_CheckExact(__pyx_t_6)) {
     __pyx_t_3 = __pyx_t_6; __Pyx_INCREF(__pyx_t_3); __pyx_t_2 = 0;
     __pyx_t_5 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_t_6); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_t_6); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1896; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_5 = Py_TYPE(__pyx_t_3)->tp_iternext;
   }
@@ -60384,23 +60452,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_3)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_3)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_6 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_2); __Pyx_INCREF(__pyx_t_6); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_2); __Pyx_INCREF(__pyx_t_6); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1896; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_6 = PySequence_ITEM(__pyx_t_3, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PySequence_ITEM(__pyx_t_3, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1896; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_3)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_6 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_2); __Pyx_INCREF(__pyx_t_6); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_2); __Pyx_INCREF(__pyx_t_6); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1896; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_6 = PySequence_ITEM(__pyx_t_3, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PySequence_ITEM(__pyx_t_3, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1896; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_6 = __pyx_t_5(__pyx_t_3);
       if (unlikely(!__pyx_t_6)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1896; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -60409,9 +60477,9 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     __Pyx_XDECREF(__pyx_v_i);
     __pyx_v_i = __pyx_t_6;
     __pyx_t_6 = 0;
-    __pyx_t_6 = PyNumber_Add(__pyx_cur_scope->__pyx_v_f_len, __pyx_int_1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyNumber_Add(__pyx_cur_scope->__pyx_v_f_len, __pyx_int_1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1896; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_4 = PyList_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyList_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1896; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     PyList_SET_ITEM(__pyx_t_4, 0, __pyx_t_6);
     __Pyx_GIVEREF(__pyx_t_6);
@@ -60419,7 +60487,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     PyList_SET_ITEM(__pyx_t_4, 1, __pyx_int_neg_1);
     __Pyx_GIVEREF(__pyx_int_neg_1);
     __pyx_t_6 = 0;
-    if (unlikely(__Pyx_PyList_Append(__pyx_t_1, (PyObject*)__pyx_t_4))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(__Pyx_PyList_Append(__pyx_t_1, (PyObject*)__pyx_t_4))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1896; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
   }
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -60428,7 +60496,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
   __pyx_cur_scope->__pyx_v_ef_span = ((PyObject *)__pyx_t_1);
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1895
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1897
  *         fe_span = [[e_len + 1, -1] for i in range(f_len)]
  *         ef_span = [[f_len + 1, -1] for i in range(e_len)]
  *         for (f, e) in alignment:             # <<<<<<<<<<<<<<
@@ -60439,7 +60507,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     __pyx_t_1 = __pyx_v_alignment; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
     __pyx_t_5 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_alignment); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_alignment); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_5 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -60447,23 +60515,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_3 = __pyx_t_5(__pyx_t_1);
       if (unlikely(!__pyx_t_3)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -60479,7 +60547,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
       if (unlikely(size != 2)) {
         if (size > 2) __Pyx_RaiseTooManyValuesError(2);
         else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       }
       #if CYTHON_COMPILING_IN_CPYTHON
       if (likely(PyTuple_CheckExact(sequence))) {
@@ -60492,14 +60560,14 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
       __Pyx_INCREF(__pyx_t_4);
       __Pyx_INCREF(__pyx_t_6);
       #else
-      __pyx_t_4 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     } else
     {
       Py_ssize_t index = -1;
-      __pyx_t_7 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_7);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
       __pyx_t_8 = Py_TYPE(__pyx_t_7)->tp_iternext;
@@ -60507,7 +60575,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
       __Pyx_GOTREF(__pyx_t_4);
       index = 1; __pyx_t_6 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_6)) goto __pyx_L11_unpacking_failed;
       __Pyx_GOTREF(__pyx_t_6);
-      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_t_8 = NULL;
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       goto __pyx_L12_unpacking_done;
@@ -60515,7 +60583,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       __pyx_t_8 = NULL;
       if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_L12_unpacking_done:;
     }
     __Pyx_XDECREF(__pyx_v_f);
@@ -60525,21 +60593,21 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     __pyx_v_e = __pyx_t_6;
     __pyx_t_6 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1896
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1898
  *         ef_span = [[f_len + 1, -1] for i in range(e_len)]
  *         for (f, e) in alignment:
  *             al[f].append(e)             # <<<<<<<<<<<<<<
  *             fe_span[f][0] = min(fe_span[f][0], e)
  *             fe_span[f][1] = max(fe_span[f][1], e)
  */
-    __pyx_t_3 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_al, __pyx_v_f); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1896; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_al, __pyx_v_f); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1898; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_6 = __Pyx_PyObject_Append(__pyx_t_3, __pyx_v_e); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1896; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = __Pyx_PyObject_Append(__pyx_t_3, __pyx_v_e); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1898; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1897
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1899
  *         for (f, e) in alignment:
  *             al[f].append(e)
  *             fe_span[f][0] = min(fe_span[f][0], e)             # <<<<<<<<<<<<<<
@@ -60548,13 +60616,13 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
  */
     __Pyx_INCREF(__pyx_v_e);
     __pyx_t_6 = __pyx_v_e;
-    __pyx_t_3 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fe_span, __pyx_v_f); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fe_span, __pyx_v_f); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_3, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_3, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __pyx_t_7 = PyObject_RichCompare(__pyx_t_6, __pyx_t_4, Py_LT); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_9 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyObject_RichCompare(__pyx_t_6, __pyx_t_4, Py_LT); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_9 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     if (__pyx_t_9) {
       __Pyx_INCREF(__pyx_t_6);
@@ -60565,13 +60633,13 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     }
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fe_span, __pyx_v_f); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fe_span, __pyx_v_f); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
-    if (__Pyx_SetItemInt(__pyx_t_6, 0, __pyx_t_3, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (__Pyx_SetItemInt(__pyx_t_6, 0, __pyx_t_3, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1898
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1900
  *             al[f].append(e)
  *             fe_span[f][0] = min(fe_span[f][0], e)
  *             fe_span[f][1] = max(fe_span[f][1], e)             # <<<<<<<<<<<<<<
@@ -60580,13 +60648,13 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
  */
     __Pyx_INCREF(__pyx_v_e);
     __pyx_t_3 = __pyx_v_e;
-    __pyx_t_6 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fe_span, __pyx_v_f); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1898; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fe_span, __pyx_v_f); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1900; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_6, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1898; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_6, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1900; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_7 = PyObject_RichCompare(__pyx_t_3, __pyx_t_4, Py_GT); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1898; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_9 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1898; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyObject_RichCompare(__pyx_t_3, __pyx_t_4, Py_GT); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1900; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_9 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1900; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     if (__pyx_t_9) {
       __Pyx_INCREF(__pyx_t_3);
@@ -60597,13 +60665,13 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     }
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __pyx_t_3 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fe_span, __pyx_v_f); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1898; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_fe_span, __pyx_v_f); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1900; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
-    if (__Pyx_SetItemInt(__pyx_t_3, 1, __pyx_t_6, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1898; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (__Pyx_SetItemInt(__pyx_t_3, 1, __pyx_t_6, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1900; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1899
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1901
  *             fe_span[f][0] = min(fe_span[f][0], e)
  *             fe_span[f][1] = max(fe_span[f][1], e)
  *             ef_span[e][0] = min(ef_span[e][0], f)             # <<<<<<<<<<<<<<
@@ -60612,13 +60680,13 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
  */
     __Pyx_INCREF(__pyx_v_f);
     __pyx_t_6 = __pyx_v_f;
-    __pyx_t_3 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_e); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_e); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1901; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_3, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_3, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1901; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __pyx_t_7 = PyObject_RichCompare(__pyx_t_6, __pyx_t_4, Py_LT); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_9 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyObject_RichCompare(__pyx_t_6, __pyx_t_4, Py_LT); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1901; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_9 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1901; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     if (__pyx_t_9) {
       __Pyx_INCREF(__pyx_t_6);
@@ -60629,13 +60697,13 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     }
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_e); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_e); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1901; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
-    if (__Pyx_SetItemInt(__pyx_t_6, 0, __pyx_t_3, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (__Pyx_SetItemInt(__pyx_t_6, 0, __pyx_t_3, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1901; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1900
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1902
  *             fe_span[f][1] = max(fe_span[f][1], e)
  *             ef_span[e][0] = min(ef_span[e][0], f)
  *             ef_span[e][1] = max(ef_span[e][1], f)             # <<<<<<<<<<<<<<
@@ -60644,13 +60712,13 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
  */
     __Pyx_INCREF(__pyx_v_f);
     __pyx_t_3 = __pyx_v_f;
-    __pyx_t_6 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_e); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1900; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_e); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1902; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_6, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1900; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_6, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1902; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_7 = PyObject_RichCompare(__pyx_t_3, __pyx_t_4, Py_GT); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1900; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_9 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1900; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyObject_RichCompare(__pyx_t_3, __pyx_t_4, Py_GT); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1902; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_9 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1902; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     if (__pyx_t_9) {
       __Pyx_INCREF(__pyx_t_3);
@@ -60661,27 +60729,27 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     }
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __pyx_t_3 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_e); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1900; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_ef_span, __pyx_v_e); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1902; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
-    if (__Pyx_SetItemInt(__pyx_t_3, 1, __pyx_t_6, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1900; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (__Pyx_SetItemInt(__pyx_t_3, 1, __pyx_t_6, sizeof(long), PyInt_FromLong) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1902; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1903
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1905
  * 
  *         # Target side word coverage
  *         cover = [0] * e_len             # <<<<<<<<<<<<<<
  *         # Non-terminal coverage
  *         f_nt_cover = [0] * f_len
  */
-  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1903; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(__pyx_int_0);
   PyList_SET_ITEM(__pyx_t_1, 0, __pyx_int_0);
   __Pyx_GIVEREF(__pyx_int_0);
-  { PyObject* __pyx_temp = PyNumber_InPlaceMultiply(__pyx_t_1, __pyx_v_e_len); if (unlikely(!__pyx_temp)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1903; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  { PyObject* __pyx_temp = PyNumber_InPlaceMultiply(__pyx_t_1, __pyx_v_e_len); if (unlikely(!__pyx_temp)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_temp);
     __Pyx_DECREF(__pyx_t_1);
     __pyx_t_1 = __pyx_temp;
@@ -60690,19 +60758,19 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
   __pyx_cur_scope->__pyx_v_cover = ((PyObject *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1905
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1907
  *         cover = [0] * e_len
  *         # Non-terminal coverage
  *         f_nt_cover = [0] * f_len             # <<<<<<<<<<<<<<
  *         e_nt_cover = [0] * e_len
  * 
  */
-  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1907; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(__pyx_int_0);
   PyList_SET_ITEM(__pyx_t_1, 0, __pyx_int_0);
   __Pyx_GIVEREF(__pyx_int_0);
-  { PyObject* __pyx_temp = PyNumber_InPlaceMultiply(__pyx_t_1, __pyx_cur_scope->__pyx_v_f_len); if (unlikely(!__pyx_temp)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  { PyObject* __pyx_temp = PyNumber_InPlaceMultiply(__pyx_t_1, __pyx_cur_scope->__pyx_v_f_len); if (unlikely(!__pyx_temp)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1907; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_temp);
     __Pyx_DECREF(__pyx_t_1);
     __pyx_t_1 = __pyx_temp;
@@ -60710,19 +60778,19 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
   __pyx_v_f_nt_cover = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1906
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1908
  *         # Non-terminal coverage
  *         f_nt_cover = [0] * f_len
  *         e_nt_cover = [0] * e_len             # <<<<<<<<<<<<<<
  * 
  *         # Extract all possible hierarchical phrases starting at a source index
  */
-  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1908; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(__pyx_int_0);
   PyList_SET_ITEM(__pyx_t_1, 0, __pyx_int_0);
   __Pyx_GIVEREF(__pyx_int_0);
-  { PyObject* __pyx_temp = PyNumber_InPlaceMultiply(__pyx_t_1, __pyx_v_e_len); if (unlikely(!__pyx_temp)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  { PyObject* __pyx_temp = PyNumber_InPlaceMultiply(__pyx_t_1, __pyx_v_e_len); if (unlikely(!__pyx_temp)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1908; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_temp);
     __Pyx_DECREF(__pyx_t_1);
     __pyx_t_1 = __pyx_temp;
@@ -60731,44 +60799,44 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
   __pyx_cur_scope->__pyx_v_e_nt_cover = ((PyObject *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1911
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1913
  *         # f_ i and j are current, e_ i and j are previous
  *         # We care _considering_ f_j, so it is not yet in counts
  *         def extract(f_i, f_j, e_i, e_j, min_bound, wc, links, nt, nt_open):             # <<<<<<<<<<<<<<
  *             # Phrase extraction limits
  *             if f_j > (f_len - 1) or (f_j - f_i) + 1 > self.max_initial_size:
  */
-  __pyx_t_1 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_12add_instance_1extract, 0, ((PyObject*)__pyx_cur_scope), __pyx_n_s___sa, ((PyObject *)__pyx_k_codeobj_135)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_12add_instance_1extract, 0, ((PyObject*)__pyx_cur_scope), __pyx_n_s___sa, ((PyObject *)__pyx_k_codeobj_135)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_1);
   __pyx_cur_scope->__pyx_v_extract = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2017
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2019
  * 
  *         # Try to extract phrases from every f index
  *         for f_i from 0 <= f_i < f_len:             # <<<<<<<<<<<<<<
  *             # Skip if phrases won't be tight on left side
  *             if not al[f_i]:
  */
-  __pyx_t_10 = __Pyx_PyInt_AsLong(__pyx_cur_scope->__pyx_v_f_len); if (unlikely((__pyx_t_10 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2017; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_10 = __Pyx_PyInt_AsLong(__pyx_cur_scope->__pyx_v_f_len); if (unlikely((__pyx_t_10 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2019; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   for (__pyx_v_f_i = 0; __pyx_v_f_i < __pyx_t_10; __pyx_v_f_i++) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2019
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2021
  *         for f_i from 0 <= f_i < f_len:
  *             # Skip if phrases won't be tight on left side
  *             if not al[f_i]:             # <<<<<<<<<<<<<<
  *                 continue
  *             extract(f_i, f_i, f_len + 1, -1, f_i, 0, [], [], False)
  */
-    __pyx_t_1 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_al, __pyx_v_f_i, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2019; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_al, __pyx_v_f_i, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_9 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2019; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_9 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __pyx_t_11 = (!__pyx_t_9);
     if (__pyx_t_11) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2020
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2022
  *             # Skip if phrases won't be tight on left side
  *             if not al[f_i]:
  *                 continue             # <<<<<<<<<<<<<<
@@ -60780,28 +60848,28 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     }
     __pyx_L15:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2021
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2023
  *             if not al[f_i]:
  *                 continue
  *             extract(f_i, f_i, f_len + 1, -1, f_i, 0, [], [], False)             # <<<<<<<<<<<<<<
  * 
  *         # Update possible phrases (samples)
  */
-    __pyx_t_1 = PyInt_FromLong(__pyx_v_f_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyInt_FromLong(__pyx_v_f_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_6 = PyInt_FromLong(__pyx_v_f_i); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyInt_FromLong(__pyx_v_f_i); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_3 = PyNumber_Add(__pyx_cur_scope->__pyx_v_f_len, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyNumber_Add(__pyx_cur_scope->__pyx_v_f_len, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_4 = PyInt_FromLong(__pyx_v_f_i); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyInt_FromLong(__pyx_v_f_i); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_7 = PyList_New(0); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyList_New(0); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_7);
-    __pyx_t_12 = PyList_New(0); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_12 = PyList_New(0); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_12);
-    __pyx_t_13 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_13 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_13);
-    __pyx_t_14 = PyTuple_New(9); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_14 = PyTuple_New(9); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_14);
     PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_t_1);
     __Pyx_GIVEREF(__pyx_t_1);
@@ -60830,28 +60898,28 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     __pyx_t_7 = 0;
     __pyx_t_12 = 0;
     __pyx_t_13 = 0;
-    __pyx_t_13 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_13 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_13);
     __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
     __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
     __pyx_L13_continue:;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2026
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2028
  *         # This could be more efficiently integrated with extraction
  *         # at the cost of readability
  *         for (f, lex_i, lex_j) in self.get_f_phrases(f_words):             # <<<<<<<<<<<<<<
  *             self.samples_f[f] += 1
  * 
  */
-  __pyx_t_13 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__get_f_phrases); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_13 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_v_self), __pyx_n_s__get_f_phrases); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2028; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_13);
-  __pyx_t_14 = PyTuple_New(1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_14 = PyTuple_New(1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2028; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_14);
   __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f_words);
   PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_cur_scope->__pyx_v_f_words);
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_f_words);
-  __pyx_t_12 = PyObject_Call(__pyx_t_13, ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_12 = PyObject_Call(__pyx_t_13, ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2028; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_12);
   __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
@@ -60859,7 +60927,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     __pyx_t_14 = __pyx_t_12; __Pyx_INCREF(__pyx_t_14); __pyx_t_2 = 0;
     __pyx_t_5 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_14 = PyObject_GetIter(__pyx_t_12); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_14 = PyObject_GetIter(__pyx_t_12); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2028; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_14);
     __pyx_t_5 = Py_TYPE(__pyx_t_14)->tp_iternext;
   }
@@ -60868,23 +60936,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_14)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_14)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_12 = PyList_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_12); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_12 = PyList_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_12); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2028; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_12 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_12 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2028; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_14)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_14)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_12 = PyTuple_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_12); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_12 = PyTuple_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_12); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2028; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_12 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_12 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2028; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_12 = __pyx_t_5(__pyx_t_14);
       if (unlikely(!__pyx_t_12)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2028; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -60900,7 +60968,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
       if (unlikely(size != 3)) {
         if (size > 3) __Pyx_RaiseTooManyValuesError(3);
         else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2028; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       }
       #if CYTHON_COMPILING_IN_CPYTHON
       if (likely(PyTuple_CheckExact(sequence))) {
@@ -60916,15 +60984,15 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
       __Pyx_INCREF(__pyx_t_7);
       __Pyx_INCREF(__pyx_t_4);
       #else
-      __pyx_t_13 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_7 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_4 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_13 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2028; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2028; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2028; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
       __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
     } else
     {
       Py_ssize_t index = -1;
-      __pyx_t_3 = PyObject_GetIter(__pyx_t_12); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyObject_GetIter(__pyx_t_12); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2028; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
       __pyx_t_8 = Py_TYPE(__pyx_t_3)->tp_iternext;
@@ -60934,7 +61002,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
       __Pyx_GOTREF(__pyx_t_7);
       index = 2; __pyx_t_4 = __pyx_t_8(__pyx_t_3); if (unlikely(!__pyx_t_4)) goto __pyx_L18_unpacking_failed;
       __Pyx_GOTREF(__pyx_t_4);
-      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_3), 3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_3), 3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2028; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_t_8 = NULL;
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
       goto __pyx_L19_unpacking_done;
@@ -60942,7 +61010,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
       __pyx_t_8 = NULL;
       if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2028; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_L19_unpacking_done:;
     }
     __Pyx_XDECREF(__pyx_v_f);
@@ -60955,7 +61023,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     __pyx_v_lex_j = __pyx_t_4;
     __pyx_t_4 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2027
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2029
  *         # at the cost of readability
  *         for (f, lex_i, lex_j) in self.get_f_phrases(f_words):
  *             self.samples_f[f] += 1             # <<<<<<<<<<<<<<
@@ -60966,19 +61034,19 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     __pyx_t_12 = __pyx_cur_scope->__pyx_v_self->samples_f;
     __Pyx_INCREF(__pyx_v_f);
     __pyx_t_4 = __pyx_v_f;
-    __pyx_t_7 = PyObject_GetItem(__pyx_t_12, __pyx_t_4); if (!__pyx_t_7) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2027; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyObject_GetItem(__pyx_t_12, __pyx_t_4); if (!__pyx_t_7) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2029; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_7);
-    __pyx_t_13 = PyNumber_InPlaceAdd(__pyx_t_7, __pyx_int_1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2027; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_13 = PyNumber_InPlaceAdd(__pyx_t_7, __pyx_int_1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2029; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_13);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (PyObject_SetItem(__pyx_t_12, __pyx_t_4, __pyx_t_13) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2027; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyObject_SetItem(__pyx_t_12, __pyx_t_4, __pyx_t_13) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2029; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
   }
   __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2030
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2032
  * 
  *         # Update phrase counts
  *         for rule in rules:             # <<<<<<<<<<<<<<
@@ -60989,7 +61057,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     __pyx_t_14 = __pyx_cur_scope->__pyx_v_rules; __Pyx_INCREF(__pyx_t_14); __pyx_t_2 = 0;
     __pyx_t_5 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_14 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_rules); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_14 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_rules); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2032; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_14);
     __pyx_t_5 = Py_TYPE(__pyx_t_14)->tp_iternext;
   }
@@ -60997,23 +61065,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_14)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_14)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_12 = PyList_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_12); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_12 = PyList_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_12); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2032; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_12 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_12 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2032; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_14)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_14)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_12 = PyTuple_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_12); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_12 = PyTuple_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_12); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2032; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_12 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_12 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2032; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_12 = __pyx_t_5(__pyx_t_14);
       if (unlikely(!__pyx_t_12)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2032; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -61023,14 +61091,14 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     __pyx_v_rule = __pyx_t_12;
     __pyx_t_12 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2031
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2033
  *         # Update phrase counts
  *         for rule in rules:
  *             (f_ph, e_ph, al) = rule[:3]             # <<<<<<<<<<<<<<
  *             self.phrases_f[f_ph] += 1
  *             self.phrases_e[e_ph] += 1
  */
-    __pyx_t_12 = __Pyx_PySequence_GetSlice(__pyx_v_rule, 0, 3); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2031; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_12 = __Pyx_PySequence_GetSlice(__pyx_v_rule, 0, 3); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_12);
     if ((likely(PyTuple_CheckExact(__pyx_t_12))) || (PyList_CheckExact(__pyx_t_12))) {
       PyObject* sequence = __pyx_t_12;
@@ -61042,7 +61110,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
       if (unlikely(size != 3)) {
         if (size > 3) __Pyx_RaiseTooManyValuesError(3);
         else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2031; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       }
       #if CYTHON_COMPILING_IN_CPYTHON
       if (likely(PyTuple_CheckExact(sequence))) {
@@ -61058,15 +61126,15 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
       __Pyx_INCREF(__pyx_t_13);
       __Pyx_INCREF(__pyx_t_7);
       #else
-      __pyx_t_4 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2031; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_13 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2031; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_7 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2031; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_13 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
       __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
     } else
     {
       Py_ssize_t index = -1;
-      __pyx_t_3 = PyObject_GetIter(__pyx_t_12); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2031; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyObject_GetIter(__pyx_t_12); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
       __pyx_t_8 = Py_TYPE(__pyx_t_3)->tp_iternext;
@@ -61076,7 +61144,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
       __Pyx_GOTREF(__pyx_t_13);
       index = 2; __pyx_t_7 = __pyx_t_8(__pyx_t_3); if (unlikely(!__pyx_t_7)) goto __pyx_L22_unpacking_failed;
       __Pyx_GOTREF(__pyx_t_7);
-      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_3), 3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2031; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_3), 3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_t_8 = NULL;
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
       goto __pyx_L23_unpacking_done;
@@ -61084,7 +61152,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
       __pyx_t_8 = NULL;
       if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2031; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_L23_unpacking_done:;
     }
     __Pyx_XDECREF(__pyx_v_f_ph);
@@ -61099,7 +61167,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     __pyx_cur_scope->__pyx_v_al = __pyx_t_7;
     __pyx_t_7 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2032
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2034
  *         for rule in rules:
  *             (f_ph, e_ph, al) = rule[:3]
  *             self.phrases_f[f_ph] += 1             # <<<<<<<<<<<<<<
@@ -61110,17 +61178,17 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     __pyx_t_12 = __pyx_cur_scope->__pyx_v_self->phrases_f;
     __Pyx_INCREF(__pyx_v_f_ph);
     __pyx_t_7 = __pyx_v_f_ph;
-    __pyx_t_13 = PyObject_GetItem(__pyx_t_12, __pyx_t_7); if (!__pyx_t_13) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2032; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_13 = PyObject_GetItem(__pyx_t_12, __pyx_t_7); if (!__pyx_t_13) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2034; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_13);
-    __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_t_13, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2032; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_t_13, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2034; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
-    if (PyObject_SetItem(__pyx_t_12, __pyx_t_7, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2032; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyObject_SetItem(__pyx_t_12, __pyx_t_7, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2034; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2033
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2035
  *             (f_ph, e_ph, al) = rule[:3]
  *             self.phrases_f[f_ph] += 1
  *             self.phrases_e[e_ph] += 1             # <<<<<<<<<<<<<<
@@ -61131,64 +61199,64 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     __pyx_t_12 = __pyx_cur_scope->__pyx_v_self->phrases_e;
     __Pyx_INCREF(__pyx_v_e_ph);
     __pyx_t_7 = __pyx_v_e_ph;
-    __pyx_t_4 = PyObject_GetItem(__pyx_t_12, __pyx_t_7); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_GetItem(__pyx_t_12, __pyx_t_7); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_13 = PyNumber_InPlaceAdd(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_13 = PyNumber_InPlaceAdd(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_13);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (PyObject_SetItem(__pyx_t_12, __pyx_t_7, __pyx_t_13) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyObject_SetItem(__pyx_t_12, __pyx_t_7, __pyx_t_13) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2034
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2036
  *             self.phrases_f[f_ph] += 1
  *             self.phrases_e[e_ph] += 1
  *             self.phrases_fe[f_ph][e_ph] += 1             # <<<<<<<<<<<<<<
  *             if not self.phrases_al[f_ph][e_ph]:
  *                 self.phrases_al[f_ph][e_ph] = al
  */
-    __pyx_t_12 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_self->phrases_fe, __pyx_v_f_ph); if (!__pyx_t_12) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2034; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_12 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_self->phrases_fe, __pyx_v_f_ph); if (!__pyx_t_12) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2036; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_12);
     __Pyx_INCREF(__pyx_v_e_ph);
     __pyx_t_7 = __pyx_v_e_ph;
-    __pyx_t_13 = PyObject_GetItem(__pyx_t_12, __pyx_t_7); if (!__pyx_t_13) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2034; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_13 = PyObject_GetItem(__pyx_t_12, __pyx_t_7); if (!__pyx_t_13) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2036; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_13);
-    __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_t_13, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2034; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_t_13, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2036; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
-    if (PyObject_SetItem(__pyx_t_12, __pyx_t_7, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2034; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyObject_SetItem(__pyx_t_12, __pyx_t_7, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2036; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2035
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2037
  *             self.phrases_e[e_ph] += 1
  *             self.phrases_fe[f_ph][e_ph] += 1
  *             if not self.phrases_al[f_ph][e_ph]:             # <<<<<<<<<<<<<<
  *                 self.phrases_al[f_ph][e_ph] = al
  * 
  */
-    __pyx_t_12 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_self->phrases_al, __pyx_v_f_ph); if (!__pyx_t_12) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_12 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_self->phrases_al, __pyx_v_f_ph); if (!__pyx_t_12) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_12);
-    __pyx_t_7 = PyObject_GetItem(__pyx_t_12, __pyx_v_e_ph); if (!__pyx_t_7) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyObject_GetItem(__pyx_t_12, __pyx_v_e_ph); if (!__pyx_t_7) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_7);
     __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
-    __pyx_t_11 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_11 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_11 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_11 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     __pyx_t_9 = (!__pyx_t_11);
     if (__pyx_t_9) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2036
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2038
  *             self.phrases_fe[f_ph][e_ph] += 1
  *             if not self.phrases_al[f_ph][e_ph]:
  *                 self.phrases_al[f_ph][e_ph] = al             # <<<<<<<<<<<<<<
  * 
  *         # Update Bilexical counts
  */
-      __pyx_t_7 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_self->phrases_al, __pyx_v_f_ph); if (!__pyx_t_7) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2036; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_self->phrases_al, __pyx_v_f_ph); if (!__pyx_t_7) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2038; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_7);
-      if (PyObject_SetItem(__pyx_t_7, __pyx_v_e_ph, __pyx_cur_scope->__pyx_v_al) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2036; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (PyObject_SetItem(__pyx_t_7, __pyx_v_e_ph, __pyx_cur_scope->__pyx_v_al) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2038; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       goto __pyx_L24;
     }
@@ -61196,7 +61264,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
   }
   __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2039
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2041
  * 
  *         # Update Bilexical counts
  *         for e_w in e_words:             # <<<<<<<<<<<<<<
@@ -61207,7 +61275,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     __pyx_t_14 = __pyx_cur_scope->__pyx_v_e_words; __Pyx_INCREF(__pyx_t_14); __pyx_t_2 = 0;
     __pyx_t_5 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_14 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_e_words); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_14 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_e_words); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2041; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_14);
     __pyx_t_5 = Py_TYPE(__pyx_t_14)->tp_iternext;
   }
@@ -61215,23 +61283,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_14)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_14)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_7 = PyList_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_7); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyList_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_7); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2041; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_7 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2041; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_14)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_14)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_7); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_7); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2041; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_7 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2041; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_7 = __pyx_t_5(__pyx_t_14);
       if (unlikely(!__pyx_t_7)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2041; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -61241,7 +61309,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     __pyx_v_e_w = __pyx_t_7;
     __pyx_t_7 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2040
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2042
  *         # Update Bilexical counts
  *         for e_w in e_words:
  *             self.bilex_e[e_w] += 1             # <<<<<<<<<<<<<<
@@ -61252,19 +61320,19 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     __pyx_t_7 = __pyx_cur_scope->__pyx_v_self->bilex_e;
     __Pyx_INCREF(__pyx_v_e_w);
     __pyx_t_12 = __pyx_v_e_w;
-    __pyx_t_4 = PyObject_GetItem(__pyx_t_7, __pyx_t_12); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2040; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_GetItem(__pyx_t_7, __pyx_t_12); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2042; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_13 = PyNumber_InPlaceAdd(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2040; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_13 = PyNumber_InPlaceAdd(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2042; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_13);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (PyObject_SetItem(__pyx_t_7, __pyx_t_12, __pyx_t_13) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2040; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyObject_SetItem(__pyx_t_7, __pyx_t_12, __pyx_t_13) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2042; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
     __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
   }
   __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2041
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2043
  *         for e_w in e_words:
  *             self.bilex_e[e_w] += 1
  *         for f_w in f_words:             # <<<<<<<<<<<<<<
@@ -61275,7 +61343,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     __pyx_t_14 = __pyx_cur_scope->__pyx_v_f_words; __Pyx_INCREF(__pyx_t_14); __pyx_t_2 = 0;
     __pyx_t_5 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_14 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_f_words); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2041; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_14 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_f_words); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_14);
     __pyx_t_5 = Py_TYPE(__pyx_t_14)->tp_iternext;
   }
@@ -61283,23 +61351,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_14)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_14)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_7 = PyList_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_7); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2041; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyList_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_7); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_7 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2041; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_14)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_14)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_7); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2041; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_14, __pyx_t_2); __Pyx_INCREF(__pyx_t_7); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_7 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2041; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PySequence_ITEM(__pyx_t_14, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_7 = __pyx_t_5(__pyx_t_14);
       if (unlikely(!__pyx_t_7)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2041; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -61309,7 +61377,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     __pyx_v_f_w = __pyx_t_7;
     __pyx_t_7 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2042
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2044
  *             self.bilex_e[e_w] += 1
  *         for f_w in f_words:
  *             self.bilex_f[f_w] += 1             # <<<<<<<<<<<<<<
@@ -61320,17 +61388,17 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
     __pyx_t_7 = __pyx_cur_scope->__pyx_v_self->bilex_f;
     __Pyx_INCREF(__pyx_v_f_w);
     __pyx_t_12 = __pyx_v_f_w;
-    __pyx_t_13 = PyObject_GetItem(__pyx_t_7, __pyx_t_12); if (!__pyx_t_13) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2042; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_13 = PyObject_GetItem(__pyx_t_7, __pyx_t_12); if (!__pyx_t_13) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2044; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_13);
-    __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_t_13, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2042; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_t_13, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2044; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
-    if (PyObject_SetItem(__pyx_t_7, __pyx_t_12, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2042; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyObject_SetItem(__pyx_t_7, __pyx_t_12, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2044; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2043
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2045
  *         for f_w in f_words:
  *             self.bilex_f[f_w] += 1
  *             for e_w in e_words:             # <<<<<<<<<<<<<<
@@ -61341,7 +61409,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
       __pyx_t_7 = __pyx_cur_scope->__pyx_v_e_words; __Pyx_INCREF(__pyx_t_7); __pyx_t_15 = 0;
       __pyx_t_16 = NULL;
     } else {
-      __pyx_t_15 = -1; __pyx_t_7 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_e_words); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_15 = -1; __pyx_t_7 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_e_words); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2045; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_7);
       __pyx_t_16 = Py_TYPE(__pyx_t_7)->tp_iternext;
     }
@@ -61349,23 +61417,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
       if (!__pyx_t_16 && PyList_CheckExact(__pyx_t_7)) {
         if (__pyx_t_15 >= PyList_GET_SIZE(__pyx_t_7)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_12 = PyList_GET_ITEM(__pyx_t_7, __pyx_t_15); __Pyx_INCREF(__pyx_t_12); __pyx_t_15++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_12 = PyList_GET_ITEM(__pyx_t_7, __pyx_t_15); __Pyx_INCREF(__pyx_t_12); __pyx_t_15++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2045; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_12 = PySequence_ITEM(__pyx_t_7, __pyx_t_15); __pyx_t_15++; if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_12 = PySequence_ITEM(__pyx_t_7, __pyx_t_15); __pyx_t_15++; if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2045; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else if (!__pyx_t_16 && PyTuple_CheckExact(__pyx_t_7)) {
         if (__pyx_t_15 >= PyTuple_GET_SIZE(__pyx_t_7)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_12 = PyTuple_GET_ITEM(__pyx_t_7, __pyx_t_15); __Pyx_INCREF(__pyx_t_12); __pyx_t_15++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_12 = PyTuple_GET_ITEM(__pyx_t_7, __pyx_t_15); __Pyx_INCREF(__pyx_t_12); __pyx_t_15++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2045; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_12 = PySequence_ITEM(__pyx_t_7, __pyx_t_15); __pyx_t_15++; if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_12 = PySequence_ITEM(__pyx_t_7, __pyx_t_15); __pyx_t_15++; if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2045; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else {
         __pyx_t_12 = __pyx_t_16(__pyx_t_7);
         if (unlikely(!__pyx_t_12)) {
           if (PyErr_Occurred()) {
             if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2045; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           }
           break;
         }
@@ -61375,23 +61443,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_25add_instance(struct _
       __pyx_v_e_w = __pyx_t_12;
       __pyx_t_12 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2044
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2046
  *             self.bilex_f[f_w] += 1
  *             for e_w in e_words:
  *                 self.bilex_fe[f_w][e_w] += 1             # <<<<<<<<<<<<<<
  * 
  *     # Create a rule from source, target, non-terminals, and alignments
  */
-      __pyx_t_12 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_self->bilex_fe, __pyx_v_f_w); if (!__pyx_t_12) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2044; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_12 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_self->bilex_fe, __pyx_v_f_w); if (!__pyx_t_12) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2046; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_12);
       __Pyx_INCREF(__pyx_v_e_w);
       __pyx_t_4 = __pyx_v_e_w;
-      __pyx_t_13 = PyObject_GetItem(__pyx_t_12, __pyx_t_4); if (!__pyx_t_13) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2044; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_13 = PyObject_GetItem(__pyx_t_12, __pyx_t_4); if (!__pyx_t_13) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2046; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_13);
-      __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_t_13, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2044; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_t_13, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2046; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
-      if (PyObject_SetItem(__pyx_t_12, __pyx_t_4, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2044; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (PyObject_SetItem(__pyx_t_12, __pyx_t_4, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2046; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
@@ -61468,31 +61536,31 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_28form_rule(PyObject *_
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__e_i)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("form_rule", 1, 6, 6, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2047; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("form_rule", 1, 6, 6, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2049; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__f_span)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("form_rule", 1, 6, 6, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2047; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("form_rule", 1, 6, 6, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2049; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  3:
         if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__e_span)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("form_rule", 1, 6, 6, 3); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2047; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("form_rule", 1, 6, 6, 3); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2049; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  4:
         if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__nt)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("form_rule", 1, 6, 6, 4); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2047; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("form_rule", 1, 6, 6, 4); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2049; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  5:
         if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__al)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("form_rule", 1, 6, 6, 5); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2047; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("form_rule", 1, 6, 6, 5); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2049; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "form_rule") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2047; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "form_rule") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2049; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 6) {
       goto __pyx_L5_argtuple_error;
@@ -61513,7 +61581,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_28form_rule(PyObject *_
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("form_rule", 1, 6, 6, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2047; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("form_rule", 1, 6, 6, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2049; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.form_rule", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -61553,11 +61621,11 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_9form_rule_lambda7(PyOb
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__y)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("lambda7", 1, 2, 2, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2050; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("lambda7", 1, 2, 2, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2052; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "lambda7") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2050; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "lambda7") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2052; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -61570,7 +61638,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_9form_rule_lambda7(PyOb
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("lambda7", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2050; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("lambda7", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2052; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.form_rule.lambda7", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -61581,7 +61649,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_9form_rule_lambda7(PyOb
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2050
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2052
  * 
  *         # Substitute in non-terminals
  *         nt_inv = sorted(nt, cmp=lambda x, y: cmp(x[3], y[3]))             # <<<<<<<<<<<<<<
@@ -61600,11 +61668,11 @@ static PyObject *__pyx_lambda_funcdef_lambda7(CYTHON_UNUSED PyObject *__pyx_self
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("lambda7", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_x, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_x, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2052; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_y, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_y, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2052; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2052; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_1);
@@ -61612,7 +61680,7 @@ static PyObject *__pyx_lambda_funcdef_lambda7(CYTHON_UNUSED PyObject *__pyx_self
   __Pyx_GIVEREF(__pyx_t_2);
   __pyx_t_1 = 0;
   __pyx_t_2 = 0;
-  __pyx_t_2 = PyObject_Call(__pyx_builtin_cmp, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Call(__pyx_builtin_cmp, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2052; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
   __pyx_r = __pyx_t_2;
@@ -61662,11 +61730,11 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_9form_rule_1lambda8(PyO
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__y)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("lambda8", 1, 2, 2, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2074; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("lambda8", 1, 2, 2, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2076; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "lambda8") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2074; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "lambda8") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2076; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -61679,7 +61747,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_9form_rule_1lambda8(PyO
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("lambda8", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2074; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("lambda8", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2076; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.form_rule.lambda8", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -61690,7 +61758,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_9form_rule_1lambda8(PyO
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2074
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2076
  *         # Adjusting alignment links takes some doing
  *         links = [list(link) for sub in al for link in sub]
  *         links_inv = sorted(links, cmp=lambda x, y: cmp(x[1], y[1]))             # <<<<<<<<<<<<<<
@@ -61709,11 +61777,11 @@ static PyObject *__pyx_lambda_funcdef_lambda8(CYTHON_UNUSED PyObject *__pyx_self
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("lambda8", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_x, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2074; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_x, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2076; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_y, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2074; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_y, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2076; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2074; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2076; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_1);
@@ -61721,7 +61789,7 @@ static PyObject *__pyx_lambda_funcdef_lambda8(CYTHON_UNUSED PyObject *__pyx_self
   __Pyx_GIVEREF(__pyx_t_2);
   __pyx_t_1 = 0;
   __pyx_t_2 = 0;
-  __pyx_t_2 = PyObject_Call(__pyx_builtin_cmp, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2074; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Call(__pyx_builtin_cmp, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2076; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
   __pyx_r = __pyx_t_2;
@@ -61743,7 +61811,7 @@ static PyObject *__pyx_lambda_funcdef_lambda8(CYTHON_UNUSED PyObject *__pyx_self
 }
 static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_9form_rule_4generator15(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value); /* proto */
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2108
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2110
  *         f = Phrase(f_sym)
  *         e = Phrase(e_sym)
  *         a = tuple(self.alignment.link(i, j) for (i, j) in links)             # <<<<<<<<<<<<<<
@@ -61769,7 +61837,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_9form_rule_2genexpr(PyO
   __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_outer_scope));
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_outer_scope);
   {
-    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_23HieroCachingRuleFactory_9form_rule_4generator15, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_23HieroCachingRuleFactory_9form_rule_4generator15, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_cur_scope);
     __Pyx_RefNannyFinishContext();
     return (PyObject *) gen;
@@ -61811,13 +61879,13 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_9form_rule_4generator15
     return NULL;
   }
   __pyx_L3_first_run:;
-  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_links)) { __Pyx_RaiseClosureNameError("links"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_links)) { __Pyx_RaiseClosureNameError("links"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
   if (PyList_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_links) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_links)) {
     __pyx_t_1 = __pyx_cur_scope->__pyx_outer_scope->__pyx_v_links; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
     __pyx_t_3 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_links); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_links); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -61825,23 +61893,23 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_9form_rule_4generator15
     if (!__pyx_t_3 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_3 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_4 = __pyx_t_3(__pyx_t_1);
       if (unlikely(!__pyx_t_4)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -61857,7 +61925,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_9form_rule_4generator15
       if (unlikely(size != 2)) {
         if (size > 2) __Pyx_RaiseTooManyValuesError(2);
         else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       }
       #if CYTHON_COMPILING_IN_CPYTHON
       if (likely(PyTuple_CheckExact(sequence))) {
@@ -61870,14 +61938,14 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_9form_rule_4generator15
       __Pyx_INCREF(__pyx_t_5);
       __Pyx_INCREF(__pyx_t_6);
       #else
-      __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     } else
     {
       Py_ssize_t index = -1;
-      __pyx_t_7 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __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;
@@ -61885,7 +61953,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_9form_rule_4generator15
       __Pyx_GOTREF(__pyx_t_5);
       index = 1; __pyx_t_6 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_6)) goto __pyx_L6_unpacking_failed;
       __Pyx_GOTREF(__pyx_t_6);
-      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 2) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_t_8 = NULL;
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       goto __pyx_L7_unpacking_done;
@@ -61893,7 +61961,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_9form_rule_4generator15
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       __pyx_t_8 = NULL;
       if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __pyx_L7_unpacking_done:;
     }
     __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_i);
@@ -61906,10 +61974,10 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_9form_rule_4generator15
     __Pyx_GIVEREF(__pyx_t_6);
     __pyx_cur_scope->__pyx_v_j = __pyx_t_6;
     __pyx_t_6 = 0;
-    if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_self)) { __Pyx_RaiseClosureNameError("self"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-    __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_cur_scope->__pyx_v_i); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_10 = __Pyx_PyInt_AsInt(__pyx_cur_scope->__pyx_v_j); if (unlikely((__pyx_t_10 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_4 = PyInt_FromLong(((struct __pyx_vtabstruct_3_sa_Alignment *)__pyx_cur_scope->__pyx_outer_scope->__pyx_v_self->alignment->__pyx_vtab)->link(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_self->alignment, __pyx_t_9, __pyx_t_10)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_self)) { __Pyx_RaiseClosureNameError("self"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+    __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_cur_scope->__pyx_v_i); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = __Pyx_PyInt_AsInt(__pyx_cur_scope->__pyx_v_j); if (unlikely((__pyx_t_10 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyInt_FromLong(((struct __pyx_vtabstruct_3_sa_Alignment *)__pyx_cur_scope->__pyx_outer_scope->__pyx_v_self->alignment->__pyx_vtab)->link(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_self->alignment, __pyx_t_9, __pyx_t_10)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __pyx_r = __pyx_t_4;
     __pyx_t_4 = 0;
@@ -61928,7 +61996,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_9form_rule_4generator15
     __Pyx_XGOTREF(__pyx_t_1);
     __pyx_t_2 = __pyx_cur_scope->__pyx_t_1;
     __pyx_t_3 = __pyx_cur_scope->__pyx_t_2;
-    if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyErr_SetNone(PyExc_StopIteration);
@@ -61948,7 +62016,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_9form_rule_4generator15
   return NULL;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2047
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2049
  * 
  *     # Create a rule from source, target, non-terminals, and alignments
  *     def form_rule(self, f_i, e_i, f_span, e_span, nt, al):             # <<<<<<<<<<<<<<
@@ -62005,52 +62073,52 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
   __Pyx_INCREF((PyObject *)__pyx_cur_scope->__pyx_v_self);
   __Pyx_GIVEREF((PyObject *)__pyx_cur_scope->__pyx_v_self);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2050
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2052
  * 
  *         # Substitute in non-terminals
  *         nt_inv = sorted(nt, cmp=lambda x, y: cmp(x[3], y[3]))             # <<<<<<<<<<<<<<
  *         f_sym = list(f_span[:])
  *         off = f_i
  */
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2052; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(__pyx_v_nt);
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_nt);
   __Pyx_GIVEREF(__pyx_v_nt);
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2052; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_2));
-  __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_9form_rule_lambda7, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_9form_rule_lambda7, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2052; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
-  if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__cmp), __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__cmp), __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2052; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_3 = PyObject_Call(__pyx_builtin_sorted, ((PyObject *)__pyx_t_1), ((PyObject *)__pyx_t_2)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Call(__pyx_builtin_sorted, ((PyObject *)__pyx_t_1), ((PyObject *)__pyx_t_2)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2052; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
   __pyx_v_nt_inv = __pyx_t_3;
   __pyx_t_3 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2051
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2053
  *         # Substitute in non-terminals
  *         nt_inv = sorted(nt, cmp=lambda x, y: cmp(x[3], y[3]))
  *         f_sym = list(f_span[:])             # <<<<<<<<<<<<<<
  *         off = f_i
  *         for next_nt in nt:
  */
-  __pyx_t_3 = __Pyx_PySequence_GetSlice(__pyx_v_f_span, 0, PY_SSIZE_T_MAX); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2051; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = __Pyx_PySequence_GetSlice(__pyx_v_f_span, 0, PY_SSIZE_T_MAX); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2051; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_3);
   __Pyx_GIVEREF(__pyx_t_3);
   __pyx_t_3 = 0;
-  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)(&PyList_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2051; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)(&PyList_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
   __pyx_v_f_sym = ((PyObject*)__pyx_t_3);
   __pyx_t_3 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2052
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2054
  *         nt_inv = sorted(nt, cmp=lambda x, y: cmp(x[3], y[3]))
  *         f_sym = list(f_span[:])
  *         off = f_i             # <<<<<<<<<<<<<<
@@ -62060,7 +62128,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
   __Pyx_INCREF(__pyx_v_f_i);
   __pyx_v_off = __pyx_v_f_i;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2053
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2055
  *         f_sym = list(f_span[:])
  *         off = f_i
  *         for next_nt in nt:             # <<<<<<<<<<<<<<
@@ -62071,7 +62139,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
     __pyx_t_3 = __pyx_v_nt; __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_nt); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_nt); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2055; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_5 = Py_TYPE(__pyx_t_3)->tp_iternext;
   }
@@ -62079,23 +62147,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
     if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_3)) {
       if (__pyx_t_4 >= PyList_GET_SIZE(__pyx_t_3)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_2 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_2); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_2); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2055; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2055; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_3)) {
       if (__pyx_t_4 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_2); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_2); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2055; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2055; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_2 = __pyx_t_5(__pyx_t_3);
       if (unlikely(!__pyx_t_2)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2055; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -62105,29 +62173,29 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
     __pyx_v_next_nt = __pyx_t_2;
     __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2054
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2056
  *         off = f_i
  *         for next_nt in nt:
  *             nt_len = (next_nt[2] - next_nt[1]) + 1             # <<<<<<<<<<<<<<
  *             i = 0
  *             while i < nt_len:
  */
-    __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_next_nt, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2054; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_next_nt, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2056; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_next_nt, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2054; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_next_nt, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2056; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_6 = PyNumber_Subtract(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2054; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyNumber_Subtract(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2056; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __pyx_t_1 = PyNumber_Add(__pyx_t_6, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2054; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyNumber_Add(__pyx_t_6, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2056; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_XDECREF(__pyx_v_nt_len);
     __pyx_v_nt_len = __pyx_t_1;
     __pyx_t_1 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2055
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2057
  *         for next_nt in nt:
  *             nt_len = (next_nt[2] - next_nt[1]) + 1
  *             i = 0             # <<<<<<<<<<<<<<
@@ -62138,7 +62206,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
     __Pyx_XDECREF(__pyx_v_i);
     __pyx_v_i = __pyx_int_0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2056
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2058
  *             nt_len = (next_nt[2] - next_nt[1]) + 1
  *             i = 0
  *             while i < nt_len:             # <<<<<<<<<<<<<<
@@ -62146,83 +62214,83 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
  *                 i += 1
  */
     while (1) {
-      __pyx_t_1 = PyObject_RichCompare(__pyx_v_i, __pyx_v_nt_len, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2056; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2056; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_RichCompare(__pyx_v_i, __pyx_v_nt_len, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2058; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2058; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       if (!__pyx_t_7) break;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2057
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2059
  *             i = 0
  *             while i < nt_len:
  *                 f_sym.pop(next_nt[1] - off)             # <<<<<<<<<<<<<<
  *                 i += 1
  *             f_sym.insert(next_nt[1] - off, sym_setindex(self.category, next_nt[0]))
  */
-      __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_f_sym), __pyx_n_s__pop); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_f_sym), __pyx_n_s__pop); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2059; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_6 = __Pyx_GetItemInt(__pyx_v_next_nt, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_GetItemInt(__pyx_v_next_nt, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2059; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_6);
-      __pyx_t_2 = PyNumber_Subtract(__pyx_t_6, __pyx_v_off); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_Subtract(__pyx_t_6, __pyx_v_off); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2059; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-      __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2059; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_6);
       PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_2);
       __Pyx_GIVEREF(__pyx_t_2);
       __pyx_t_2 = 0;
-      __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2059; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2058
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2060
  *             while i < nt_len:
  *                 f_sym.pop(next_nt[1] - off)
  *                 i += 1             # <<<<<<<<<<<<<<
  *             f_sym.insert(next_nt[1] - off, sym_setindex(self.category, next_nt[0]))
  *             off += (nt_len - 1)
  */
-      __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_i, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2058; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_i, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2060; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_v_i);
       __pyx_v_i = __pyx_t_2;
       __pyx_t_2 = 0;
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2059
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2061
  *                 f_sym.pop(next_nt[1] - off)
  *                 i += 1
  *             f_sym.insert(next_nt[1] - off, sym_setindex(self.category, next_nt[0]))             # <<<<<<<<<<<<<<
  *             off += (nt_len - 1)
  *         e_sym = list(e_span[:])
  */
-    __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_next_nt, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2059; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_next_nt, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2061; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_6 = PyNumber_Subtract(__pyx_t_2, __pyx_v_off); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2059; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyNumber_Subtract(__pyx_t_2, __pyx_v_off); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2061; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_8 = __Pyx_PyIndex_AsSsize_t(__pyx_t_6); if (unlikely((__pyx_t_8 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2059; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = __Pyx_PyIndex_AsSsize_t(__pyx_t_6); if (unlikely((__pyx_t_8 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2061; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = __Pyx_GetItemInt(__pyx_v_next_nt, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2059; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = __Pyx_GetItemInt(__pyx_v_next_nt, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2061; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_t_6); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2059; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_t_6); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2061; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_cur_scope->__pyx_v_self->category, __pyx_t_9)); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2059; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_cur_scope->__pyx_v_self->category, __pyx_t_9)); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2061; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_10 = PyList_Insert(__pyx_v_f_sym, __pyx_t_8, __pyx_t_6); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2059; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = PyList_Insert(__pyx_v_f_sym, __pyx_t_8, __pyx_t_6); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2061; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2060
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2062
  *                 i += 1
  *             f_sym.insert(next_nt[1] - off, sym_setindex(self.category, next_nt[0]))
  *             off += (nt_len - 1)             # <<<<<<<<<<<<<<
  *         e_sym = list(e_span[:])
  *         off = e_i
  */
-    __pyx_t_6 = PyNumber_Subtract(__pyx_v_nt_len, __pyx_int_1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2060; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyNumber_Subtract(__pyx_v_nt_len, __pyx_int_1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2062; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_off, __pyx_t_6); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2060; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_off, __pyx_t_6); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2062; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_DECREF(__pyx_v_off);
@@ -62231,27 +62299,27 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
   }
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2061
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2063
  *             f_sym.insert(next_nt[1] - off, sym_setindex(self.category, next_nt[0]))
  *             off += (nt_len - 1)
  *         e_sym = list(e_span[:])             # <<<<<<<<<<<<<<
  *         off = e_i
  *         for next_nt in nt_inv:
  */
-  __pyx_t_3 = __Pyx_PySequence_GetSlice(__pyx_v_e_span, 0, PY_SSIZE_T_MAX); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2061; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = __Pyx_PySequence_GetSlice(__pyx_v_e_span, 0, PY_SSIZE_T_MAX); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2063; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2061; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2063; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_3);
   __Pyx_GIVEREF(__pyx_t_3);
   __pyx_t_3 = 0;
-  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)(&PyList_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2061; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)(&PyList_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2063; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
   __pyx_v_e_sym = ((PyObject*)__pyx_t_3);
   __pyx_t_3 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2062
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2064
  *             off += (nt_len - 1)
  *         e_sym = list(e_span[:])
  *         off = e_i             # <<<<<<<<<<<<<<
@@ -62262,7 +62330,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
   __Pyx_DECREF(__pyx_v_off);
   __pyx_v_off = __pyx_v_e_i;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2063
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2065
  *         e_sym = list(e_span[:])
  *         off = e_i
  *         for next_nt in nt_inv:             # <<<<<<<<<<<<<<
@@ -62273,7 +62341,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
     __pyx_t_3 = __pyx_v_nt_inv; __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_nt_inv); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2063; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_nt_inv); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2065; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_5 = Py_TYPE(__pyx_t_3)->tp_iternext;
   }
@@ -62281,23 +62349,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
     if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_3)) {
       if (__pyx_t_4 >= PyList_GET_SIZE(__pyx_t_3)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_2 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_2); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2063; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_2); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2065; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2063; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2065; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_3)) {
       if (__pyx_t_4 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_2); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2063; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_2); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2065; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2063; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2065; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_2 = __pyx_t_5(__pyx_t_3);
       if (unlikely(!__pyx_t_2)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2063; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2065; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -62307,29 +62375,29 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
     __pyx_v_next_nt = __pyx_t_2;
     __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2064
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2066
  *         off = e_i
  *         for next_nt in nt_inv:
  *             nt_len = (next_nt[4] - next_nt[3]) + 1             # <<<<<<<<<<<<<<
  *             i = 0
  *             while i < nt_len:
  */
-    __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_next_nt, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2064; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_next_nt, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2066; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_6 = __Pyx_GetItemInt(__pyx_v_next_nt, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2064; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = __Pyx_GetItemInt(__pyx_v_next_nt, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_6) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2066; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_t_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2064; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_t_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2066; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = PyNumber_Add(__pyx_t_1, __pyx_int_1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2064; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyNumber_Add(__pyx_t_1, __pyx_int_1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2066; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_XDECREF(__pyx_v_nt_len);
     __pyx_v_nt_len = __pyx_t_6;
     __pyx_t_6 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2065
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2067
  *         for next_nt in nt_inv:
  *             nt_len = (next_nt[4] - next_nt[3]) + 1
  *             i = 0             # <<<<<<<<<<<<<<
@@ -62340,7 +62408,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
     __Pyx_XDECREF(__pyx_v_i);
     __pyx_v_i = __pyx_int_0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2066
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2068
  *             nt_len = (next_nt[4] - next_nt[3]) + 1
  *             i = 0
  *             while i < nt_len:             # <<<<<<<<<<<<<<
@@ -62348,83 +62416,83 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
  *                 i += 1
  */
     while (1) {
-      __pyx_t_6 = PyObject_RichCompare(__pyx_v_i, __pyx_v_nt_len, Py_LT); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2066; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2066; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PyObject_RichCompare(__pyx_v_i, __pyx_v_nt_len, Py_LT); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2068; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2068; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       if (!__pyx_t_7) break;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2067
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2069
  *             i = 0
  *             while i < nt_len:
  *                 e_sym.pop(next_nt[3] - off)             # <<<<<<<<<<<<<<
  *                 i += 1
  *             e_sym.insert(next_nt[3] - off, sym_setindex(self.category, next_nt[0]))
  */
-      __pyx_t_6 = PyObject_GetAttr(((PyObject *)__pyx_v_e_sym), __pyx_n_s__pop); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PyObject_GetAttr(((PyObject *)__pyx_v_e_sym), __pyx_n_s__pop); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_6);
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_next_nt, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_next_nt, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_2 = PyNumber_Subtract(__pyx_t_1, __pyx_v_off); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_Subtract(__pyx_t_1, __pyx_v_off); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
       __Pyx_GIVEREF(__pyx_t_2);
       __pyx_t_2 = 0;
-      __pyx_t_2 = PyObject_Call(__pyx_t_6, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2067; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_Call(__pyx_t_6, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2068
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2070
  *             while i < nt_len:
  *                 e_sym.pop(next_nt[3] - off)
  *                 i += 1             # <<<<<<<<<<<<<<
  *             e_sym.insert(next_nt[3] - off, sym_setindex(self.category, next_nt[0]))
  *             off += (nt_len - 1)
  */
-      __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_i, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2068; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_i, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2070; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_v_i);
       __pyx_v_i = __pyx_t_2;
       __pyx_t_2 = 0;
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2069
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2071
  *                 e_sym.pop(next_nt[3] - off)
  *                 i += 1
  *             e_sym.insert(next_nt[3] - off, sym_setindex(self.category, next_nt[0]))             # <<<<<<<<<<<<<<
  *             off += (nt_len - 1)
  * 
  */
-    __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_next_nt, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_next_nt, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2071; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_v_off); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_v_off); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2071; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_8 = __Pyx_PyIndex_AsSsize_t(__pyx_t_1); if (unlikely((__pyx_t_8 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = __Pyx_PyIndex_AsSsize_t(__pyx_t_1); if (unlikely((__pyx_t_8 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2071; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_next_nt, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_next_nt, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2071; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_9 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2071; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __pyx_t_1 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_cur_scope->__pyx_v_self->category, __pyx_t_9)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_cur_scope->__pyx_v_self->category, __pyx_t_9)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2071; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_10 = PyList_Insert(__pyx_v_e_sym, __pyx_t_8, __pyx_t_1); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = PyList_Insert(__pyx_v_e_sym, __pyx_t_8, __pyx_t_1); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2071; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2070
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2072
  *                 i += 1
  *             e_sym.insert(next_nt[3] - off, sym_setindex(self.category, next_nt[0]))
  *             off += (nt_len - 1)             # <<<<<<<<<<<<<<
  * 
  *         # Adjusting alignment links takes some doing
  */
-    __pyx_t_1 = PyNumber_Subtract(__pyx_v_nt_len, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2070; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyNumber_Subtract(__pyx_v_nt_len, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2072; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_off, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2070; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_off, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2072; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_DECREF(__pyx_v_off);
@@ -62433,20 +62501,20 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
   }
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2073
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2075
  * 
  *         # Adjusting alignment links takes some doing
  *         links = [list(link) for sub in al for link in sub]             # <<<<<<<<<<<<<<
  *         links_inv = sorted(links, cmp=lambda x, y: cmp(x[1], y[1]))
  *         links_len = len(links)
  */
-  __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2075; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   if (PyList_CheckExact(__pyx_v_al) || PyTuple_CheckExact(__pyx_v_al)) {
     __pyx_t_2 = __pyx_v_al; __Pyx_INCREF(__pyx_t_2); __pyx_t_4 = 0;
     __pyx_t_5 = NULL;
   } else {
-    __pyx_t_4 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_al); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_al); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2075; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_5 = Py_TYPE(__pyx_t_2)->tp_iternext;
   }
@@ -62454,23 +62522,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
     if (!__pyx_t_5 && PyList_CheckExact(__pyx_t_2)) {
       if (__pyx_t_4 >= PyList_GET_SIZE(__pyx_t_2)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_1 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_4); __Pyx_INCREF(__pyx_t_1); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_4); __Pyx_INCREF(__pyx_t_1); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2075; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_1 = PySequence_ITEM(__pyx_t_2, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PySequence_ITEM(__pyx_t_2, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2075; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_5 && PyTuple_CheckExact(__pyx_t_2)) {
       if (__pyx_t_4 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_4); __Pyx_INCREF(__pyx_t_1); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_4); __Pyx_INCREF(__pyx_t_1); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2075; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_1 = PySequence_ITEM(__pyx_t_2, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PySequence_ITEM(__pyx_t_2, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2075; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_1 = __pyx_t_5(__pyx_t_2);
       if (unlikely(!__pyx_t_1)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2075; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -62483,7 +62551,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
       __pyx_t_1 = __pyx_v_sub; __Pyx_INCREF(__pyx_t_1); __pyx_t_8 = 0;
       __pyx_t_11 = NULL;
     } else {
-      __pyx_t_8 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_sub); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_sub); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2075; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __pyx_t_11 = Py_TYPE(__pyx_t_1)->tp_iternext;
     }
@@ -62491,23 +62559,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
       if (!__pyx_t_11 && PyList_CheckExact(__pyx_t_1)) {
         if (__pyx_t_8 >= PyList_GET_SIZE(__pyx_t_1)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_6 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_8); __Pyx_INCREF(__pyx_t_6); __pyx_t_8++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_6 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_8); __Pyx_INCREF(__pyx_t_6); __pyx_t_8++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2075; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_6 = PySequence_ITEM(__pyx_t_1, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_6 = PySequence_ITEM(__pyx_t_1, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2075; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else if (!__pyx_t_11 && PyTuple_CheckExact(__pyx_t_1)) {
         if (__pyx_t_8 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_6 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_8); __Pyx_INCREF(__pyx_t_6); __pyx_t_8++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_6 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_8); __Pyx_INCREF(__pyx_t_6); __pyx_t_8++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2075; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_6 = PySequence_ITEM(__pyx_t_1, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_6 = PySequence_ITEM(__pyx_t_1, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2075; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else {
         __pyx_t_6 = __pyx_t_11(__pyx_t_1);
         if (unlikely(!__pyx_t_6)) {
           if (PyErr_Occurred()) {
             if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2075; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           }
           break;
         }
@@ -62516,15 +62584,15 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
       __Pyx_XDECREF(__pyx_v_link);
       __pyx_v_link = __pyx_t_6;
       __pyx_t_6 = 0;
-      __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2075; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_6);
       __Pyx_INCREF(__pyx_v_link);
       PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_v_link);
       __Pyx_GIVEREF(__pyx_v_link);
-      __pyx_t_12 = PyObject_Call(((PyObject *)((PyObject*)(&PyList_Type))), ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_12 = PyObject_Call(((PyObject *)((PyObject*)(&PyList_Type))), ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2075; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_12);
       __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
-      if (unlikely(__Pyx_PyList_Append(__pyx_t_3, (PyObject*)__pyx_t_12))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2073; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(__Pyx_PyList_Append(__pyx_t_3, (PyObject*)__pyx_t_12))) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2075; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
     }
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -62535,32 +62603,32 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
   __pyx_cur_scope->__pyx_v_links = ((PyObject *)__pyx_t_3);
   __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2074
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2076
  *         # Adjusting alignment links takes some doing
  *         links = [list(link) for sub in al for link in sub]
  *         links_inv = sorted(links, cmp=lambda x, y: cmp(x[1], y[1]))             # <<<<<<<<<<<<<<
  *         links_len = len(links)
  *         nt_len = len(nt)
  */
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2074; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2076; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_INCREF(__pyx_cur_scope->__pyx_v_links);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_cur_scope->__pyx_v_links);
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_links);
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2074; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2076; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_2));
-  __pyx_t_1 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_9form_rule_1lambda8, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2074; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_9form_rule_1lambda8, 0, NULL, __pyx_n_s___sa, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2076; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__cmp), __pyx_t_1) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2074; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__cmp), __pyx_t_1) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2076; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_builtin_sorted, ((PyObject *)__pyx_t_3), ((PyObject *)__pyx_t_2)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2074; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(__pyx_builtin_sorted, ((PyObject *)__pyx_t_3), ((PyObject *)__pyx_t_2)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2076; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
   __pyx_v_links_inv = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2075
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2077
  *         links = [list(link) for sub in al for link in sub]
  *         links_inv = sorted(links, cmp=lambda x, y: cmp(x[1], y[1]))
  *         links_len = len(links)             # <<<<<<<<<<<<<<
@@ -62569,28 +62637,28 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
  */
   __pyx_t_1 = __pyx_cur_scope->__pyx_v_links;
   __Pyx_INCREF(__pyx_t_1);
-  __pyx_t_4 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2075; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2075; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_links_len = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2076
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2078
  *         links_inv = sorted(links, cmp=lambda x, y: cmp(x[1], y[1]))
  *         links_len = len(links)
  *         nt_len = len(nt)             # <<<<<<<<<<<<<<
  *         nt_i = 0
  *         off = f_i
  */
-  __pyx_t_4 = PyObject_Length(__pyx_v_nt); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2076; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2076; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyObject_Length(__pyx_v_nt); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2078; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2078; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_XDECREF(__pyx_v_nt_len);
   __pyx_v_nt_len = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2077
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2079
  *         links_len = len(links)
  *         nt_len = len(nt)
  *         nt_i = 0             # <<<<<<<<<<<<<<
@@ -62600,7 +62668,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
   __Pyx_INCREF(__pyx_int_0);
   __pyx_v_nt_i = __pyx_int_0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2078
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2080
  *         nt_len = len(nt)
  *         nt_i = 0
  *         off = f_i             # <<<<<<<<<<<<<<
@@ -62611,7 +62679,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
   __Pyx_DECREF(__pyx_v_off);
   __pyx_v_off = __pyx_v_f_i;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2079
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2081
  *         nt_i = 0
  *         off = f_i
  *         i = 0             # <<<<<<<<<<<<<<
@@ -62622,7 +62690,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
   __Pyx_XDECREF(__pyx_v_i);
   __pyx_v_i = __pyx_int_0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2080
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2082
  *         off = f_i
  *         i = 0
  *         while i < links_len:             # <<<<<<<<<<<<<<
@@ -62630,12 +62698,12 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
  *                 off += (nt[nt_i][2] - nt[nt_i][1])
  */
   while (1) {
-    __pyx_t_1 = PyObject_RichCompare(__pyx_v_i, __pyx_v_links_len, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2080; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2080; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_RichCompare(__pyx_v_i, __pyx_v_links_len, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2082; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2082; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     if (!__pyx_t_7) break;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2081
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2083
  *         i = 0
  *         while i < links_len:
  *             while nt_i < nt_len and links[i][0] > nt[nt_i][1]:             # <<<<<<<<<<<<<<
@@ -62643,24 +62711,24 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
  *                 nt_i += 1
  */
     while (1) {
-      __pyx_t_1 = PyObject_RichCompare(__pyx_v_nt_i, __pyx_v_nt_len, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_RichCompare(__pyx_v_nt_i, __pyx_v_nt_len, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2083; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2083; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       if (__pyx_t_7) {
-        __pyx_t_1 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_links, __pyx_v_i); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_links, __pyx_v_i); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2083; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
-        __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2083; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-        __pyx_t_1 = PyObject_GetItem(__pyx_v_nt, __pyx_v_nt_i); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyObject_GetItem(__pyx_v_nt, __pyx_v_nt_i); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2083; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
-        __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2083; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-        __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_3, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_3, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2083; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_13 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_13 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2081; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_13 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_13 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2083; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
         __pyx_t_14 = __pyx_t_13;
       } else {
@@ -62668,82 +62736,82 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
       }
       if (!__pyx_t_14) break;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2082
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2084
  *         while i < links_len:
  *             while nt_i < nt_len and links[i][0] > nt[nt_i][1]:
  *                 off += (nt[nt_i][2] - nt[nt_i][1])             # <<<<<<<<<<<<<<
  *                 nt_i += 1
  *             links[i][0] -= off
  */
-      __pyx_t_1 = PyObject_GetItem(__pyx_v_nt, __pyx_v_nt_i); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2082; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_GetItem(__pyx_v_nt, __pyx_v_nt_i); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2084; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2082; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2084; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_1 = PyObject_GetItem(__pyx_v_nt, __pyx_v_nt_i); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2082; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_GetItem(__pyx_v_nt, __pyx_v_nt_i); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2084; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2082; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2084; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_1 = PyNumber_Subtract(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2082; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyNumber_Subtract(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2084; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_off, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2082; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_off, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2084; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       __Pyx_DECREF(__pyx_v_off);
       __pyx_v_off = __pyx_t_2;
       __pyx_t_2 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2083
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2085
  *             while nt_i < nt_len and links[i][0] > nt[nt_i][1]:
  *                 off += (nt[nt_i][2] - nt[nt_i][1])
  *                 nt_i += 1             # <<<<<<<<<<<<<<
  *             links[i][0] -= off
  *             i += 1
  */
-      __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_nt_i, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2083; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_nt_i, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2085; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_v_nt_i);
       __pyx_v_nt_i = __pyx_t_2;
       __pyx_t_2 = 0;
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2084
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2086
  *                 off += (nt[nt_i][2] - nt[nt_i][1])
  *                 nt_i += 1
  *             links[i][0] -= off             # <<<<<<<<<<<<<<
  *             i += 1
  *         nt_i = 0
  */
-    __pyx_t_2 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_links, __pyx_v_i); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2084; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_links, __pyx_v_i); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2086; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_4 = 0;
-    __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_2, __pyx_t_4, sizeof(Py_ssize_t), PyInt_FromSsize_t); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2084; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_2, __pyx_t_4, sizeof(Py_ssize_t), PyInt_FromSsize_t); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2086; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_3 = PyNumber_InPlaceSubtract(__pyx_t_1, __pyx_v_off); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2084; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyNumber_InPlaceSubtract(__pyx_t_1, __pyx_v_off); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2086; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    if (__Pyx_SetItemInt(__pyx_t_2, __pyx_t_4, __pyx_t_3, sizeof(Py_ssize_t), PyInt_FromSsize_t) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2084; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (__Pyx_SetItemInt(__pyx_t_2, __pyx_t_4, __pyx_t_3, sizeof(Py_ssize_t), PyInt_FromSsize_t) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2086; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2085
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2087
  *                 nt_i += 1
  *             links[i][0] -= off
  *             i += 1             # <<<<<<<<<<<<<<
  *         nt_i = 0
  *         off = e_i
  */
-    __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_i, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2085; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_i, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2087; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_v_i);
     __pyx_v_i = __pyx_t_2;
     __pyx_t_2 = 0;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2086
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2088
  *             links[i][0] -= off
  *             i += 1
  *         nt_i = 0             # <<<<<<<<<<<<<<
@@ -62754,7 +62822,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
   __Pyx_DECREF(__pyx_v_nt_i);
   __pyx_v_nt_i = __pyx_int_0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2087
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2089
  *             i += 1
  *         nt_i = 0
  *         off = e_i             # <<<<<<<<<<<<<<
@@ -62765,7 +62833,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
   __Pyx_DECREF(__pyx_v_off);
   __pyx_v_off = __pyx_v_e_i;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2088
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2090
  *         nt_i = 0
  *         off = e_i
  *         i = 0             # <<<<<<<<<<<<<<
@@ -62776,7 +62844,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
   __Pyx_DECREF(__pyx_v_i);
   __pyx_v_i = __pyx_int_0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2089
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2091
  *         off = e_i
  *         i = 0
  *         while i < links_len:             # <<<<<<<<<<<<<<
@@ -62784,12 +62852,12 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
  *                 off += (nt_inv[nt_i][4] - nt_inv[nt_i][3])
  */
   while (1) {
-    __pyx_t_2 = PyObject_RichCompare(__pyx_v_i, __pyx_v_links_len, Py_LT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2089; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_14 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_14 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2089; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyObject_RichCompare(__pyx_v_i, __pyx_v_links_len, Py_LT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2091; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_14 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_14 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2091; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     if (!__pyx_t_14) break;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2090
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2092
  *         i = 0
  *         while i < links_len:
  *             while nt_i < nt_len and links_inv[i][1] > nt_inv[nt_i][3]:             # <<<<<<<<<<<<<<
@@ -62797,24 +62865,24 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
  *                 nt_i += 1
  */
     while (1) {
-      __pyx_t_2 = PyObject_RichCompare(__pyx_v_nt_i, __pyx_v_nt_len, Py_LT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2090; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_14 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_14 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2090; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_RichCompare(__pyx_v_nt_i, __pyx_v_nt_len, Py_LT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2092; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_14 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_14 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2092; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       if (__pyx_t_14) {
-        __pyx_t_2 = PyObject_GetItem(__pyx_v_links_inv, __pyx_v_i); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2090; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_2 = PyObject_GetItem(__pyx_v_links_inv, __pyx_v_i); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2092; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
-        __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_2, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2090; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_2, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2092; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-        __pyx_t_2 = PyObject_GetItem(__pyx_v_nt_inv, __pyx_v_nt_i); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2090; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_2 = PyObject_GetItem(__pyx_v_nt_inv, __pyx_v_nt_i); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2092; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
-        __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_2, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2090; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_2, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2092; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-        __pyx_t_2 = PyObject_RichCompare(__pyx_t_3, __pyx_t_1, Py_GT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2090; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_2 = PyObject_RichCompare(__pyx_t_3, __pyx_t_1, Py_GT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2092; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-        __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2090; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2092; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_t_13 = __pyx_t_7;
       } else {
@@ -62822,82 +62890,82 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
       }
       if (!__pyx_t_13) break;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2091
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2093
  *         while i < links_len:
  *             while nt_i < nt_len and links_inv[i][1] > nt_inv[nt_i][3]:
  *                 off += (nt_inv[nt_i][4] - nt_inv[nt_i][3])             # <<<<<<<<<<<<<<
  *                 nt_i += 1
  *             links_inv[i][1] -= off
  */
-      __pyx_t_2 = PyObject_GetItem(__pyx_v_nt_inv, __pyx_v_nt_i); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2091; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_GetItem(__pyx_v_nt_inv, __pyx_v_nt_i); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_2, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2091; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_2, 4, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_2 = PyObject_GetItem(__pyx_v_nt_inv, __pyx_v_nt_i); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2091; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_GetItem(__pyx_v_nt_inv, __pyx_v_nt_i); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_2, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2091; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_2, 3, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_2 = PyNumber_Subtract(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2091; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_Subtract(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_off, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2091; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_off, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_v_off);
       __pyx_v_off = __pyx_t_3;
       __pyx_t_3 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2092
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2094
  *             while nt_i < nt_len and links_inv[i][1] > nt_inv[nt_i][3]:
  *                 off += (nt_inv[nt_i][4] - nt_inv[nt_i][3])
  *                 nt_i += 1             # <<<<<<<<<<<<<<
  *             links_inv[i][1] -= off
  *             i += 1
  */
-      __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_nt_i, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2092; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_nt_i, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2094; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_v_nt_i);
       __pyx_v_nt_i = __pyx_t_3;
       __pyx_t_3 = 0;
     }
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2093
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2095
  *                 off += (nt_inv[nt_i][4] - nt_inv[nt_i][3])
  *                 nt_i += 1
  *             links_inv[i][1] -= off             # <<<<<<<<<<<<<<
  *             i += 1
  * 
  */
-    __pyx_t_3 = PyObject_GetItem(__pyx_v_links_inv, __pyx_v_i); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_GetItem(__pyx_v_links_inv, __pyx_v_i); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2095; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = 1;
-    __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_3, __pyx_t_4, sizeof(Py_ssize_t), PyInt_FromSsize_t); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_3, __pyx_t_4, sizeof(Py_ssize_t), PyInt_FromSsize_t); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2095; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_1 = PyNumber_InPlaceSubtract(__pyx_t_2, __pyx_v_off); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyNumber_InPlaceSubtract(__pyx_t_2, __pyx_v_off); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2095; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    if (__Pyx_SetItemInt(__pyx_t_3, __pyx_t_4, __pyx_t_1, sizeof(Py_ssize_t), PyInt_FromSsize_t) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (__Pyx_SetItemInt(__pyx_t_3, __pyx_t_4, __pyx_t_1, sizeof(Py_ssize_t), PyInt_FromSsize_t) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2095; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2094
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2096
  *                 nt_i += 1
  *             links_inv[i][1] -= off
  *             i += 1             # <<<<<<<<<<<<<<
  * 
  *         # Find lexical span
  */
-    __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_i, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2094; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_i, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2096; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_v_i);
     __pyx_v_i = __pyx_t_3;
     __pyx_t_3 = 0;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2097
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2099
  * 
  *         # Find lexical span
  *         lex_f_i = f_i             # <<<<<<<<<<<<<<
@@ -62907,75 +62975,75 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
   __Pyx_INCREF(__pyx_v_f_i);
   __pyx_v_lex_f_i = __pyx_v_f_i;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2098
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2100
  *         # Find lexical span
  *         lex_f_i = f_i
  *         lex_f_j = f_i + (len(f_span) - 1)             # <<<<<<<<<<<<<<
  *         if nt:
  *             if nt[0][1] == lex_f_i:
  */
-  __pyx_t_4 = PyObject_Length(__pyx_v_f_span); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2098; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_3 = PyInt_FromSsize_t((__pyx_t_4 - 1)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2098; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyObject_Length(__pyx_v_f_span); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyInt_FromSsize_t((__pyx_t_4 - 1)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_1 = PyNumber_Add(__pyx_v_f_i, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2098; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyNumber_Add(__pyx_v_f_i, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __pyx_v_lex_f_j = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2099
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2101
  *         lex_f_i = f_i
  *         lex_f_j = f_i + (len(f_span) - 1)
  *         if nt:             # <<<<<<<<<<<<<<
  *             if nt[0][1] == lex_f_i:
  *                 lex_f_i += (nt[0][2] - nt[0][1]) + 1
  */
-  __pyx_t_13 = __Pyx_PyObject_IsTrue(__pyx_v_nt); if (unlikely(__pyx_t_13 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2099; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_13 = __Pyx_PyObject_IsTrue(__pyx_v_nt); if (unlikely(__pyx_t_13 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   if (__pyx_t_13) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2100
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2102
  *         lex_f_j = f_i + (len(f_span) - 1)
  *         if nt:
  *             if nt[0][1] == lex_f_i:             # <<<<<<<<<<<<<<
  *                 lex_f_i += (nt[0][2] - nt[0][1]) + 1
  *             if nt[-1][2] == lex_f_j:
  */
-    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __pyx_t_1 = PyObject_RichCompare(__pyx_t_3, __pyx_v_lex_f_i, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_RichCompare(__pyx_t_3, __pyx_v_lex_f_i, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __pyx_t_13 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_13 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_13 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_13 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     if (__pyx_t_13) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2101
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2103
  *         if nt:
  *             if nt[0][1] == lex_f_i:
  *                 lex_f_i += (nt[0][2] - nt[0][1]) + 1             # <<<<<<<<<<<<<<
  *             if nt[-1][2] == lex_f_j:
  *                 lex_f_j -= (nt[-1][2] - nt[-1][1]) + 1
  */
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_1 = PyNumber_Subtract(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyNumber_Subtract(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_lex_f_i, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_lex_f_i, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_v_lex_f_i);
@@ -62985,49 +63053,49 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
     }
     __pyx_L24:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2102
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2104
  *             if nt[0][1] == lex_f_i:
  *                 lex_f_i += (nt[0][2] - nt[0][1]) + 1
  *             if nt[-1][2] == lex_f_j:             # <<<<<<<<<<<<<<
  *                 lex_f_j -= (nt[-1][2] - nt[-1][1]) + 1
  * 
  */
-    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_v_lex_f_j, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_v_lex_f_j, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_13 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_13 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_13 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_13 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     if (__pyx_t_13) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2103
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2105
  *                 lex_f_i += (nt[0][2] - nt[0][1]) + 1
  *             if nt[-1][2] == lex_f_j:
  *                 lex_f_j -= (nt[-1][2] - nt[-1][1]) + 1             # <<<<<<<<<<<<<<
  * 
  *         # Create rule (f_phrase, e_phrase, links, f_link_min, f_link_max)
  */
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_nt, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_3 = PyNumber_Add(__pyx_t_1, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = PyNumber_Add(__pyx_t_1, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_1 = PyNumber_InPlaceSubtract(__pyx_v_lex_f_j, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyNumber_InPlaceSubtract(__pyx_v_lex_f_j, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
       __Pyx_DECREF(__pyx_v_lex_f_j);
@@ -63040,63 +63108,63 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
   }
   __pyx_L23:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2106
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2108
  * 
  *         # Create rule (f_phrase, e_phrase, links, f_link_min, f_link_max)
  *         f = Phrase(f_sym)             # <<<<<<<<<<<<<<
  *         e = Phrase(e_sym)
  *         a = tuple(self.alignment.link(i, j) for (i, j) in links)
  */
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(((PyObject *)__pyx_v_f_sym));
   PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_v_f_sym));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_f_sym));
-  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
   __pyx_v_f = ((struct __pyx_obj_3_sa_Phrase *)__pyx_t_3);
   __pyx_t_3 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2107
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2109
  *         # Create rule (f_phrase, e_phrase, links, f_link_min, f_link_max)
  *         f = Phrase(f_sym)
  *         e = Phrase(e_sym)             # <<<<<<<<<<<<<<
  *         a = tuple(self.alignment.link(i, j) for (i, j) in links)
  *         return (f, e, a, lex_f_i, lex_f_j)
  */
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_INCREF(((PyObject *)__pyx_v_e_sym));
   PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_v_e_sym));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_e_sym));
-  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
   __pyx_v_e = ((struct __pyx_obj_3_sa_Phrase *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2108
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2110
  *         f = Phrase(f_sym)
  *         e = Phrase(e_sym)
  *         a = tuple(self.alignment.link(i, j) for (i, j) in links)             # <<<<<<<<<<<<<<
  *         return (f, e, a, lex_f_i, lex_f_j)
  * 
  */
-  __pyx_t_1 = __pyx_pf_3_sa_23HieroCachingRuleFactory_9form_rule_2genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __pyx_pf_3_sa_23HieroCachingRuleFactory_9form_rule_2genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_1);
   __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
   __pyx_v_a = ((PyObject*)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2109
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2111
  *         e = Phrase(e_sym)
  *         a = tuple(self.alignment.link(i, j) for (i, j) in links)
  *         return (f, e, a, lex_f_i, lex_f_j)             # <<<<<<<<<<<<<<
@@ -63104,7 +63172,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_27form_rule(struct __py
  *     # Rule string from rule
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(((PyObject *)__pyx_v_f));
   PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_v_f));
@@ -63189,16 +63257,16 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_30fmt_rule(PyObject *__
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__e)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("fmt_rule", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2112; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("fmt_rule", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2114; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__a)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("fmt_rule", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2112; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("fmt_rule", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2114; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "fmt_rule") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2112; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "fmt_rule") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2114; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
       goto __pyx_L5_argtuple_error;
@@ -63213,7 +63281,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_30fmt_rule(PyObject *__
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("fmt_rule", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2112; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("fmt_rule", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2114; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.fmt_rule", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -63225,7 +63293,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_30fmt_rule(PyObject *__
 }
 static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_8fmt_rule_2generator16(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value); /* proto */
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2113
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2115
  *     # Rule string from rule
  *     def fmt_rule(self, f, e, a):
  *         a_str = ' '.join('{0}-{1}'.format(*self.alignment.unlink(packed)) for packed in a)             # <<<<<<<<<<<<<<
@@ -63251,7 +63319,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_8fmt_rule_genexpr(PyObj
   __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_outer_scope));
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_outer_scope);
   {
-    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_23HieroCachingRuleFactory_8fmt_rule_2generator16, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_3_sa_23HieroCachingRuleFactory_8fmt_rule_2generator16, (PyObject *) __pyx_cur_scope); if (unlikely(!gen)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_cur_scope);
     __Pyx_RefNannyFinishContext();
     return (PyObject *) gen;
@@ -63290,13 +63358,13 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_8fmt_rule_2generator16(
     return NULL;
   }
   __pyx_L3_first_run:;
-  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_a)) { __Pyx_RaiseClosureNameError("a"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+  if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_a)) { __Pyx_RaiseClosureNameError("a"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
   if (PyList_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_a) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_a)) {
     __pyx_t_1 = __pyx_cur_scope->__pyx_outer_scope->__pyx_v_a; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
     __pyx_t_3 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_a); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_a); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -63304,23 +63372,23 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_8fmt_rule_2generator16(
     if (!__pyx_t_3 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_3 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_4 = __pyx_t_3(__pyx_t_1);
       if (unlikely(!__pyx_t_4)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -63331,24 +63399,24 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_8fmt_rule_2generator16(
     __Pyx_GIVEREF(__pyx_t_4);
     __pyx_cur_scope->__pyx_v_packed = __pyx_t_4;
     __pyx_t_4 = 0;
-    __pyx_t_4 = PyObject_GetAttr(((PyObject *)__pyx_kp_s_137), __pyx_n_s__format); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_GetAttr(((PyObject *)__pyx_kp_s_137), __pyx_n_s__format); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_self)) { __Pyx_RaiseClosureNameError("self"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-    __pyx_t_5 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_outer_scope->__pyx_v_self->alignment), __pyx_n_s__unlink); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_self)) { __Pyx_RaiseClosureNameError("self"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+    __pyx_t_5 = PyObject_GetAttr(((PyObject *)__pyx_cur_scope->__pyx_outer_scope->__pyx_v_self->alignment), __pyx_n_s__unlink); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_INCREF(__pyx_cur_scope->__pyx_v_packed);
     PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_cur_scope->__pyx_v_packed);
     __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_packed);
-    __pyx_t_7 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_7);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
-    __pyx_t_6 = PySequence_Tuple(__pyx_t_7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PySequence_Tuple(__pyx_t_7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(((PyObject *)__pyx_t_6));
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-    __pyx_t_7 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_7);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
@@ -63369,7 +63437,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_8fmt_rule_2generator16(
     __Pyx_XGOTREF(__pyx_t_1);
     __pyx_t_2 = __pyx_cur_scope->__pyx_t_1;
     __pyx_t_3 = __pyx_cur_scope->__pyx_t_2;
-    if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyErr_SetNone(PyExc_StopIteration);
@@ -63389,7 +63457,7 @@ static PyObject *__pyx_gb_3_sa_23HieroCachingRuleFactory_8fmt_rule_2generator16(
   return NULL;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2112
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2114
  * 
  *     # Rule string from rule
  *     def fmt_rule(self, f, e, a):             # <<<<<<<<<<<<<<
@@ -63422,30 +63490,30 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_29fmt_rule(struct __pyx
   __Pyx_INCREF(__pyx_cur_scope->__pyx_v_a);
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_a);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2113
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2115
  *     # Rule string from rule
  *     def fmt_rule(self, f, e, a):
  *         a_str = ' '.join('{0}-{1}'.format(*self.alignment.unlink(packed)) for packed in a)             # <<<<<<<<<<<<<<
  *         return '[X] ||| {0} ||| {1} ||| {2}'.format(f, e, a_str)
  * 
  */
-  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_kp_s_67), __pyx_n_s__join); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_kp_s_67), __pyx_n_s__join); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __pyx_pf_3_sa_23HieroCachingRuleFactory_8fmt_rule_genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __pyx_pf_3_sa_23HieroCachingRuleFactory_8fmt_rule_genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
   __Pyx_GIVEREF(__pyx_t_2);
   __pyx_t_2 = 0;
-  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
   __pyx_v_a_str = __pyx_t_2;
   __pyx_t_2 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2114
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2116
  *     def fmt_rule(self, f, e, a):
  *         a_str = ' '.join('{0}-{1}'.format(*self.alignment.unlink(packed)) for packed in a)
  *         return '[X] ||| {0} ||| {1} ||| {2}'.format(f, e, a_str)             # <<<<<<<<<<<<<<
@@ -63453,9 +63521,9 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_29fmt_rule(struct __pyx
  *     # Debugging
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = PyObject_GetAttr(((PyObject *)__pyx_kp_s_138), __pyx_n_s__format); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_GetAttr(((PyObject *)__pyx_kp_s_138), __pyx_n_s__format); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_INCREF(__pyx_v_f);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_f);
@@ -63466,7 +63534,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_29fmt_rule(struct __pyx
   __Pyx_INCREF(__pyx_v_a_str);
   PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_v_a_str);
   __Pyx_GIVEREF(__pyx_v_a_str);
-  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
@@ -63501,7 +63569,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_32dump_online_stats(PyO
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2117
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2119
  * 
  *     # Debugging
  *     def dump_online_stats(self):             # <<<<<<<<<<<<<<
@@ -63531,75 +63599,75 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("dump_online_stats", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2118
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2120
  *     # Debugging
  *     def dump_online_stats(self):
  *         logger.info('------------------------------')             # <<<<<<<<<<<<<<
  *         logger.info('         Online Stats         ')
  *         logger.info('------------------------------')
  */
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_k_tuple_140), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_k_tuple_140), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2119
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2121
  *     def dump_online_stats(self):
  *         logger.info('------------------------------')
  *         logger.info('         Online Stats         ')             # <<<<<<<<<<<<<<
  *         logger.info('------------------------------')
  *         logger.info('f')
  */
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_k_tuple_142), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_k_tuple_142), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2120
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2122
  *         logger.info('------------------------------')
  *         logger.info('         Online Stats         ')
  *         logger.info('------------------------------')             # <<<<<<<<<<<<<<
  *         logger.info('f')
  *         for w in self.bilex_f:
  */
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_k_tuple_143), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_k_tuple_143), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2121
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2123
  *         logger.info('         Online Stats         ')
  *         logger.info('------------------------------')
  *         logger.info('f')             # <<<<<<<<<<<<<<
  *         for w in self.bilex_f:
  *             logger.info(sym_tostring(w) + ' : ' + str(self.bilex_f[w]))
  */
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_k_tuple_144), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_k_tuple_144), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2122
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2124
  *         logger.info('------------------------------')
  *         logger.info('f')
  *         for w in self.bilex_f:             # <<<<<<<<<<<<<<
@@ -63610,7 +63678,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
     __pyx_t_1 = __pyx_v_self->bilex_f; __Pyx_INCREF(__pyx_t_1); __pyx_t_3 = 0;
     __pyx_t_4 = NULL;
   } else {
-    __pyx_t_3 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_self->bilex_f); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_self->bilex_f); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_4 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -63618,23 +63686,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
     if (!__pyx_t_4 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_2 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_2); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_2); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_4 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_2); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_2); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_2 = __pyx_t_4(__pyx_t_1);
       if (unlikely(!__pyx_t_2)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -63644,44 +63712,44 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
     __pyx_v_w = __pyx_t_2;
     __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2123
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2125
  *         logger.info('f')
  *         for w in self.bilex_f:
  *             logger.info(sym_tostring(w) + ' : ' + str(self.bilex_f[w]))             # <<<<<<<<<<<<<<
  *         logger.info('e')
  *         for w in self.bilex_e:
  */
-    __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_5 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__info); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__info); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_w); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_2 = PyBytes_FromString(__pyx_f_3_sa_sym_tostring(__pyx_t_6)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_w); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyBytes_FromString(__pyx_f_3_sa_sym_tostring(__pyx_t_6)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(((PyObject *)__pyx_t_2));
-    __pyx_t_7 = PyNumber_Add(((PyObject *)__pyx_t_2), ((PyObject *)__pyx_kp_s_145)); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyNumber_Add(((PyObject *)__pyx_t_2), ((PyObject *)__pyx_kp_s_145)); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_7);
     __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
-    __pyx_t_2 = PyObject_GetItem(__pyx_v_self->bilex_f, __pyx_v_w); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyObject_GetItem(__pyx_v_self->bilex_f, __pyx_v_w); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
     PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_2);
     __Pyx_GIVEREF(__pyx_t_2);
     __pyx_t_2 = 0;
-    __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(((PyObject *)__pyx_t_8)); __pyx_t_8 = 0;
-    __pyx_t_8 = PyNumber_Add(__pyx_t_7, __pyx_t_2); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyNumber_Add(__pyx_t_7, __pyx_t_2); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_8);
     __Pyx_GIVEREF(__pyx_t_8);
     __pyx_t_8 = 0;
-    __pyx_t_8 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
@@ -63689,24 +63757,24 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2124
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2126
  *         for w in self.bilex_f:
  *             logger.info(sym_tostring(w) + ' : ' + str(self.bilex_f[w]))
  *         logger.info('e')             # <<<<<<<<<<<<<<
  *         for w in self.bilex_e:
  *             logger.info(sym_tostring(w) + ' : ' + str(self.bilex_e[w]))
  */
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_8 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_8 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_8);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_k_tuple_146), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_k_tuple_146), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2125
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2127
  *             logger.info(sym_tostring(w) + ' : ' + str(self.bilex_f[w]))
  *         logger.info('e')
  *         for w in self.bilex_e:             # <<<<<<<<<<<<<<
@@ -63717,7 +63785,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
     __pyx_t_1 = __pyx_v_self->bilex_e; __Pyx_INCREF(__pyx_t_1); __pyx_t_3 = 0;
     __pyx_t_4 = NULL;
   } else {
-    __pyx_t_3 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_self->bilex_e); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_self->bilex_e); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_4 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -63725,23 +63793,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
     if (!__pyx_t_4 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_8 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_8); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_8); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_8 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_4 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_8 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_8); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_8); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_8 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_8 = __pyx_t_4(__pyx_t_1);
       if (unlikely(!__pyx_t_8)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -63751,44 +63819,44 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
     __pyx_v_w = __pyx_t_8;
     __pyx_t_8 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2126
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2128
  *         logger.info('e')
  *         for w in self.bilex_e:
  *             logger.info(sym_tostring(w) + ' : ' + str(self.bilex_e[w]))             # <<<<<<<<<<<<<<
  *         logger.info('fe')
  *         for w in self.bilex_fe:
  */
-    __pyx_t_8 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
-    __pyx_t_2 = PyObject_GetAttr(__pyx_t_8, __pyx_n_s__info); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyObject_GetAttr(__pyx_t_8, __pyx_n_s__info); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-    __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_w); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_8 = PyBytes_FromString(__pyx_f_3_sa_sym_tostring(__pyx_t_6)); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_w); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyBytes_FromString(__pyx_f_3_sa_sym_tostring(__pyx_t_6)); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(((PyObject *)__pyx_t_8));
-    __pyx_t_5 = PyNumber_Add(((PyObject *)__pyx_t_8), ((PyObject *)__pyx_kp_s_145)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyNumber_Add(((PyObject *)__pyx_t_8), ((PyObject *)__pyx_kp_s_145)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(((PyObject *)__pyx_t_8)); __pyx_t_8 = 0;
-    __pyx_t_8 = PyObject_GetItem(__pyx_v_self->bilex_e, __pyx_v_w); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyObject_GetItem(__pyx_v_self->bilex_e, __pyx_v_w); if (!__pyx_t_8) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
-    __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_7);
     PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_8);
     __Pyx_GIVEREF(__pyx_t_8);
     __pyx_t_8 = 0;
-    __pyx_t_8 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_7), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_7), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
     __Pyx_DECREF(((PyObject *)__pyx_t_7)); __pyx_t_7 = 0;
-    __pyx_t_7 = PyNumber_Add(__pyx_t_5, __pyx_t_8); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyNumber_Add(__pyx_t_5, __pyx_t_8); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_7);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-    __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
     PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7);
     __Pyx_GIVEREF(__pyx_t_7);
     __pyx_t_7 = 0;
-    __pyx_t_7 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_7);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_8)); __pyx_t_8 = 0;
@@ -63796,24 +63864,24 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2127
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2129
  *         for w in self.bilex_e:
  *             logger.info(sym_tostring(w) + ' : ' + str(self.bilex_e[w]))
  *         logger.info('fe')             # <<<<<<<<<<<<<<
  *         for w in self.bilex_fe:
  *             for w2 in self.bilex_fe[w]:
  */
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_7 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_7 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_7);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_t_7, ((PyObject *)__pyx_k_tuple_147), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(__pyx_t_7, ((PyObject *)__pyx_k_tuple_147), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2128
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2130
  *             logger.info(sym_tostring(w) + ' : ' + str(self.bilex_e[w]))
  *         logger.info('fe')
  *         for w in self.bilex_fe:             # <<<<<<<<<<<<<<
@@ -63824,7 +63892,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
     __pyx_t_1 = __pyx_v_self->bilex_fe; __Pyx_INCREF(__pyx_t_1); __pyx_t_3 = 0;
     __pyx_t_4 = NULL;
   } else {
-    __pyx_t_3 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_self->bilex_fe); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_self->bilex_fe); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_4 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -63832,23 +63900,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
     if (!__pyx_t_4 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_7 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_7); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_7); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_7 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_4 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_7); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_7); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_7 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_7 = __pyx_t_4(__pyx_t_1);
       if (unlikely(!__pyx_t_7)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -63858,20 +63926,20 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
     __pyx_v_w = __pyx_t_7;
     __pyx_t_7 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2129
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2131
  *         logger.info('fe')
  *         for w in self.bilex_fe:
  *             for w2 in self.bilex_fe[w]:             # <<<<<<<<<<<<<<
  *                 logger.info(sym_tostring(w) + ' : ' + sym_tostring(w2) + ' : ' + str(self.bilex_fe[w][w2]))
  *         logger.info('F')
  */
-    __pyx_t_7 = PyObject_GetItem(__pyx_v_self->bilex_fe, __pyx_v_w); if (!__pyx_t_7) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyObject_GetItem(__pyx_v_self->bilex_fe, __pyx_v_w); if (!__pyx_t_7) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_7);
     if (PyList_CheckExact(__pyx_t_7) || PyTuple_CheckExact(__pyx_t_7)) {
       __pyx_t_8 = __pyx_t_7; __Pyx_INCREF(__pyx_t_8); __pyx_t_9 = 0;
       __pyx_t_10 = NULL;
     } else {
-      __pyx_t_9 = -1; __pyx_t_8 = PyObject_GetIter(__pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_9 = -1; __pyx_t_8 = PyObject_GetIter(__pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __pyx_t_10 = Py_TYPE(__pyx_t_8)->tp_iternext;
     }
@@ -63880,23 +63948,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
       if (!__pyx_t_10 && PyList_CheckExact(__pyx_t_8)) {
         if (__pyx_t_9 >= PyList_GET_SIZE(__pyx_t_8)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_7 = PyList_GET_ITEM(__pyx_t_8, __pyx_t_9); __Pyx_INCREF(__pyx_t_7); __pyx_t_9++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PyList_GET_ITEM(__pyx_t_8, __pyx_t_9); __Pyx_INCREF(__pyx_t_7); __pyx_t_9++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_7 = PySequence_ITEM(__pyx_t_8, __pyx_t_9); __pyx_t_9++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PySequence_ITEM(__pyx_t_8, __pyx_t_9); __pyx_t_9++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else if (!__pyx_t_10 && PyTuple_CheckExact(__pyx_t_8)) {
         if (__pyx_t_9 >= PyTuple_GET_SIZE(__pyx_t_8)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_8, __pyx_t_9); __Pyx_INCREF(__pyx_t_7); __pyx_t_9++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_8, __pyx_t_9); __Pyx_INCREF(__pyx_t_7); __pyx_t_9++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_7 = PySequence_ITEM(__pyx_t_8, __pyx_t_9); __pyx_t_9++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_7 = PySequence_ITEM(__pyx_t_8, __pyx_t_9); __pyx_t_9++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else {
         __pyx_t_7 = __pyx_t_10(__pyx_t_8);
         if (unlikely(!__pyx_t_7)) {
           if (PyErr_Occurred()) {
             if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           }
           break;
         }
@@ -63906,57 +63974,57 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
       __pyx_v_w2 = __pyx_t_7;
       __pyx_t_7 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2130
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2132
  *         for w in self.bilex_fe:
  *             for w2 in self.bilex_fe[w]:
  *                 logger.info(sym_tostring(w) + ' : ' + sym_tostring(w2) + ' : ' + str(self.bilex_fe[w][w2]))             # <<<<<<<<<<<<<<
  *         logger.info('F')
  *         for ph in self.phrases_f:
  */
-      __pyx_t_7 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_7);
-      __pyx_t_2 = PyObject_GetAttr(__pyx_t_7, __pyx_n_s__info); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_GetAttr(__pyx_t_7, __pyx_n_s__info); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-      __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_w); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_7 = PyBytes_FromString(__pyx_f_3_sa_sym_tostring(__pyx_t_6)); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_w); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyBytes_FromString(__pyx_f_3_sa_sym_tostring(__pyx_t_6)); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(((PyObject *)__pyx_t_7));
-      __pyx_t_5 = PyNumber_Add(((PyObject *)__pyx_t_7), ((PyObject *)__pyx_kp_s_145)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyNumber_Add(((PyObject *)__pyx_t_7), ((PyObject *)__pyx_kp_s_145)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_DECREF(((PyObject *)__pyx_t_7)); __pyx_t_7 = 0;
-      __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_w2); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_7 = PyBytes_FromString(__pyx_f_3_sa_sym_tostring(__pyx_t_6)); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = __Pyx_PyInt_AsInt(__pyx_v_w2); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyBytes_FromString(__pyx_f_3_sa_sym_tostring(__pyx_t_6)); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(((PyObject *)__pyx_t_7));
-      __pyx_t_11 = PyNumber_Add(__pyx_t_5, ((PyObject *)__pyx_t_7)); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_11 = PyNumber_Add(__pyx_t_5, ((PyObject *)__pyx_t_7)); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_11);
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_7)); __pyx_t_7 = 0;
-      __pyx_t_7 = PyNumber_Add(__pyx_t_11, ((PyObject *)__pyx_kp_s_145)); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_7 = PyNumber_Add(__pyx_t_11, ((PyObject *)__pyx_kp_s_145)); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_7);
       __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-      __pyx_t_11 = PyObject_GetItem(__pyx_v_self->bilex_fe, __pyx_v_w); if (!__pyx_t_11) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_11 = PyObject_GetItem(__pyx_v_self->bilex_fe, __pyx_v_w); if (!__pyx_t_11) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_11);
-      __pyx_t_5 = PyObject_GetItem(__pyx_t_11, __pyx_v_w2); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyObject_GetItem(__pyx_t_11, __pyx_v_w2); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-      __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_11);
       PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_5);
       __Pyx_GIVEREF(__pyx_t_5);
       __pyx_t_5 = 0;
-      __pyx_t_5 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_11), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_11), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_DECREF(((PyObject *)__pyx_t_11)); __pyx_t_11 = 0;
-      __pyx_t_11 = PyNumber_Add(__pyx_t_7, __pyx_t_5); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_11 = PyNumber_Add(__pyx_t_7, __pyx_t_5); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_11);
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
       PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_11);
       __Pyx_GIVEREF(__pyx_t_11);
       __pyx_t_11 = 0;
-      __pyx_t_11 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_11 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_11);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
@@ -63966,24 +64034,24 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2131
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2133
  *             for w2 in self.bilex_fe[w]:
  *                 logger.info(sym_tostring(w) + ' : ' + sym_tostring(w2) + ' : ' + str(self.bilex_fe[w][w2]))
  *         logger.info('F')             # <<<<<<<<<<<<<<
  *         for ph in self.phrases_f:
  *             logger.info(str(ph) + ' ||| ' + str(self.phrases_f[ph]))
  */
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_8 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_8 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_8);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_k_tuple_148), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_k_tuple_148), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2132
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2134
  *                 logger.info(sym_tostring(w) + ' : ' + sym_tostring(w2) + ' : ' + str(self.bilex_fe[w][w2]))
  *         logger.info('F')
  *         for ph in self.phrases_f:             # <<<<<<<<<<<<<<
@@ -63994,7 +64062,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
     __pyx_t_1 = __pyx_v_self->phrases_f; __Pyx_INCREF(__pyx_t_1); __pyx_t_3 = 0;
     __pyx_t_4 = NULL;
   } else {
-    __pyx_t_3 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_self->phrases_f); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_self->phrases_f); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_4 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -64002,23 +64070,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
     if (!__pyx_t_4 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_8 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_8); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_8); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_8 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_4 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_8 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_8); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_8); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_8 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_8 = __pyx_t_4(__pyx_t_1);
       if (unlikely(!__pyx_t_8)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -64028,49 +64096,49 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
     __pyx_v_ph = __pyx_t_8;
     __pyx_t_8 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2133
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2135
  *         logger.info('F')
  *         for ph in self.phrases_f:
  *             logger.info(str(ph) + ' ||| ' + str(self.phrases_f[ph]))             # <<<<<<<<<<<<<<
  *         logger.info('E')
  *         for ph in self.phrases_e:
  */
-    __pyx_t_8 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
-    __pyx_t_11 = PyObject_GetAttr(__pyx_t_8, __pyx_n_s__info); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_11 = PyObject_GetAttr(__pyx_t_8, __pyx_n_s__info); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_11);
     __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-    __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
     __Pyx_INCREF(__pyx_v_ph);
     PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_ph);
     __Pyx_GIVEREF(__pyx_v_ph);
-    __pyx_t_5 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(((PyObject *)__pyx_t_8)); __pyx_t_8 = 0;
-    __pyx_t_8 = PyNumber_Add(__pyx_t_5, ((PyObject *)__pyx_kp_s_18)); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyNumber_Add(__pyx_t_5, ((PyObject *)__pyx_kp_s_18)); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __pyx_t_5 = PyObject_GetItem(__pyx_v_self->phrases_f, __pyx_v_ph); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyObject_GetItem(__pyx_v_self->phrases_f, __pyx_v_ph); if (!__pyx_t_5) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_5);
     __Pyx_GIVEREF(__pyx_t_5);
     __pyx_t_5 = 0;
-    __pyx_t_5 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
-    __pyx_t_2 = PyNumber_Add(__pyx_t_8, __pyx_t_5); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyNumber_Add(__pyx_t_8, __pyx_t_5); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2135; __pyx_clineno = __LINE__; goto __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_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2);
     __Pyx_GIVEREF(__pyx_t_2);
     __pyx_t_2 = 0;
-    __pyx_t_2 = PyObject_Call(__pyx_t_11, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyObject_Call(__pyx_t_11, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
@@ -64078,24 +64146,24 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2134
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2136
  *         for ph in self.phrases_f:
  *             logger.info(str(ph) + ' ||| ' + str(self.phrases_f[ph]))
  *         logger.info('E')             # <<<<<<<<<<<<<<
  *         for ph in self.phrases_e:
  *             logger.info(str(ph) + ' ||| ' + str(self.phrases_e[ph]))
  */
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_k_tuple_149), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_k_tuple_149), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2135
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2137
  *             logger.info(str(ph) + ' ||| ' + str(self.phrases_f[ph]))
  *         logger.info('E')
  *         for ph in self.phrases_e:             # <<<<<<<<<<<<<<
@@ -64106,7 +64174,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
     __pyx_t_1 = __pyx_v_self->phrases_e; __Pyx_INCREF(__pyx_t_1); __pyx_t_3 = 0;
     __pyx_t_4 = NULL;
   } else {
-    __pyx_t_3 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_self->phrases_e); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_self->phrases_e); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_4 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -64114,23 +64182,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
     if (!__pyx_t_4 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_2 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_2); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_2); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_4 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_2); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_3); __Pyx_INCREF(__pyx_t_2); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_2 = __pyx_t_4(__pyx_t_1);
       if (unlikely(!__pyx_t_2)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -64140,49 +64208,49 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
     __pyx_v_ph = __pyx_t_2;
     __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2136
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2138
  *         logger.info('E')
  *         for ph in self.phrases_e:
  *             logger.info(str(ph) + ' ||| ' + str(self.phrases_e[ph]))             # <<<<<<<<<<<<<<
  *         logger.info('FE')
  *         self.dump_online_rules()
  */
-    __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_5 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__info); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__info); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_INCREF(__pyx_v_ph);
     PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_ph);
     __Pyx_GIVEREF(__pyx_v_ph);
-    __pyx_t_11 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_11 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_11);
     __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
-    __pyx_t_2 = PyNumber_Add(__pyx_t_11, ((PyObject *)__pyx_kp_s_18)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyNumber_Add(__pyx_t_11, ((PyObject *)__pyx_kp_s_18)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-    __pyx_t_11 = PyObject_GetItem(__pyx_v_self->phrases_e, __pyx_v_ph); if (!__pyx_t_11) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_11 = PyObject_GetItem(__pyx_v_self->phrases_e, __pyx_v_ph); if (!__pyx_t_11) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_11);
-    __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
     PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_11);
     __Pyx_GIVEREF(__pyx_t_11);
     __pyx_t_11 = 0;
-    __pyx_t_11 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_11 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_8), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_11);
     __Pyx_DECREF(((PyObject *)__pyx_t_8)); __pyx_t_8 = 0;
-    __pyx_t_8 = PyNumber_Add(__pyx_t_2, __pyx_t_11); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyNumber_Add(__pyx_t_2, __pyx_t_11); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-    __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_11);
     PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_8);
     __Pyx_GIVEREF(__pyx_t_8);
     __pyx_t_8 = 0;
-    __pyx_t_8 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_11), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = PyObject_Call(__pyx_t_5, ((PyObject *)__pyx_t_11), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_8);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_11)); __pyx_t_11 = 0;
@@ -64190,33 +64258,33 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_31dump_online_stats(str
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2137
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2139
  *         for ph in self.phrases_e:
  *             logger.info(str(ph) + ' ||| ' + str(self.phrases_e[ph]))
  *         logger.info('FE')             # <<<<<<<<<<<<<<
  *         self.dump_online_rules()
  * 
  */
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_8 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_8 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__info); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_8);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_k_tuple_150), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_k_tuple_150), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2138
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2140
  *             logger.info(str(ph) + ' ||| ' + str(self.phrases_e[ph]))
  *         logger.info('FE')
  *         self.dump_online_rules()             # <<<<<<<<<<<<<<
  * 
  *     def dump_online_rules(self):
  */
-  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__dump_online_rules); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__dump_online_rules); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_8 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_8 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_8);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
@@ -64252,7 +64320,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_34dump_online_rules(PyO
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2140
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2142
  *         self.dump_online_rules()
  * 
  *     def dump_online_rules(self):             # <<<<<<<<<<<<<<
@@ -64282,7 +64350,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_33dump_online_rules(str
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("dump_online_rules", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2141
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2143
  * 
  *     def dump_online_rules(self):
  *         for ph in self.phrases_fe:             # <<<<<<<<<<<<<<
@@ -64293,7 +64361,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_33dump_online_rules(str
     __pyx_t_1 = __pyx_v_self->phrases_fe; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
     __pyx_t_3 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_self->phrases_fe); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_self->phrases_fe); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -64301,23 +64369,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_33dump_online_rules(str
     if (!__pyx_t_3 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 2141; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_3 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __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_filename = __pyx_f[8]; __pyx_lineno = 2141; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_4 = __pyx_t_3(__pyx_t_1);
       if (unlikely(!__pyx_t_4)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
@@ -64327,20 +64395,20 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_33dump_online_rules(str
     __pyx_v_ph = __pyx_t_4;
     __pyx_t_4 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2142
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2144
  *     def dump_online_rules(self):
  *         for ph in self.phrases_fe:
  *             for ph2 in self.phrases_fe[ph]:             # <<<<<<<<<<<<<<
  *                 logger.info(self.fmt_rule(str(ph), str(ph2), self.phrases_al[ph][ph2]) + ' ||| ' + str(self.phrases_fe[ph][ph2]))
  * 
  */
-    __pyx_t_4 = PyObject_GetItem(__pyx_v_self->phrases_fe, __pyx_v_ph); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_GetItem(__pyx_v_self->phrases_fe, __pyx_v_ph); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     if (PyList_CheckExact(__pyx_t_4) || PyTuple_CheckExact(__pyx_t_4)) {
       __pyx_t_5 = __pyx_t_4; __Pyx_INCREF(__pyx_t_5); __pyx_t_6 = 0;
       __pyx_t_7 = NULL;
     } else {
-      __pyx_t_6 = -1; __pyx_t_5 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = -1; __pyx_t_5 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
       __pyx_t_7 = Py_TYPE(__pyx_t_5)->tp_iternext;
     }
@@ -64349,23 +64417,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_33dump_online_rules(str
       if (!__pyx_t_7 && PyList_CheckExact(__pyx_t_5)) {
         if (__pyx_t_6 >= PyList_GET_SIZE(__pyx_t_5)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_4 = PyList_GET_ITEM(__pyx_t_5, __pyx_t_6); __Pyx_INCREF(__pyx_t_4); __pyx_t_6++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyList_GET_ITEM(__pyx_t_5, __pyx_t_6); __Pyx_INCREF(__pyx_t_4); __pyx_t_6++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_4 = PySequence_ITEM(__pyx_t_5, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PySequence_ITEM(__pyx_t_5, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else if (!__pyx_t_7 && PyTuple_CheckExact(__pyx_t_5)) {
         if (__pyx_t_6 >= PyTuple_GET_SIZE(__pyx_t_5)) break;
         #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_5, __pyx_t_6); __Pyx_INCREF(__pyx_t_4); __pyx_t_6++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_5, __pyx_t_6); __Pyx_INCREF(__pyx_t_4); __pyx_t_6++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #else
-        __pyx_t_4 = PySequence_ITEM(__pyx_t_5, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PySequence_ITEM(__pyx_t_5, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         #endif
       } else {
         __pyx_t_4 = __pyx_t_7(__pyx_t_5);
         if (unlikely(!__pyx_t_4)) {
           if (PyErr_Occurred()) {
             if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+            else {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
           }
           break;
         }
@@ -64375,42 +64443,42 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_33dump_online_rules(str
       __pyx_v_ph2 = __pyx_t_4;
       __pyx_t_4 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2143
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2145
  *         for ph in self.phrases_fe:
  *             for ph2 in self.phrases_fe[ph]:
  *                 logger.info(self.fmt_rule(str(ph), str(ph2), self.phrases_al[ph][ph2]) + ' ||| ' + str(self.phrases_fe[ph][ph2]))             # <<<<<<<<<<<<<<
  * 
  *     # Lookup online stats for phrase pair (f, e).  Return None if no match.
  */
-      __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__logger); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_8 = PyObject_GetAttr(__pyx_t_4, __pyx_n_s__info); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = PyObject_GetAttr(__pyx_t_4, __pyx_n_s__info); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_4 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__fmt_rule); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__fmt_rule); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_9);
       __Pyx_INCREF(__pyx_v_ph);
       PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_v_ph);
       __Pyx_GIVEREF(__pyx_v_ph);
-      __pyx_t_10 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_10 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_10);
       __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
-      __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_9);
       __Pyx_INCREF(__pyx_v_ph2);
       PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_v_ph2);
       __Pyx_GIVEREF(__pyx_v_ph2);
-      __pyx_t_11 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_11 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_11);
       __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
-      __pyx_t_9 = PyObject_GetItem(__pyx_v_self->phrases_al, __pyx_v_ph); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_9 = PyObject_GetItem(__pyx_v_self->phrases_al, __pyx_v_ph); if (!__pyx_t_9) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_9);
-      __pyx_t_12 = PyObject_GetItem(__pyx_t_9, __pyx_v_ph2); if (!__pyx_t_12) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_12 = PyObject_GetItem(__pyx_t_9, __pyx_v_ph2); if (!__pyx_t_12) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_12);
       __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-      __pyx_t_9 = PyTuple_New(3); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_9 = PyTuple_New(3); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_9);
       PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_10);
       __Pyx_GIVEREF(__pyx_t_10);
@@ -64421,36 +64489,36 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_33dump_online_rules(str
       __pyx_t_10 = 0;
       __pyx_t_11 = 0;
       __pyx_t_12 = 0;
-      __pyx_t_12 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_12 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_12);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
-      __pyx_t_9 = PyNumber_Add(__pyx_t_12, ((PyObject *)__pyx_kp_s_18)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_9 = PyNumber_Add(__pyx_t_12, ((PyObject *)__pyx_kp_s_18)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_9);
       __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
-      __pyx_t_12 = PyObject_GetItem(__pyx_v_self->phrases_fe, __pyx_v_ph); if (!__pyx_t_12) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_12 = PyObject_GetItem(__pyx_v_self->phrases_fe, __pyx_v_ph); if (!__pyx_t_12) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_12);
-      __pyx_t_4 = PyObject_GetItem(__pyx_t_12, __pyx_v_ph2); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_GetItem(__pyx_t_12, __pyx_v_ph2); if (!__pyx_t_4) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
-      __pyx_t_12 = PyTuple_New(1); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_12 = PyTuple_New(1); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_12);
       PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_t_4);
       __Pyx_GIVEREF(__pyx_t_4);
       __pyx_t_4 = 0;
-      __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_12), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_12), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(((PyObject *)__pyx_t_12)); __pyx_t_12 = 0;
-      __pyx_t_12 = PyNumber_Add(__pyx_t_9, __pyx_t_4); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_12 = PyNumber_Add(__pyx_t_9, __pyx_t_4); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_12);
       __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_12);
       __Pyx_GIVEREF(__pyx_t_12);
       __pyx_t_12 = 0;
-      __pyx_t_12 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_12 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_12);
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
@@ -64509,11 +64577,11 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_36online_ctx_lookup(PyO
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__e)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("online_ctx_lookup", 1, 2, 2, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2147; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("online_ctx_lookup", 1, 2, 2, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2149; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "online_ctx_lookup") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2147; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "online_ctx_lookup") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2149; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -64526,7 +64594,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_36online_ctx_lookup(PyO
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("online_ctx_lookup", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2147; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("online_ctx_lookup", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2149; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.online_ctx_lookup", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -64537,7 +64605,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_36online_ctx_lookup(PyO
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2147
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2149
  *     # Lookup online stats for phrase pair (f, e).  Return None if no match.
  *     # IMPORTANT: use get() to avoid adding items to defaultdict
  *     def online_ctx_lookup(self, f, e):             # <<<<<<<<<<<<<<
@@ -64562,7 +64630,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_35online_ctx_lookup(str
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("online_ctx_lookup", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2148
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2150
  *     # IMPORTANT: use get() to avoid adding items to defaultdict
  *     def online_ctx_lookup(self, f, e):
  *         if self.online:             # <<<<<<<<<<<<<<
@@ -64571,16 +64639,16 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_35online_ctx_lookup(str
  */
   if (__pyx_v_self->online) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2149
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2151
  *     def online_ctx_lookup(self, f, e):
  *         if self.online:
  *             fcount = self.phrases_f.get(f, 0)             # <<<<<<<<<<<<<<
  *             fsample_count = self.samples_f.get(f, 0)
  *             d = self.phrases_fe.get(f, None)
  */
-    __pyx_t_1 = PyObject_GetAttr(__pyx_v_self->phrases_f, __pyx_n_s__get); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_GetAttr(__pyx_v_self->phrases_f, __pyx_n_s__get); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_INCREF(__pyx_v_f);
     PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_f);
@@ -64588,23 +64656,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_35online_ctx_lookup(str
     __Pyx_INCREF(__pyx_int_0);
     PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_int_0);
     __Pyx_GIVEREF(__pyx_int_0);
-    __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
     __pyx_v_fcount = __pyx_t_3;
     __pyx_t_3 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2150
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2152
  *         if self.online:
  *             fcount = self.phrases_f.get(f, 0)
  *             fsample_count = self.samples_f.get(f, 0)             # <<<<<<<<<<<<<<
  *             d = self.phrases_fe.get(f, None)
  *             paircount = d.get(e, 0) if d else 0
  */
-    __pyx_t_3 = PyObject_GetAttr(__pyx_v_self->samples_f, __pyx_n_s__get); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_GetAttr(__pyx_v_self->samples_f, __pyx_n_s__get); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_INCREF(__pyx_v_f);
     PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_f);
@@ -64612,23 +64680,23 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_35online_ctx_lookup(str
     __Pyx_INCREF(__pyx_int_0);
     PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_int_0);
     __Pyx_GIVEREF(__pyx_int_0);
-    __pyx_t_1 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
     __pyx_v_fsample_count = __pyx_t_1;
     __pyx_t_1 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2151
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2153
  *             fcount = self.phrases_f.get(f, 0)
  *             fsample_count = self.samples_f.get(f, 0)
  *             d = self.phrases_fe.get(f, None)             # <<<<<<<<<<<<<<
  *             paircount = d.get(e, 0) if d else 0
- *             return OnlineFeatureContext(fcount, fsample_count, paircount, self.bilex_fe)
+ *             return OnlineFeatureContext(fcount, fsample_count, paircount, self.bilex_f, self.bilex_e, self.bilex_fe)
  */
-    __pyx_t_1 = PyObject_GetAttr(__pyx_v_self->phrases_fe, __pyx_n_s__get); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_GetAttr(__pyx_v_self->phrases_fe, __pyx_n_s__get); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_INCREF(__pyx_v_f);
     PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_f);
@@ -64636,25 +64704,25 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_35online_ctx_lookup(str
     __Pyx_INCREF(Py_None);
     PyTuple_SET_ITEM(__pyx_t_2, 1, Py_None);
     __Pyx_GIVEREF(Py_None);
-    __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
     __pyx_v_d = __pyx_t_3;
     __pyx_t_3 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2152
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2154
  *             fsample_count = self.samples_f.get(f, 0)
  *             d = self.phrases_fe.get(f, None)
  *             paircount = d.get(e, 0) if d else 0             # <<<<<<<<<<<<<<
- *             return OnlineFeatureContext(fcount, fsample_count, paircount, self.bilex_fe)
+ *             return OnlineFeatureContext(fcount, fsample_count, paircount, self.bilex_f, self.bilex_e, self.bilex_fe)
  *         return None
  */
-    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_d); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_d); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     if (__pyx_t_4) {
-      __pyx_t_2 = PyObject_GetAttr(__pyx_v_d, __pyx_n_s__get); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_GetAttr(__pyx_v_d, __pyx_n_s__get); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_INCREF(__pyx_v_e);
       PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_e);
@@ -64662,7 +64730,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_35online_ctx_lookup(str
       __Pyx_INCREF(__pyx_int_0);
       PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_0);
       __Pyx_GIVEREF(__pyx_int_0);
-      __pyx_t_5 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
@@ -64675,17 +64743,17 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_35online_ctx_lookup(str
     __pyx_v_paircount = __pyx_t_3;
     __pyx_t_3 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2153
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2155
  *             d = self.phrases_fe.get(f, None)
  *             paircount = d.get(e, 0) if d else 0
- *             return OnlineFeatureContext(fcount, fsample_count, paircount, self.bilex_fe)             # <<<<<<<<<<<<<<
+ *             return OnlineFeatureContext(fcount, fsample_count, paircount, self.bilex_f, self.bilex_e, self.bilex_fe)             # <<<<<<<<<<<<<<
  *         return None
  * 
  */
     __Pyx_XDECREF(__pyx_r);
-    __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s_151); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s_151); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyTuple_New(6); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_INCREF(__pyx_v_fcount);
     PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_fcount);
@@ -64696,10 +64764,16 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_35online_ctx_lookup(str
     __Pyx_INCREF(__pyx_v_paircount);
     PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_v_paircount);
     __Pyx_GIVEREF(__pyx_v_paircount);
+    __Pyx_INCREF(__pyx_v_self->bilex_f);
+    PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_v_self->bilex_f);
+    __Pyx_GIVEREF(__pyx_v_self->bilex_f);
+    __Pyx_INCREF(__pyx_v_self->bilex_e);
+    PyTuple_SET_ITEM(__pyx_t_5, 4, __pyx_v_self->bilex_e);
+    __Pyx_GIVEREF(__pyx_v_self->bilex_e);
     __Pyx_INCREF(__pyx_v_self->bilex_fe);
-    PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_v_self->bilex_fe);
+    PyTuple_SET_ITEM(__pyx_t_5, 5, __pyx_v_self->bilex_fe);
     __Pyx_GIVEREF(__pyx_v_self->bilex_fe);
-    __pyx_t_1 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
@@ -64710,9 +64784,9 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_35online_ctx_lookup(str
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2154
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2156
  *             paircount = d.get(e, 0) if d else 0
- *             return OnlineFeatureContext(fcount, fsample_count, paircount, self.bilex_fe)
+ *             return OnlineFeatureContext(fcount, fsample_count, paircount, self.bilex_f, self.bilex_e, self.bilex_fe)
  *         return None             # <<<<<<<<<<<<<<
  * 
  *     # Find all phrases that we might try to extract
@@ -64791,36 +64865,36 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_13get_f_phrases_1extrac
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__f_j)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("extract", 1, 7, 7, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2164; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("extract", 1, 7, 7, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__lex_i)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("extract", 1, 7, 7, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2164; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("extract", 1, 7, 7, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  3:
         if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__lex_j)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("extract", 1, 7, 7, 3); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2164; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("extract", 1, 7, 7, 3); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  4:
         if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__wc)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("extract", 1, 7, 7, 4); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2164; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("extract", 1, 7, 7, 4); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  5:
         if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__ntc)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("extract", 1, 7, 7, 5); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2164; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("extract", 1, 7, 7, 5); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  6:
         if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__syms)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("extract", 1, 7, 7, 6); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2164; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("extract", 1, 7, 7, 6); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "extract") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2164; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "extract") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 7) {
       goto __pyx_L5_argtuple_error;
@@ -64843,7 +64917,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_13get_f_phrases_1extrac
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("extract", 1, 7, 7, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2164; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("extract", 1, 7, 7, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.HieroCachingRuleFactory.get_f_phrases.extract", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -64854,7 +64928,7 @@ static PyObject *__pyx_pw_3_sa_23HieroCachingRuleFactory_13get_f_phrases_1extrac
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2164
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2166
  *         phrases = set() # (fphrase, lex_i, lex_j)
  * 
  *         def extract(f_i, f_j, lex_i, lex_j, wc, ntc, syms):             # <<<<<<<<<<<<<<
@@ -64886,33 +64960,33 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_13get_f_phrases_extract
   __pyx_outer_scope = (struct __pyx_obj_3_sa___pyx_scope_struct_26_get_f_phrases *) __Pyx_CyFunction_GetClosure(__pyx_self);
   __pyx_cur_scope = __pyx_outer_scope;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2166
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2168
  *         def extract(f_i, f_j, lex_i, lex_j, wc, ntc, syms):
  *             # Phrase extraction limits
  *             if f_j > (f_len - 1) or (f_j - f_i) + 1 > self.max_initial_size:             # <<<<<<<<<<<<<<
  *                 return
  *             # Extend with word
  */
-  if (unlikely(!__pyx_cur_scope->__pyx_v_f_len)) { __Pyx_RaiseClosureNameError("f_len"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-  __pyx_t_1 = PyNumber_Subtract(__pyx_cur_scope->__pyx_v_f_len, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__pyx_cur_scope->__pyx_v_f_len)) { __Pyx_RaiseClosureNameError("f_len"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2168; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+  __pyx_t_1 = PyNumber_Subtract(__pyx_cur_scope->__pyx_v_f_len, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_RichCompare(__pyx_v_f_j, __pyx_t_1, Py_GT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_RichCompare(__pyx_v_f_j, __pyx_t_1, Py_GT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   if (!__pyx_t_3) {
-    __pyx_t_2 = PyNumber_Subtract(__pyx_v_f_j, __pyx_v_f_i); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyNumber_Subtract(__pyx_v_f_j, __pyx_v_f_i); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    if (unlikely(!__pyx_cur_scope->__pyx_v_self)) { __Pyx_RaiseClosureNameError("self"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-    __pyx_t_2 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_initial_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_cur_scope->__pyx_v_self)) { __Pyx_RaiseClosureNameError("self"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2168; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+    __pyx_t_2 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_initial_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_4 = PyObject_RichCompare(__pyx_t_1, __pyx_t_2, Py_GT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_RichCompare(__pyx_t_1, __pyx_t_2, Py_GT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __pyx_t_6 = __pyx_t_5;
   } else {
@@ -64920,7 +64994,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_13get_f_phrases_extract
   }
   if (__pyx_t_6) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2167
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2169
  *             # Phrase extraction limits
  *             if f_j > (f_len - 1) or (f_j - f_i) + 1 > self.max_initial_size:
  *                 return             # <<<<<<<<<<<<<<
@@ -64934,58 +65008,58 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_13get_f_phrases_extract
   }
   __pyx_L3:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2169
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2171
  *                 return
  *             # Extend with word
  *             if wc + ntc < self.max_length:             # <<<<<<<<<<<<<<
  *                 syms.append(f_words[f_j])
  *                 f = Phrase(syms)
  */
-  __pyx_t_4 = PyNumber_Add(__pyx_v_wc, __pyx_v_ntc); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyNumber_Add(__pyx_v_wc, __pyx_v_ntc); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_2 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_length); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_length); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_1 = PyObject_RichCompare(__pyx_t_4, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_RichCompare(__pyx_t_4, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   if (__pyx_t_6) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2170
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2172
  *             # Extend with word
  *             if wc + ntc < self.max_length:
  *                 syms.append(f_words[f_j])             # <<<<<<<<<<<<<<
  *                 f = Phrase(syms)
  *                 new_lex_i = min(lex_i, f_j)
  */
-    if (unlikely(!__pyx_cur_scope->__pyx_v_f_words)) { __Pyx_RaiseClosureNameError("f_words"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2170; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-    __pyx_t_1 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_f_words, __pyx_v_f_j); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_cur_scope->__pyx_v_f_words)) { __Pyx_RaiseClosureNameError("f_words"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2172; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+    __pyx_t_1 = PyObject_GetItem(__pyx_cur_scope->__pyx_v_f_words, __pyx_v_f_j); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_2 = __Pyx_PyObject_Append(__pyx_v_syms, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_PyObject_Append(__pyx_v_syms, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2171
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2173
  *             if wc + ntc < self.max_length:
  *                 syms.append(f_words[f_j])
  *                 f = Phrase(syms)             # <<<<<<<<<<<<<<
  *                 new_lex_i = min(lex_i, f_j)
  *                 new_lex_j = max(lex_j, f_j)
  */
-    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_INCREF(__pyx_v_syms);
     PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_syms);
     __Pyx_GIVEREF(__pyx_v_syms);
-    __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
     __pyx_v_f = ((struct __pyx_obj_3_sa_Phrase *)__pyx_t_1);
     __pyx_t_1 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2172
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2174
  *                 syms.append(f_words[f_j])
  *                 f = Phrase(syms)
  *                 new_lex_i = min(lex_i, f_j)             # <<<<<<<<<<<<<<
@@ -64996,8 +65070,8 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_13get_f_phrases_extract
     __pyx_t_1 = __pyx_v_f_j;
     __Pyx_INCREF(__pyx_v_lex_i);
     __pyx_t_2 = __pyx_v_lex_i;
-    __pyx_t_7 = PyObject_RichCompare(__pyx_t_1, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyObject_RichCompare(__pyx_t_1, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     if (__pyx_t_6) {
       __Pyx_INCREF(__pyx_t_1);
@@ -65012,7 +65086,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_13get_f_phrases_extract
     __pyx_v_new_lex_i = __pyx_t_4;
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2173
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2175
  *                 f = Phrase(syms)
  *                 new_lex_i = min(lex_i, f_j)
  *                 new_lex_j = max(lex_j, f_j)             # <<<<<<<<<<<<<<
@@ -65023,8 +65097,8 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_13get_f_phrases_extract
     __pyx_t_4 = __pyx_v_f_j;
     __Pyx_INCREF(__pyx_v_lex_j);
     __pyx_t_1 = __pyx_v_lex_j;
-    __pyx_t_7 = PyObject_RichCompare(__pyx_t_4, __pyx_t_1, Py_GT); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyObject_RichCompare(__pyx_t_4, __pyx_t_1, Py_GT); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     if (__pyx_t_6) {
       __Pyx_INCREF(__pyx_t_4);
@@ -65039,17 +65113,17 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_13get_f_phrases_extract
     __pyx_v_new_lex_j = __pyx_t_2;
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2174
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2176
  *                 new_lex_i = min(lex_i, f_j)
  *                 new_lex_j = max(lex_j, f_j)
  *                 phrases.add((f, new_lex_i, new_lex_j))             # <<<<<<<<<<<<<<
  *                 extract(f_i, f_j + 1, new_lex_i, new_lex_j, wc + 1, ntc, syms)
  *                 syms.pop()
  */
-    if (unlikely(!__pyx_cur_scope->__pyx_v_phrases)) { __Pyx_RaiseClosureNameError("phrases"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-    __pyx_t_2 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_phrases, __pyx_n_s__add); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_cur_scope->__pyx_v_phrases)) { __Pyx_RaiseClosureNameError("phrases"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2176; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+    __pyx_t_2 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_phrases, __pyx_n_s__add); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_INCREF(((PyObject *)__pyx_v_f));
     PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_v_f));
@@ -65060,30 +65134,30 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_13get_f_phrases_extract
     __Pyx_INCREF(__pyx_v_new_lex_j);
     PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_v_new_lex_j);
     __Pyx_GIVEREF(__pyx_v_new_lex_j);
-    __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_t_4));
     __Pyx_GIVEREF(((PyObject *)__pyx_t_4));
     __pyx_t_4 = 0;
-    __pyx_t_4 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2175
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2177
  *                 new_lex_j = max(lex_j, f_j)
  *                 phrases.add((f, new_lex_i, new_lex_j))
  *                 extract(f_i, f_j + 1, new_lex_i, new_lex_j, wc + 1, ntc, syms)             # <<<<<<<<<<<<<<
  *                 syms.pop()
  *             # Extend with existing non-terminal
  */
-    if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2175; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-    __pyx_t_4 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2177; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+    __pyx_t_4 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_1 = PyNumber_Add(__pyx_v_wc, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyNumber_Add(__pyx_v_wc, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_2 = PyTuple_New(7); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyTuple_New(7); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_INCREF(__pyx_v_f_i);
     PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_f_i);
@@ -65106,37 +65180,37 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_13get_f_phrases_extract
     __Pyx_GIVEREF(__pyx_v_syms);
     __pyx_t_4 = 0;
     __pyx_t_1 = 0;
-    __pyx_t_1 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2176
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2178
  *                 phrases.add((f, new_lex_i, new_lex_j))
  *                 extract(f_i, f_j + 1, new_lex_i, new_lex_j, wc + 1, ntc, syms)
  *                 syms.pop()             # <<<<<<<<<<<<<<
  *             # Extend with existing non-terminal
  *             if syms and sym_isvar(syms[-1]):
  */
-    __pyx_t_1 = __Pyx_PyObject_Pop(__pyx_v_syms); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_PyObject_Pop(__pyx_v_syms); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     goto __pyx_L4;
   }
   __pyx_L4:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2178
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2180
  *                 syms.pop()
  *             # Extend with existing non-terminal
  *             if syms and sym_isvar(syms[-1]):             # <<<<<<<<<<<<<<
  *                 # Don't re-extract the same phrase
  *                 extract(f_i, f_j + 1, lex_i, lex_j, wc, ntc, syms)
  */
-  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_syms); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_syms); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   if (__pyx_t_6) {
-    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_syms, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_syms, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_8 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_8 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_8 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_8 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __pyx_t_3 = __pyx_f_3_sa_sym_isvar(__pyx_t_8);
   } else {
@@ -65144,17 +65218,17 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_13get_f_phrases_extract
   }
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2180
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2182
  *             if syms and sym_isvar(syms[-1]):
  *                 # Don't re-extract the same phrase
  *                 extract(f_i, f_j + 1, lex_i, lex_j, wc, ntc, syms)             # <<<<<<<<<<<<<<
  *             # Extend with new non-terminal
  *             if wc + ntc < self.max_length:
  */
-    if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2180; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-    __pyx_t_1 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2182; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+    __pyx_t_1 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_2 = PyTuple_New(7); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyTuple_New(7); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_INCREF(__pyx_v_f_i);
     PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_f_i);
@@ -65177,7 +65251,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_13get_f_phrases_extract
     PyTuple_SET_ITEM(__pyx_t_2, 6, __pyx_v_syms);
     __Pyx_GIVEREF(__pyx_v_syms);
     __pyx_t_1 = 0;
-    __pyx_t_1 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -65185,44 +65259,44 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_13get_f_phrases_extract
   }
   __pyx_L5:;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2182
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2184
  *                 extract(f_i, f_j + 1, lex_i, lex_j, wc, ntc, syms)
  *             # Extend with new non-terminal
  *             if wc + ntc < self.max_length:             # <<<<<<<<<<<<<<
  *                 if not syms or (ntc < self.max_nonterminals and not sym_isvar(syms[-1])):
  *                     syms.append(sym_setindex(self.category, ntc + 1))
  */
-  __pyx_t_1 = PyNumber_Add(__pyx_v_wc, __pyx_v_ntc); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyNumber_Add(__pyx_v_wc, __pyx_v_ntc); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_length); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_length); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = PyObject_RichCompare(__pyx_t_1, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyObject_RichCompare(__pyx_t_1, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   if (__pyx_t_3) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2183
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2185
  *             # Extend with new non-terminal
  *             if wc + ntc < self.max_length:
  *                 if not syms or (ntc < self.max_nonterminals and not sym_isvar(syms[-1])):             # <<<<<<<<<<<<<<
  *                     syms.append(sym_setindex(self.category, ntc + 1))
  *                     f = Phrase(syms)
  */
-    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_syms); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_syms); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __pyx_t_6 = (!__pyx_t_3);
     if (!__pyx_t_6) {
-      __pyx_t_4 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_nonterminals); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyInt_FromLong(__pyx_cur_scope->__pyx_v_self->max_nonterminals); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_2 = PyObject_RichCompare(__pyx_v_ntc, __pyx_t_4, Py_LT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_RichCompare(__pyx_v_ntc, __pyx_t_4, Py_LT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       if (__pyx_t_3) {
-        __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_syms, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_syms, -1, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
-        __pyx_t_8 = __Pyx_PyInt_AsInt(__pyx_t_2); if (unlikely((__pyx_t_8 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_8 = __Pyx_PyInt_AsInt(__pyx_t_2); if (unlikely((__pyx_t_8 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_t_5 = (!__pyx_f_3_sa_sym_isvar(__pyx_t_8));
         __pyx_t_9 = __pyx_t_5;
@@ -65235,66 +65309,66 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_13get_f_phrases_extract
     }
     if (__pyx_t_3) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2184
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2186
  *             if wc + ntc < self.max_length:
  *                 if not syms or (ntc < self.max_nonterminals and not sym_isvar(syms[-1])):
  *                     syms.append(sym_setindex(self.category, ntc + 1))             # <<<<<<<<<<<<<<
  *                     f = Phrase(syms)
  *                     if wc > 0:
  */
-      __pyx_t_2 = PyNumber_Add(__pyx_v_ntc, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyNumber_Add(__pyx_v_ntc, __pyx_int_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_8 = __Pyx_PyInt_AsInt(__pyx_t_2); if (unlikely((__pyx_t_8 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_8 = __Pyx_PyInt_AsInt(__pyx_t_2); if (unlikely((__pyx_t_8 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_2 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_cur_scope->__pyx_v_self->category, __pyx_t_8)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyInt_FromLong(__pyx_f_3_sa_sym_setindex(__pyx_cur_scope->__pyx_v_self->category, __pyx_t_8)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_4 = __Pyx_PyObject_Append(__pyx_v_syms, __pyx_t_2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_PyObject_Append(__pyx_v_syms, __pyx_t_2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2185
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2187
  *                 if not syms or (ntc < self.max_nonterminals and not sym_isvar(syms[-1])):
  *                     syms.append(sym_setindex(self.category, ntc + 1))
  *                     f = Phrase(syms)             # <<<<<<<<<<<<<<
  *                     if wc > 0:
  *                         phrases.add((f, lex_i, lex_j))
  */
-      __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_INCREF(__pyx_v_syms);
       PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_syms);
       __Pyx_GIVEREF(__pyx_v_syms);
-      __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_3_sa_Phrase)), ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
       __Pyx_XDECREF(((PyObject *)__pyx_v_f));
       __pyx_v_f = ((struct __pyx_obj_3_sa_Phrase *)__pyx_t_2);
       __pyx_t_2 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2186
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2188
  *                     syms.append(sym_setindex(self.category, ntc + 1))
  *                     f = Phrase(syms)
  *                     if wc > 0:             # <<<<<<<<<<<<<<
  *                         phrases.add((f, lex_i, lex_j))
  *                     extract(f_i, f_j + 1, lex_i, lex_j, wc, ntc + 1, syms)
  */
-      __pyx_t_2 = PyObject_RichCompare(__pyx_v_wc, __pyx_int_0, Py_GT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyObject_RichCompare(__pyx_v_wc, __pyx_int_0, Py_GT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       if (__pyx_t_3) {
 
-        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2187
+        /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2189
  *                     f = Phrase(syms)
  *                     if wc > 0:
  *                         phrases.add((f, lex_i, lex_j))             # <<<<<<<<<<<<<<
  *                     extract(f_i, f_j + 1, lex_i, lex_j, wc, ntc + 1, syms)
  *                     syms.pop()
  */
-        if (unlikely(!__pyx_cur_scope->__pyx_v_phrases)) { __Pyx_RaiseClosureNameError("phrases"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2187; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-        __pyx_t_2 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_phrases, __pyx_n_s__add); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        if (unlikely(!__pyx_cur_scope->__pyx_v_phrases)) { __Pyx_RaiseClosureNameError("phrases"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2189; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+        __pyx_t_2 = PyObject_GetAttr(__pyx_cur_scope->__pyx_v_phrases, __pyx_n_s__add); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_2);
-        __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_INCREF(((PyObject *)__pyx_v_f));
         PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_v_f));
@@ -65305,12 +65379,12 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_13get_f_phrases_extract
         __Pyx_INCREF(__pyx_v_lex_j);
         PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_v_lex_j);
         __Pyx_GIVEREF(__pyx_v_lex_j);
-        __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_1);
         PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_t_4));
         __Pyx_GIVEREF(((PyObject *)__pyx_t_4));
         __pyx_t_4 = 0;
-        __pyx_t_4 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_4 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
@@ -65319,19 +65393,19 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_13get_f_phrases_extract
       }
       __pyx_L8:;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2188
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2190
  *                     if wc > 0:
  *                         phrases.add((f, lex_i, lex_j))
  *                     extract(f_i, f_j + 1, lex_i, lex_j, wc, ntc + 1, syms)             # <<<<<<<<<<<<<<
  *                     syms.pop()
  * 
  */
-      if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2188; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
-      __pyx_t_4 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(!__pyx_cur_scope->__pyx_v_extract)) { __Pyx_RaiseClosureNameError("extract"); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2190; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+      __pyx_t_4 = PyNumber_Add(__pyx_v_f_j, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_1 = PyNumber_Add(__pyx_v_ntc, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyNumber_Add(__pyx_v_ntc, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_2 = PyTuple_New(7); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = PyTuple_New(7); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_INCREF(__pyx_v_f_i);
       PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_f_i);
@@ -65354,19 +65428,19 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_13get_f_phrases_extract
       __Pyx_GIVEREF(__pyx_v_syms);
       __pyx_t_4 = 0;
       __pyx_t_1 = 0;
-      __pyx_t_1 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2189
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2191
  *                         phrases.add((f, lex_i, lex_j))
  *                     extract(f_i, f_j + 1, lex_i, lex_j, wc, ntc + 1, syms)
  *                     syms.pop()             # <<<<<<<<<<<<<<
  * 
  *         # Try to extract phrases from every f index
  */
-      __pyx_t_1 = __Pyx_PyObject_Pop(__pyx_v_syms); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_PyObject_Pop(__pyx_v_syms); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       goto __pyx_L7;
@@ -65394,7 +65468,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_13get_f_phrases_extract
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2159
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2161
  *     # (Used for EGivenFCoherent)
  *     # Return set of (fphrase, lex_i, lex_j)
  *     def get_f_phrases(self, f_words):             # <<<<<<<<<<<<<<
@@ -65430,7 +65504,7 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_37get_f_phrases(struct
   __Pyx_INCREF(__pyx_cur_scope->__pyx_v_f_words);
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_f_words);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2161
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2163
  *     def get_f_phrases(self, f_words):
  * 
  *         f_len = len(f_words)             # <<<<<<<<<<<<<<
@@ -65439,64 +65513,64 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_37get_f_phrases(struct
  */
   __pyx_t_1 = __pyx_cur_scope->__pyx_v_f_words;
   __Pyx_INCREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_1);
   __pyx_cur_scope->__pyx_v_f_len = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2162
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2164
  * 
  *         f_len = len(f_words)
  *         phrases = set() # (fphrase, lex_i, lex_j)             # <<<<<<<<<<<<<<
  * 
  *         def extract(f_i, f_j, lex_i, lex_j, wc, ntc, syms):
  */
-  __pyx_t_1 = PySet_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PySet_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
   __pyx_cur_scope->__pyx_v_phrases = ((PyObject *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2164
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2166
  *         phrases = set() # (fphrase, lex_i, lex_j)
  * 
  *         def extract(f_i, f_j, lex_i, lex_j, wc, ntc, syms):             # <<<<<<<<<<<<<<
  *             # Phrase extraction limits
  *             if f_j > (f_len - 1) or (f_j - f_i) + 1 > self.max_initial_size:
  */
-  __pyx_t_1 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_13get_f_phrases_1extract, 0, ((PyObject*)__pyx_cur_scope), __pyx_n_s___sa, ((PyObject *)__pyx_k_codeobj_153)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_CyFunction_NewEx(&__pyx_mdef_3_sa_23HieroCachingRuleFactory_13get_f_phrases_1extract, 0, ((PyObject*)__pyx_cur_scope), __pyx_n_s___sa, ((PyObject *)__pyx_k_codeobj_153)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_1);
   __pyx_cur_scope->__pyx_v_extract = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2192
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2194
  * 
  *         # Try to extract phrases from every f index
  *         for f_i from 0 <= f_i < f_len:             # <<<<<<<<<<<<<<
  *             extract(f_i, f_i, f_len, -1, 0, 0, [])
  * 
  */
-  __pyx_t_3 = __Pyx_PyInt_AsLong(__pyx_cur_scope->__pyx_v_f_len); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = __Pyx_PyInt_AsLong(__pyx_cur_scope->__pyx_v_f_len); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   for (__pyx_v_f_i = 0; __pyx_v_f_i < __pyx_t_3; __pyx_v_f_i++) {
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2193
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2195
  *         # Try to extract phrases from every f index
  *         for f_i from 0 <= f_i < f_len:
  *             extract(f_i, f_i, f_len, -1, 0, 0, [])             # <<<<<<<<<<<<<<
  * 
  *         return phrases
  */
-    __pyx_t_1 = PyInt_FromLong(__pyx_v_f_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyInt_FromLong(__pyx_v_f_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2195; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_4 = PyInt_FromLong(__pyx_v_f_i); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyInt_FromLong(__pyx_v_f_i); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2195; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = PyList_New(0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyList_New(0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2195; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_6 = PyTuple_New(7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyTuple_New(7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2195; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_1);
     __Pyx_GIVEREF(__pyx_t_1);
@@ -65519,13 +65593,13 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_37get_f_phrases(struct
     __pyx_t_1 = 0;
     __pyx_t_4 = 0;
     __pyx_t_5 = 0;
-    __pyx_t_5 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyObject_Call(__pyx_cur_scope->__pyx_v_extract, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2195; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2195
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2197
  *             extract(f_i, f_i, f_len, -1, 0, 0, [])
  * 
  *         return phrases             # <<<<<<<<<<<<<<
@@ -65554,9 +65628,9 @@ static PyObject *__pyx_pf_3_sa_23HieroCachingRuleFactory_37get_f_phrases(struct
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_3_sa_13span_check(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static PyMethodDef __pyx_mdef_3_sa_13span_check = {__Pyx_NAMESTR("span_check"), (PyCFunction)__pyx_pw_3_sa_13span_check, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};
-static PyObject *__pyx_pw_3_sa_13span_check(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_3_sa_15span_check(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_3_sa_15span_check = {__Pyx_NAMESTR("span_check"), (PyCFunction)__pyx_pw_3_sa_15span_check, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pw_3_sa_15span_check(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_vec = 0;
   PyObject *__pyx_v_i = 0;
   PyObject *__pyx_v_j = 0;
@@ -65584,16 +65658,16 @@ static PyObject *__pyx_pw_3_sa_13span_check(PyObject *__pyx_self, PyObject *__py
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__i)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("span_check", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2198; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("span_check", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2200; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__j)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("span_check", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2198; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("span_check", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2200; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "span_check") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2198; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "span_check") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2200; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
       goto __pyx_L5_argtuple_error;
@@ -65608,18 +65682,18 @@ static PyObject *__pyx_pw_3_sa_13span_check(PyObject *__pyx_self, PyObject *__py
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("span_check", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2198; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("span_check", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2200; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.span_check", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_3_sa_12span_check(__pyx_self, __pyx_v_vec, __pyx_v_i, __pyx_v_j);
+  __pyx_r = __pyx_pf_3_sa_14span_check(__pyx_self, __pyx_v_vec, __pyx_v_i, __pyx_v_j);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2198
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2200
  * 
  * # Spans are _inclusive_ on both ends [i, j]
  * def span_check(vec, i, j):             # <<<<<<<<<<<<<<
@@ -65627,7 +65701,7 @@ static PyObject *__pyx_pw_3_sa_13span_check(PyObject *__pyx_self, PyObject *__py
  *     while k <= j:
  */
 
-static PyObject *__pyx_pf_3_sa_12span_check(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_vec, PyObject *__pyx_v_i, PyObject *__pyx_v_j) {
+static PyObject *__pyx_pf_3_sa_14span_check(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_vec, PyObject *__pyx_v_i, PyObject *__pyx_v_j) {
   PyObject *__pyx_v_k = NULL;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
@@ -65638,7 +65712,7 @@ static PyObject *__pyx_pf_3_sa_12span_check(CYTHON_UNUSED PyObject *__pyx_self,
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("span_check", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2199
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2201
  * # Spans are _inclusive_ on both ends [i, j]
  * def span_check(vec, i, j):
  *     k = i             # <<<<<<<<<<<<<<
@@ -65648,7 +65722,7 @@ static PyObject *__pyx_pf_3_sa_12span_check(CYTHON_UNUSED PyObject *__pyx_self,
   __Pyx_INCREF(__pyx_v_i);
   __pyx_v_k = __pyx_v_i;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2200
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2202
  * def span_check(vec, i, j):
  *     k = i
  *     while k <= j:             # <<<<<<<<<<<<<<
@@ -65656,25 +65730,25 @@ static PyObject *__pyx_pf_3_sa_12span_check(CYTHON_UNUSED PyObject *__pyx_self,
  *             return False
  */
   while (1) {
-    __pyx_t_1 = PyObject_RichCompare(__pyx_v_k, __pyx_v_j, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_RichCompare(__pyx_v_k, __pyx_v_j, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2202; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2202; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     if (!__pyx_t_2) break;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2201
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2203
  *     k = i
  *     while k <= j:
  *         if vec[k]:             # <<<<<<<<<<<<<<
  *             return False
  *         k += 1
  */
-    __pyx_t_1 = PyObject_GetItem(__pyx_v_vec, __pyx_v_k); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_GetItem(__pyx_v_vec, __pyx_v_k); if (!__pyx_t_1) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     if (__pyx_t_2) {
 
-      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2202
+      /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2204
  *     while k <= j:
  *         if vec[k]:
  *             return False             # <<<<<<<<<<<<<<
@@ -65682,7 +65756,7 @@ static PyObject *__pyx_pf_3_sa_12span_check(CYTHON_UNUSED PyObject *__pyx_self,
  *     return True
  */
       __Pyx_XDECREF(__pyx_r);
-      __pyx_t_1 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2202; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __pyx_r = __pyx_t_1;
       __pyx_t_1 = 0;
@@ -65691,21 +65765,21 @@ static PyObject *__pyx_pf_3_sa_12span_check(CYTHON_UNUSED PyObject *__pyx_self,
     }
     __pyx_L5:;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2203
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2205
  *         if vec[k]:
  *             return False
  *         k += 1             # <<<<<<<<<<<<<<
  *     return True
  * 
  */
-    __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_k, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_k, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_v_k);
     __pyx_v_k = __pyx_t_1;
     __pyx_t_1 = 0;
   }
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2204
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2206
  *             return False
  *         k += 1
  *     return True             # <<<<<<<<<<<<<<
@@ -65713,7 +65787,7 @@ static PyObject *__pyx_pf_3_sa_12span_check(CYTHON_UNUSED PyObject *__pyx_self,
  * def span_inc(vec, i, j):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2206; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -65733,9 +65807,9 @@ static PyObject *__pyx_pf_3_sa_12span_check(CYTHON_UNUSED PyObject *__pyx_self,
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_3_sa_15span_inc(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static PyMethodDef __pyx_mdef_3_sa_15span_inc = {__Pyx_NAMESTR("span_inc"), (PyCFunction)__pyx_pw_3_sa_15span_inc, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};
-static PyObject *__pyx_pw_3_sa_15span_inc(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_3_sa_17span_inc(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_3_sa_17span_inc = {__Pyx_NAMESTR("span_inc"), (PyCFunction)__pyx_pw_3_sa_17span_inc, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pw_3_sa_17span_inc(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_vec = 0;
   PyObject *__pyx_v_i = 0;
   PyObject *__pyx_v_j = 0;
@@ -65763,16 +65837,16 @@ static PyObject *__pyx_pw_3_sa_15span_inc(PyObject *__pyx_self, PyObject *__pyx_
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__i)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("span_inc", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2206; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("span_inc", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2208; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__j)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("span_inc", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2206; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("span_inc", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2208; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "span_inc") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2206; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "span_inc") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2208; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
       goto __pyx_L5_argtuple_error;
@@ -65787,18 +65861,18 @@ static PyObject *__pyx_pw_3_sa_15span_inc(PyObject *__pyx_self, PyObject *__pyx_
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("span_inc", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2206; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("span_inc", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2208; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.span_inc", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_3_sa_14span_inc(__pyx_self, __pyx_v_vec, __pyx_v_i, __pyx_v_j);
+  __pyx_r = __pyx_pf_3_sa_16span_inc(__pyx_self, __pyx_v_vec, __pyx_v_i, __pyx_v_j);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2206
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2208
  *     return True
  * 
  * def span_inc(vec, i, j):             # <<<<<<<<<<<<<<
@@ -65806,7 +65880,7 @@ static PyObject *__pyx_pw_3_sa_15span_inc(PyObject *__pyx_self, PyObject *__pyx_
  *     while k <= j:
  */
 
-static PyObject *__pyx_pf_3_sa_14span_inc(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_vec, PyObject *__pyx_v_i, PyObject *__pyx_v_j) {
+static PyObject *__pyx_pf_3_sa_16span_inc(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_vec, PyObject *__pyx_v_i, PyObject *__pyx_v_j) {
   PyObject *__pyx_v_k = NULL;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
@@ -65819,7 +65893,7 @@ static PyObject *__pyx_pf_3_sa_14span_inc(CYTHON_UNUSED PyObject *__pyx_self, Py
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("span_inc", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2207
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2209
  * 
  * def span_inc(vec, i, j):
  *     k = i             # <<<<<<<<<<<<<<
@@ -65829,7 +65903,7 @@ static PyObject *__pyx_pf_3_sa_14span_inc(CYTHON_UNUSED PyObject *__pyx_self, Py
   __Pyx_INCREF(__pyx_v_i);
   __pyx_v_k = __pyx_v_i;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2208
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2210
  * def span_inc(vec, i, j):
  *     k = i
  *     while k <= j:             # <<<<<<<<<<<<<<
@@ -65837,12 +65911,12 @@ static PyObject *__pyx_pf_3_sa_14span_inc(CYTHON_UNUSED PyObject *__pyx_self, Py
  *         k += 1
  */
   while (1) {
-    __pyx_t_1 = PyObject_RichCompare(__pyx_v_k, __pyx_v_j, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_RichCompare(__pyx_v_k, __pyx_v_j, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     if (!__pyx_t_2) break;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2209
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2211
  *     k = i
  *     while k <= j:
  *         vec[k] += 1             # <<<<<<<<<<<<<<
@@ -65851,23 +65925,23 @@ static PyObject *__pyx_pf_3_sa_14span_inc(CYTHON_UNUSED PyObject *__pyx_self, Py
  */
     __Pyx_INCREF(__pyx_v_k);
     __pyx_t_1 = __pyx_v_k;
-    __pyx_t_3 = PyObject_GetItem(__pyx_v_vec, __pyx_t_1); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_GetItem(__pyx_v_vec, __pyx_t_1); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2211; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_t_3, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_t_3, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2211; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (PyObject_SetItem(__pyx_v_vec, __pyx_t_1, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyObject_SetItem(__pyx_v_vec, __pyx_t_1, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2211; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2210
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2212
  *     while k <= j:
  *         vec[k] += 1
  *         k += 1             # <<<<<<<<<<<<<<
  * 
  * def span_dec(vec, i, j):
  */
-    __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_k, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_k, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_v_k);
     __pyx_v_k = __pyx_t_1;
@@ -65890,9 +65964,9 @@ static PyObject *__pyx_pf_3_sa_14span_inc(CYTHON_UNUSED PyObject *__pyx_self, Py
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_3_sa_17span_dec(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static PyMethodDef __pyx_mdef_3_sa_17span_dec = {__Pyx_NAMESTR("span_dec"), (PyCFunction)__pyx_pw_3_sa_17span_dec, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};
-static PyObject *__pyx_pw_3_sa_17span_dec(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_3_sa_19span_dec(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_3_sa_19span_dec = {__Pyx_NAMESTR("span_dec"), (PyCFunction)__pyx_pw_3_sa_19span_dec, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};
+static PyObject *__pyx_pw_3_sa_19span_dec(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_vec = 0;
   PyObject *__pyx_v_i = 0;
   PyObject *__pyx_v_j = 0;
@@ -65920,16 +65994,16 @@ static PyObject *__pyx_pw_3_sa_17span_dec(PyObject *__pyx_self, PyObject *__pyx_
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__i)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("span_dec", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2212; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("span_dec", 1, 3, 3, 1); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2214; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__j)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("span_dec", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2212; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("span_dec", 1, 3, 3, 2); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2214; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "span_dec") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2212; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "span_dec") < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2214; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
       goto __pyx_L5_argtuple_error;
@@ -65944,18 +66018,18 @@ static PyObject *__pyx_pw_3_sa_17span_dec(PyObject *__pyx_self, PyObject *__pyx_
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("span_dec", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2212; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("span_dec", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2214; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("_sa.span_dec", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_3_sa_16span_dec(__pyx_self, __pyx_v_vec, __pyx_v_i, __pyx_v_j);
+  __pyx_r = __pyx_pf_3_sa_18span_dec(__pyx_self, __pyx_v_vec, __pyx_v_i, __pyx_v_j);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2212
+/* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2214
  *         k += 1
  * 
  * def span_dec(vec, i, j):             # <<<<<<<<<<<<<<
@@ -65963,7 +66037,7 @@ static PyObject *__pyx_pw_3_sa_17span_dec(PyObject *__pyx_self, PyObject *__pyx_
  *     while k <= j:
  */
 
-static PyObject *__pyx_pf_3_sa_16span_dec(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_vec, PyObject *__pyx_v_i, PyObject *__pyx_v_j) {
+static PyObject *__pyx_pf_3_sa_18span_dec(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_vec, PyObject *__pyx_v_i, PyObject *__pyx_v_j) {
   PyObject *__pyx_v_k = NULL;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
@@ -65976,7 +66050,7 @@ static PyObject *__pyx_pf_3_sa_16span_dec(CYTHON_UNUSED PyObject *__pyx_self, Py
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("span_dec", 0);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2213
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2215
  * 
  * def span_dec(vec, i, j):
  *     k = i             # <<<<<<<<<<<<<<
@@ -65986,7 +66060,7 @@ static PyObject *__pyx_pf_3_sa_16span_dec(CYTHON_UNUSED PyObject *__pyx_self, Py
   __Pyx_INCREF(__pyx_v_i);
   __pyx_v_k = __pyx_v_i;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2214
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2216
  * def span_dec(vec, i, j):
  *     k = i
  *     while k <= j:             # <<<<<<<<<<<<<<
@@ -65994,12 +66068,12 @@ static PyObject *__pyx_pf_3_sa_16span_dec(CYTHON_UNUSED PyObject *__pyx_self, Py
  *         k += 1
  */
   while (1) {
-    __pyx_t_1 = PyObject_RichCompare(__pyx_v_k, __pyx_v_j, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyObject_RichCompare(__pyx_v_k, __pyx_v_j, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2216; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2216; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     if (!__pyx_t_2) break;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2215
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2217
  *     k = i
  *     while k <= j:
  *         vec[k] -= 1             # <<<<<<<<<<<<<<
@@ -66007,21 +66081,21 @@ static PyObject *__pyx_pf_3_sa_16span_dec(CYTHON_UNUSED PyObject *__pyx_self, Py
  */
     __Pyx_INCREF(__pyx_v_k);
     __pyx_t_1 = __pyx_v_k;
-    __pyx_t_3 = PyObject_GetItem(__pyx_v_vec, __pyx_t_1); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = PyObject_GetItem(__pyx_v_vec, __pyx_t_1); if (!__pyx_t_3) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_4 = PyNumber_InPlaceSubtract(__pyx_t_3, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyNumber_InPlaceSubtract(__pyx_t_3, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (PyObject_SetItem(__pyx_v_vec, __pyx_t_1, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (PyObject_SetItem(__pyx_v_vec, __pyx_t_1, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2216
+    /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2218
  *     while k <= j:
  *         vec[k] -= 1
  *         k += 1             # <<<<<<<<<<<<<<
  */
-    __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_k, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2216; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_k, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2218; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_v_k);
     __pyx_v_k = __pyx_t_1;
@@ -79189,7 +79263,9 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s__arr, __pyx_k__arr, sizeof(__pyx_k__arr), 0, 0, 1, 1},
   {&__pyx_n_s__arr_high, __pyx_k__arr_high, sizeof(__pyx_k__arr_high), 0, 0, 1, 1},
   {&__pyx_n_s__arr_low, __pyx_k__arr_low, sizeof(__pyx_k__arr_low), 0, 0, 1, 1},
-  {&__pyx_n_s__bilex, __pyx_k__bilex, sizeof(__pyx_k__bilex), 0, 0, 1, 1},
+  {&__pyx_n_s__bilex_e, __pyx_k__bilex_e, sizeof(__pyx_k__bilex_e), 0, 0, 1, 1},
+  {&__pyx_n_s__bilex_f, __pyx_k__bilex_f, sizeof(__pyx_k__bilex_f), 0, 0, 1, 1},
+  {&__pyx_n_s__bilex_fe, __pyx_k__bilex_fe, sizeof(__pyx_k__bilex_fe), 0, 0, 1, 1},
   {&__pyx_n_s__by_slack_factor, __pyx_k__by_slack_factor, sizeof(__pyx_k__by_slack_factor), 0, 0, 1, 1},
   {&__pyx_n_s__category, __pyx_k__category, sizeof(__pyx_k__category), 0, 0, 1, 1},
   {&__pyx_n_s__chain, __pyx_k__chain, sizeof(__pyx_k__chain), 0, 0, 1, 1},
@@ -79271,6 +79347,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s__input_span, __pyx_k__input_span, sizeof(__pyx_k__input_span), 0, 0, 1, 1},
   {&__pyx_n_s__insert, __pyx_k__insert, sizeof(__pyx_k__insert), 0, 0, 1, 1},
   {&__pyx_n_s__isa, __pyx_k__isa, sizeof(__pyx_k__isa), 0, 0, 1, 1},
+  {&__pyx_n_s__isvar, __pyx_k__isvar, sizeof(__pyx_k__isvar), 0, 0, 1, 1},
   {&__pyx_n_s__iteritems, __pyx_k__iteritems, sizeof(__pyx_k__iteritems), 0, 0, 1, 1},
   {&__pyx_n_s__itertools, __pyx_k__itertools, sizeof(__pyx_k__itertools), 0, 0, 1, 1},
   {&__pyx_n_s__itervalues, __pyx_k__itervalues, sizeof(__pyx_k__itervalues), 0, 0, 1, 1},
@@ -79377,6 +79454,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s__stats, __pyx_k__stats, sizeof(__pyx_k__stats), 0, 0, 1, 1},
   {&__pyx_n_s__stop, __pyx_k__stop, sizeof(__pyx_k__stop), 0, 0, 1, 1},
   {&__pyx_n_s__suffix_link, __pyx_k__suffix_link, sizeof(__pyx_k__suffix_link), 0, 0, 1, 1},
+  {&__pyx_n_s__sym, __pyx_k__sym, sizeof(__pyx_k__sym), 0, 0, 1, 1},
   {&__pyx_n_s__syms, __pyx_k__syms, sizeof(__pyx_k__syms), 0, 0, 1, 1},
   {&__pyx_n_s__test_sentence, __pyx_k__test_sentence, sizeof(__pyx_k__test_sentence), 0, 0, 1, 1},
   {&__pyx_n_s__tight_phrases, __pyx_k__tight_phrases, sizeof(__pyx_k__tight_phrases), 0, 0, 1, 1},
@@ -79414,8 +79492,8 @@ static int __Pyx_InitCachedBuiltins(void) {
   __pyx_builtin_zip = __Pyx_GetName(__pyx_b, __pyx_n_s__zip); if (!__pyx_builtin_zip) {__pyx_filename = __pyx_f[5]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_builtin_StopIteration = __Pyx_GetName(__pyx_b, __pyx_n_s__StopIteration); if (!__pyx_builtin_StopIteration) {__pyx_filename = __pyx_f[6]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_builtin_cmp = __Pyx_GetName(__pyx_b, __pyx_n_s__cmp); if (!__pyx_builtin_cmp) {__pyx_filename = __pyx_f[7]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_builtin_sorted = __Pyx_GetName(__pyx_b, __pyx_n_s__sorted); if (!__pyx_builtin_sorted) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_builtin_max = __Pyx_GetName(__pyx_b, __pyx_n_s__max); if (!__pyx_builtin_max) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_sorted = __Pyx_GetName(__pyx_b, __pyx_n_s__sorted); if (!__pyx_builtin_sorted) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 970; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_max = __Pyx_GetName(__pyx_b, __pyx_n_s__max); if (!__pyx_builtin_max) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   return 0;
   __pyx_L1_error:;
   return -1;
@@ -80135,56 +80213,56 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_GIVEREF(Py_None);
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_98));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":117
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":119
  *             logger.info("Sampling strategy: uniform, max sample size = %d", sample_size)
  *         else:
  *             logger.info("Sampling strategy: no sampling")             # <<<<<<<<<<<<<<
  * 
  *     def sample(self, PhraseLocation phrase_location):
  */
-  __pyx_k_tuple_102 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_102)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_102 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_102)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_102);
   __Pyx_INCREF(((PyObject *)__pyx_kp_s_101));
   PyTuple_SET_ITEM(__pyx_k_tuple_102, 0, ((PyObject *)__pyx_kp_s_101));
   __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_101));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_102));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":336
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":338
  *         self.rules.root = ExtendedTrieNode(phrase_location=PhraseLocation())
  *         if alignment is None:
  *             raise Exception("Must specify an alignment object")             # <<<<<<<<<<<<<<
  *         self.alignment = alignment
  * 
  */
-  __pyx_k_tuple_107 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_107)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 336; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_107 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_107)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 338; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_107);
   __Pyx_INCREF(((PyObject *)__pyx_kp_s_106));
   PyTuple_SET_ITEM(__pyx_k_tuple_107, 0, ((PyObject *)__pyx_kp_s_106));
   __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_106));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_107));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1060
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1062
  *                         else:
  *                             #ERROR: We never get here
  *                             raise Exception("Keyword trie error")             # <<<<<<<<<<<<<<
  *                 # checking whether lookup_required
  *                 if lookup_required:
  */
-  __pyx_k_tuple_122 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_122)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1060; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_122 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_122)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1062; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_122);
   __Pyx_INCREF(((PyObject *)__pyx_kp_s_121));
   PyTuple_SET_ITEM(__pyx_k_tuple_122, 0, ((PyObject *)__pyx_kp_s_121));
   __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_121));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_122));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1911
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":1913
  *         # f_ i and j are current, e_ i and j are previous
  *         # We care _considering_ f_j, so it is not yet in counts
  *         def extract(f_i, f_j, e_i, e_j, min_bound, wc, links, nt, nt_open):             # <<<<<<<<<<<<<<
  *             # Phrase extraction limits
  *             if f_j > (f_len - 1) or (f_j - f_i) + 1 > self.max_initial_size:
  */
-  __pyx_k_tuple_134 = PyTuple_New(19); if (unlikely(!__pyx_k_tuple_134)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_134 = PyTuple_New(19); if (unlikely(!__pyx_k_tuple_134)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_134);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__f_i));
   PyTuple_SET_ITEM(__pyx_k_tuple_134, 0, ((PyObject *)__pyx_n_s__f_i));
@@ -80244,142 +80322,142 @@ static int __Pyx_InitCachedConstants(void) {
   PyTuple_SET_ITEM(__pyx_k_tuple_134, 18, ((PyObject *)__pyx_n_s__old_last_nt));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__old_last_nt));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_134));
-  __pyx_k_codeobj_135 = (PyObject*)__Pyx_PyCode_New(9, 0, 19, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_134, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_136, __pyx_n_s__extract, 1911, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_135)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_codeobj_135 = (PyObject*)__Pyx_PyCode_New(9, 0, 19, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_134, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_136, __pyx_n_s__extract, 1913, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_135)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2118
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2120
  *     # Debugging
  *     def dump_online_stats(self):
  *         logger.info('------------------------------')             # <<<<<<<<<<<<<<
  *         logger.info('         Online Stats         ')
  *         logger.info('------------------------------')
  */
-  __pyx_k_tuple_140 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_140)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_140 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_140)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_140);
   __Pyx_INCREF(((PyObject *)__pyx_kp_s_139));
   PyTuple_SET_ITEM(__pyx_k_tuple_140, 0, ((PyObject *)__pyx_kp_s_139));
   __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_139));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_140));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2119
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2121
  *     def dump_online_stats(self):
  *         logger.info('------------------------------')
  *         logger.info('         Online Stats         ')             # <<<<<<<<<<<<<<
  *         logger.info('------------------------------')
  *         logger.info('f')
  */
-  __pyx_k_tuple_142 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_142)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_142 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_142)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_142);
   __Pyx_INCREF(((PyObject *)__pyx_kp_s_141));
   PyTuple_SET_ITEM(__pyx_k_tuple_142, 0, ((PyObject *)__pyx_kp_s_141));
   __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_141));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_142));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2120
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2122
  *         logger.info('------------------------------')
  *         logger.info('         Online Stats         ')
  *         logger.info('------------------------------')             # <<<<<<<<<<<<<<
  *         logger.info('f')
  *         for w in self.bilex_f:
  */
-  __pyx_k_tuple_143 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_143)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_143 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_143)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_143);
   __Pyx_INCREF(((PyObject *)__pyx_kp_s_139));
   PyTuple_SET_ITEM(__pyx_k_tuple_143, 0, ((PyObject *)__pyx_kp_s_139));
   __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_139));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_143));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2121
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2123
  *         logger.info('         Online Stats         ')
  *         logger.info('------------------------------')
  *         logger.info('f')             # <<<<<<<<<<<<<<
  *         for w in self.bilex_f:
  *             logger.info(sym_tostring(w) + ' : ' + str(self.bilex_f[w]))
  */
-  __pyx_k_tuple_144 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_144)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_144 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_144)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_144);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__f));
   PyTuple_SET_ITEM(__pyx_k_tuple_144, 0, ((PyObject *)__pyx_n_s__f));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__f));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_144));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2124
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2126
  *         for w in self.bilex_f:
  *             logger.info(sym_tostring(w) + ' : ' + str(self.bilex_f[w]))
  *         logger.info('e')             # <<<<<<<<<<<<<<
  *         for w in self.bilex_e:
  *             logger.info(sym_tostring(w) + ' : ' + str(self.bilex_e[w]))
  */
-  __pyx_k_tuple_146 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_146)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_146 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_146)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_146);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__e));
   PyTuple_SET_ITEM(__pyx_k_tuple_146, 0, ((PyObject *)__pyx_n_s__e));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__e));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_146));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2127
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2129
  *         for w in self.bilex_e:
  *             logger.info(sym_tostring(w) + ' : ' + str(self.bilex_e[w]))
  *         logger.info('fe')             # <<<<<<<<<<<<<<
  *         for w in self.bilex_fe:
  *             for w2 in self.bilex_fe[w]:
  */
-  __pyx_k_tuple_147 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_147)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_147 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_147)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_147);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__fe));
   PyTuple_SET_ITEM(__pyx_k_tuple_147, 0, ((PyObject *)__pyx_n_s__fe));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__fe));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_147));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2131
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2133
  *             for w2 in self.bilex_fe[w]:
  *                 logger.info(sym_tostring(w) + ' : ' + sym_tostring(w2) + ' : ' + str(self.bilex_fe[w][w2]))
  *         logger.info('F')             # <<<<<<<<<<<<<<
  *         for ph in self.phrases_f:
  *             logger.info(str(ph) + ' ||| ' + str(self.phrases_f[ph]))
  */
-  __pyx_k_tuple_148 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_148)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_148 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_148)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_148);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__F));
   PyTuple_SET_ITEM(__pyx_k_tuple_148, 0, ((PyObject *)__pyx_n_s__F));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__F));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_148));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2134
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2136
  *         for ph in self.phrases_f:
  *             logger.info(str(ph) + ' ||| ' + str(self.phrases_f[ph]))
  *         logger.info('E')             # <<<<<<<<<<<<<<
  *         for ph in self.phrases_e:
  *             logger.info(str(ph) + ' ||| ' + str(self.phrases_e[ph]))
  */
-  __pyx_k_tuple_149 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_149)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_149 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_149)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_149);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__E));
   PyTuple_SET_ITEM(__pyx_k_tuple_149, 0, ((PyObject *)__pyx_n_s__E));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__E));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_149));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2137
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2139
  *         for ph in self.phrases_e:
  *             logger.info(str(ph) + ' ||| ' + str(self.phrases_e[ph]))
  *         logger.info('FE')             # <<<<<<<<<<<<<<
  *         self.dump_online_rules()
  * 
  */
-  __pyx_k_tuple_150 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_150)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_150 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_150)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_150);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__FE));
   PyTuple_SET_ITEM(__pyx_k_tuple_150, 0, ((PyObject *)__pyx_n_s__FE));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__FE));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_150));
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2164
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2166
  *         phrases = set() # (fphrase, lex_i, lex_j)
  * 
  *         def extract(f_i, f_j, lex_i, lex_j, wc, ntc, syms):             # <<<<<<<<<<<<<<
  *             # Phrase extraction limits
  *             if f_j > (f_len - 1) or (f_j - f_i) + 1 > self.max_initial_size:
  */
-  __pyx_k_tuple_152 = PyTuple_New(10); if (unlikely(!__pyx_k_tuple_152)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_152 = PyTuple_New(10); if (unlikely(!__pyx_k_tuple_152)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_152);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__f_i));
   PyTuple_SET_ITEM(__pyx_k_tuple_152, 0, ((PyObject *)__pyx_n_s__f_i));
@@ -80412,7 +80490,7 @@ static int __Pyx_InitCachedConstants(void) {
   PyTuple_SET_ITEM(__pyx_k_tuple_152, 9, ((PyObject *)__pyx_n_s__new_lex_j));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__new_lex_j));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_152));
-  __pyx_k_codeobj_153 = (PyObject*)__Pyx_PyCode_New(7, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_152, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_136, __pyx_n_s__extract, 2164, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_153)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_codeobj_153 = (PyObject*)__Pyx_PyCode_New(7, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_152, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_136, __pyx_n_s__extract, 2166, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_153)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
   /* "_sa.pyx":9
  *             resource.getrusage(resource.RUSAGE_SELF).ru_stime)
@@ -80449,184 +80527,199 @@ static int __Pyx_InitCachedConstants(void) {
   /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":107
  *     return ALPHABET.fromstring(string, terminal)
  * 
+ * def isvar(sym):             # <<<<<<<<<<<<<<
+ *     return sym_isvar(sym)
+ * 
+ */
+  __pyx_k_tuple_160 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_160)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_160);
+  __Pyx_INCREF(((PyObject *)__pyx_n_s__sym));
+  PyTuple_SET_ITEM(__pyx_k_tuple_160, 0, ((PyObject *)__pyx_n_s__sym));
+  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__sym));
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_160));
+  __pyx_k_codeobj_161 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_160, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_162, __pyx_n_s__isvar, 107, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_161)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":110
+ *     return sym_isvar(sym)
+ * 
  * def make_lattice(words):             # <<<<<<<<<<<<<<
  *     word_ids = (sym_fromstring(word, True) for word in words)
  *     return tuple(((word, None, 1), ) for word in word_ids)
  */
-  __pyx_k_tuple_160 = PyTuple_New(5); if (unlikely(!__pyx_k_tuple_160)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_160);
+  __pyx_k_tuple_163 = PyTuple_New(5); if (unlikely(!__pyx_k_tuple_163)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_163);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__words));
-  PyTuple_SET_ITEM(__pyx_k_tuple_160, 0, ((PyObject *)__pyx_n_s__words));
+  PyTuple_SET_ITEM(__pyx_k_tuple_163, 0, ((PyObject *)__pyx_n_s__words));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__words));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__word_ids));
-  PyTuple_SET_ITEM(__pyx_k_tuple_160, 1, ((PyObject *)__pyx_n_s__word_ids));
+  PyTuple_SET_ITEM(__pyx_k_tuple_163, 1, ((PyObject *)__pyx_n_s__word_ids));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__word_ids));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__genexpr));
-  PyTuple_SET_ITEM(__pyx_k_tuple_160, 2, ((PyObject *)__pyx_n_s__genexpr));
+  PyTuple_SET_ITEM(__pyx_k_tuple_163, 2, ((PyObject *)__pyx_n_s__genexpr));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__genexpr));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__genexpr));
-  PyTuple_SET_ITEM(__pyx_k_tuple_160, 3, ((PyObject *)__pyx_n_s__genexpr));
+  PyTuple_SET_ITEM(__pyx_k_tuple_163, 3, ((PyObject *)__pyx_n_s__genexpr));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__genexpr));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__genexpr));
-  PyTuple_SET_ITEM(__pyx_k_tuple_160, 4, ((PyObject *)__pyx_n_s__genexpr));
+  PyTuple_SET_ITEM(__pyx_k_tuple_163, 4, ((PyObject *)__pyx_n_s__genexpr));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__genexpr));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_160));
-  __pyx_k_codeobj_161 = (PyObject*)__Pyx_PyCode_New(1, 0, 5, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_160, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_162, __pyx_n_s__make_lattice, 107, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_161)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_163));
+  __pyx_k_codeobj_164 = (PyObject*)__Pyx_PyCode_New(1, 0, 5, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_163, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_162, __pyx_n_s__make_lattice, 110, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_164)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":111
+  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":114
  *     return tuple(((word, None, 1), ) for word in word_ids)
  * 
  * def decode_lattice(lattice):             # <<<<<<<<<<<<<<
  *     return tuple((sym_tostring(sym), weight, dist) for (sym, weight, dist) in arc
  *             for arc in node for node in lattice)
  */
-  __pyx_k_tuple_163 = PyTuple_New(3); if (unlikely(!__pyx_k_tuple_163)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_163);
+  __pyx_k_tuple_165 = PyTuple_New(3); if (unlikely(!__pyx_k_tuple_165)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_165);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__lattice));
-  PyTuple_SET_ITEM(__pyx_k_tuple_163, 0, ((PyObject *)__pyx_n_s__lattice));
+  PyTuple_SET_ITEM(__pyx_k_tuple_165, 0, ((PyObject *)__pyx_n_s__lattice));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__lattice));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__genexpr));
-  PyTuple_SET_ITEM(__pyx_k_tuple_163, 1, ((PyObject *)__pyx_n_s__genexpr));
+  PyTuple_SET_ITEM(__pyx_k_tuple_165, 1, ((PyObject *)__pyx_n_s__genexpr));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__genexpr));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__genexpr));
-  PyTuple_SET_ITEM(__pyx_k_tuple_163, 2, ((PyObject *)__pyx_n_s__genexpr));
+  PyTuple_SET_ITEM(__pyx_k_tuple_165, 2, ((PyObject *)__pyx_n_s__genexpr));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__genexpr));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_163));
-  __pyx_k_codeobj_164 = (PyObject*)__Pyx_PyCode_New(1, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_163, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_162, __pyx_n_s__decode_lattice, 111, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_164)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_165));
+  __pyx_k_codeobj_166 = (PyObject*)__Pyx_PyCode_New(1, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_165, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_162, __pyx_n_s__decode_lattice, 114, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_166)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":115
+  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":118
  *             for arc in node for node in lattice)
  * 
  * def decode_sentence(lattice):             # <<<<<<<<<<<<<<
  *     return tuple(sym_tostring(sym) for ((sym, _, _),) in lattice)
  * 
  */
-  __pyx_k_tuple_165 = PyTuple_New(3); if (unlikely(!__pyx_k_tuple_165)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_165);
+  __pyx_k_tuple_167 = PyTuple_New(3); if (unlikely(!__pyx_k_tuple_167)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_167);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__lattice));
-  PyTuple_SET_ITEM(__pyx_k_tuple_165, 0, ((PyObject *)__pyx_n_s__lattice));
+  PyTuple_SET_ITEM(__pyx_k_tuple_167, 0, ((PyObject *)__pyx_n_s__lattice));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__lattice));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__genexpr));
-  PyTuple_SET_ITEM(__pyx_k_tuple_165, 1, ((PyObject *)__pyx_n_s__genexpr));
+  PyTuple_SET_ITEM(__pyx_k_tuple_167, 1, ((PyObject *)__pyx_n_s__genexpr));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__genexpr));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__genexpr));
-  PyTuple_SET_ITEM(__pyx_k_tuple_165, 2, ((PyObject *)__pyx_n_s__genexpr));
+  PyTuple_SET_ITEM(__pyx_k_tuple_167, 2, ((PyObject *)__pyx_n_s__genexpr));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__genexpr));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_165));
-  __pyx_k_codeobj_166 = (PyObject*)__Pyx_PyCode_New(1, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_165, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_162, __pyx_n_s__decode_sentence, 115, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_166)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_167));
+  __pyx_k_codeobj_168 = (PyObject*)__Pyx_PyCode_New(1, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_167, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_162, __pyx_n_s__decode_sentence, 118, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_168)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":118
+  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":121
  *     return tuple(sym_tostring(sym) for ((sym, _, _),) in lattice)
  * 
  * def encode_words(words):             # <<<<<<<<<<<<<<
  *     return tuple(sym_fromstring(word, True) for word in words)
  * 
  */
-  __pyx_k_tuple_167 = PyTuple_New(3); if (unlikely(!__pyx_k_tuple_167)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_167);
+  __pyx_k_tuple_169 = PyTuple_New(3); if (unlikely(!__pyx_k_tuple_169)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_169);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__words));
-  PyTuple_SET_ITEM(__pyx_k_tuple_167, 0, ((PyObject *)__pyx_n_s__words));
+  PyTuple_SET_ITEM(__pyx_k_tuple_169, 0, ((PyObject *)__pyx_n_s__words));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__words));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__genexpr));
-  PyTuple_SET_ITEM(__pyx_k_tuple_167, 1, ((PyObject *)__pyx_n_s__genexpr));
+  PyTuple_SET_ITEM(__pyx_k_tuple_169, 1, ((PyObject *)__pyx_n_s__genexpr));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__genexpr));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__genexpr));
-  PyTuple_SET_ITEM(__pyx_k_tuple_167, 2, ((PyObject *)__pyx_n_s__genexpr));
+  PyTuple_SET_ITEM(__pyx_k_tuple_169, 2, ((PyObject *)__pyx_n_s__genexpr));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__genexpr));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_167));
-  __pyx_k_codeobj_168 = (PyObject*)__Pyx_PyCode_New(1, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_167, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_162, __pyx_n_s__encode_words, 118, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_168)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_169));
+  __pyx_k_codeobj_170 = (PyObject*)__Pyx_PyCode_New(1, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_169, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_162, __pyx_n_s__encode_words, 121, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_170)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":121
+  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":124
  *     return tuple(sym_fromstring(word, True) for word in words)
  * 
  * def decode_words(syms):             # <<<<<<<<<<<<<<
  *     return tuple(sym_tostring(sym) for sym in syms)
  */
-  __pyx_k_tuple_169 = PyTuple_New(3); if (unlikely(!__pyx_k_tuple_169)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_169);
+  __pyx_k_tuple_171 = PyTuple_New(3); if (unlikely(!__pyx_k_tuple_171)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_171);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__syms));
-  PyTuple_SET_ITEM(__pyx_k_tuple_169, 0, ((PyObject *)__pyx_n_s__syms));
+  PyTuple_SET_ITEM(__pyx_k_tuple_171, 0, ((PyObject *)__pyx_n_s__syms));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__syms));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__genexpr));
-  PyTuple_SET_ITEM(__pyx_k_tuple_169, 1, ((PyObject *)__pyx_n_s__genexpr));
+  PyTuple_SET_ITEM(__pyx_k_tuple_171, 1, ((PyObject *)__pyx_n_s__genexpr));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__genexpr));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__genexpr));
-  PyTuple_SET_ITEM(__pyx_k_tuple_169, 2, ((PyObject *)__pyx_n_s__genexpr));
+  PyTuple_SET_ITEM(__pyx_k_tuple_171, 2, ((PyObject *)__pyx_n_s__genexpr));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__genexpr));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_169));
-  __pyx_k_codeobj_170 = (PyObject*)__Pyx_PyCode_New(1, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_169, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_162, __pyx_n_s__decode_words, 121, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_170)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_171));
+  __pyx_k_codeobj_172 = (PyObject*)__Pyx_PyCode_New(1, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_171, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_162, __pyx_n_s__decode_words, 124, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_172)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2198
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2200
  * 
  * # Spans are _inclusive_ on both ends [i, j]
  * def span_check(vec, i, j):             # <<<<<<<<<<<<<<
  *     k = i
  *     while k <= j:
  */
-  __pyx_k_tuple_172 = PyTuple_New(4); if (unlikely(!__pyx_k_tuple_172)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2198; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_172);
+  __pyx_k_tuple_174 = PyTuple_New(4); if (unlikely(!__pyx_k_tuple_174)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_174);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__vec));
-  PyTuple_SET_ITEM(__pyx_k_tuple_172, 0, ((PyObject *)__pyx_n_s__vec));
+  PyTuple_SET_ITEM(__pyx_k_tuple_174, 0, ((PyObject *)__pyx_n_s__vec));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__vec));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__i));
-  PyTuple_SET_ITEM(__pyx_k_tuple_172, 1, ((PyObject *)__pyx_n_s__i));
+  PyTuple_SET_ITEM(__pyx_k_tuple_174, 1, ((PyObject *)__pyx_n_s__i));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__i));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__j));
-  PyTuple_SET_ITEM(__pyx_k_tuple_172, 2, ((PyObject *)__pyx_n_s__j));
+  PyTuple_SET_ITEM(__pyx_k_tuple_174, 2, ((PyObject *)__pyx_n_s__j));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__j));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__k));
-  PyTuple_SET_ITEM(__pyx_k_tuple_172, 3, ((PyObject *)__pyx_n_s__k));
+  PyTuple_SET_ITEM(__pyx_k_tuple_174, 3, ((PyObject *)__pyx_n_s__k));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__k));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_172));
-  __pyx_k_codeobj_173 = (PyObject*)__Pyx_PyCode_New(3, 0, 4, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_172, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_136, __pyx_n_s__span_check, 2198, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_173)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2198; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_174));
+  __pyx_k_codeobj_175 = (PyObject*)__Pyx_PyCode_New(3, 0, 4, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_174, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_136, __pyx_n_s__span_check, 2200, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_175)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2206
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2208
  *     return True
  * 
  * def span_inc(vec, i, j):             # <<<<<<<<<<<<<<
  *     k = i
  *     while k <= j:
  */
-  __pyx_k_tuple_174 = PyTuple_New(4); if (unlikely(!__pyx_k_tuple_174)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2206; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_174);
+  __pyx_k_tuple_176 = PyTuple_New(4); if (unlikely(!__pyx_k_tuple_176)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_176);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__vec));
-  PyTuple_SET_ITEM(__pyx_k_tuple_174, 0, ((PyObject *)__pyx_n_s__vec));
+  PyTuple_SET_ITEM(__pyx_k_tuple_176, 0, ((PyObject *)__pyx_n_s__vec));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__vec));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__i));
-  PyTuple_SET_ITEM(__pyx_k_tuple_174, 1, ((PyObject *)__pyx_n_s__i));
+  PyTuple_SET_ITEM(__pyx_k_tuple_176, 1, ((PyObject *)__pyx_n_s__i));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__i));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__j));
-  PyTuple_SET_ITEM(__pyx_k_tuple_174, 2, ((PyObject *)__pyx_n_s__j));
+  PyTuple_SET_ITEM(__pyx_k_tuple_176, 2, ((PyObject *)__pyx_n_s__j));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__j));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__k));
-  PyTuple_SET_ITEM(__pyx_k_tuple_174, 3, ((PyObject *)__pyx_n_s__k));
+  PyTuple_SET_ITEM(__pyx_k_tuple_176, 3, ((PyObject *)__pyx_n_s__k));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__k));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_174));
-  __pyx_k_codeobj_175 = (PyObject*)__Pyx_PyCode_New(3, 0, 4, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_174, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_136, __pyx_n_s__span_inc, 2206, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_175)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2206; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_176));
+  __pyx_k_codeobj_177 = (PyObject*)__Pyx_PyCode_New(3, 0, 4, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_176, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_136, __pyx_n_s__span_inc, 2208, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_177)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2212
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2214
  *         k += 1
  * 
  * def span_dec(vec, i, j):             # <<<<<<<<<<<<<<
  *     k = i
  *     while k <= j:
  */
-  __pyx_k_tuple_176 = PyTuple_New(4); if (unlikely(!__pyx_k_tuple_176)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_176);
+  __pyx_k_tuple_178 = PyTuple_New(4); if (unlikely(!__pyx_k_tuple_178)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_k_tuple_178);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__vec));
-  PyTuple_SET_ITEM(__pyx_k_tuple_176, 0, ((PyObject *)__pyx_n_s__vec));
+  PyTuple_SET_ITEM(__pyx_k_tuple_178, 0, ((PyObject *)__pyx_n_s__vec));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__vec));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__i));
-  PyTuple_SET_ITEM(__pyx_k_tuple_176, 1, ((PyObject *)__pyx_n_s__i));
+  PyTuple_SET_ITEM(__pyx_k_tuple_178, 1, ((PyObject *)__pyx_n_s__i));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__i));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__j));
-  PyTuple_SET_ITEM(__pyx_k_tuple_176, 2, ((PyObject *)__pyx_n_s__j));
+  PyTuple_SET_ITEM(__pyx_k_tuple_178, 2, ((PyObject *)__pyx_n_s__j));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__j));
   __Pyx_INCREF(((PyObject *)__pyx_n_s__k));
-  PyTuple_SET_ITEM(__pyx_k_tuple_176, 3, ((PyObject *)__pyx_n_s__k));
+  PyTuple_SET_ITEM(__pyx_k_tuple_178, 3, ((PyObject *)__pyx_n_s__k));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__k));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_176));
-  __pyx_k_codeobj_177 = (PyObject*)__Pyx_PyCode_New(3, 0, 4, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_176, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_136, __pyx_n_s__span_dec, 2212, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_177)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_178));
+  __pyx_k_codeobj_179 = (PyObject*)__Pyx_PyCode_New(3, 0, 4, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_178, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_136, __pyx_n_s__span_dec, 2214, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_179)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_RefNannyFinishContext();
   return 0;
   __pyx_L1_error:;
@@ -80847,24 +80940,24 @@ PyMODINIT_FUNC PyInit__sa(void)
   if (__Pyx_SetVtable(__pyx_type_3_sa_SuffixArray.tp_dict, __pyx_vtabptr_3_sa_SuffixArray) < 0) {__pyx_filename = __pyx_f[12]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   if (__Pyx_SetAttrString(__pyx_m, "SuffixArray", (PyObject *)&__pyx_type_3_sa_SuffixArray) < 0) {__pyx_filename = __pyx_f[12]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa_SuffixArray = &__pyx_type_3_sa_SuffixArray;
-  if (PyType_Ready(&__pyx_type_3_sa_TrieNode) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (__Pyx_SetAttrString(__pyx_m, "TrieNode", (PyObject *)&__pyx_type_3_sa_TrieNode) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa_TrieNode) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "TrieNode", (PyObject *)&__pyx_type_3_sa_TrieNode) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa_TrieNode = &__pyx_type_3_sa_TrieNode;
   __pyx_type_3_sa_ExtendedTrieNode.tp_base = __pyx_ptype_3_sa_TrieNode;
-  if (PyType_Ready(&__pyx_type_3_sa_ExtendedTrieNode) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (__Pyx_SetAttrString(__pyx_m, "ExtendedTrieNode", (PyObject *)&__pyx_type_3_sa_ExtendedTrieNode) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa_ExtendedTrieNode) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "ExtendedTrieNode", (PyObject *)&__pyx_type_3_sa_ExtendedTrieNode) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa_ExtendedTrieNode = &__pyx_type_3_sa_ExtendedTrieNode;
-  if (PyType_Ready(&__pyx_type_3_sa_TrieTable) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (__Pyx_SetAttrString(__pyx_m, "TrieTable", (PyObject *)&__pyx_type_3_sa_TrieTable) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa_TrieTable) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "TrieTable", (PyObject *)&__pyx_type_3_sa_TrieTable) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa_TrieTable = &__pyx_type_3_sa_TrieTable;
   __pyx_vtabptr_3_sa_PhraseLocation = &__pyx_vtable_3_sa_PhraseLocation;
   __pyx_vtable_3_sa_PhraseLocation.contains = (int (*)(struct __pyx_obj_3_sa_PhraseLocation *, int))__pyx_f_3_sa_14PhraseLocation_contains;
-  if (PyType_Ready(&__pyx_type_3_sa_PhraseLocation) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (__Pyx_SetVtable(__pyx_type_3_sa_PhraseLocation.tp_dict, __pyx_vtabptr_3_sa_PhraseLocation) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (__Pyx_SetAttrString(__pyx_m, "PhraseLocation", (PyObject *)&__pyx_type_3_sa_PhraseLocation) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa_PhraseLocation) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetVtable(__pyx_type_3_sa_PhraseLocation.tp_dict, __pyx_vtabptr_3_sa_PhraseLocation) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "PhraseLocation", (PyObject *)&__pyx_type_3_sa_PhraseLocation) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa_PhraseLocation = &__pyx_type_3_sa_PhraseLocation;
-  if (PyType_Ready(&__pyx_type_3_sa_Sampler) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (__Pyx_SetAttrString(__pyx_m, "Sampler", (PyObject *)&__pyx_type_3_sa_Sampler) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa_Sampler) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "Sampler", (PyObject *)&__pyx_type_3_sa_Sampler) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa_Sampler = &__pyx_type_3_sa_Sampler;
   __pyx_vtabptr_3_sa_HieroCachingRuleFactory = &__pyx_vtable_3_sa_HieroCachingRuleFactory;
   __pyx_vtable_3_sa_HieroCachingRuleFactory.set_idmap = (PyObject *(*)(struct __pyx_obj_3_sa_HieroCachingRuleFactory *, struct __pyx_obj_3_sa_DataArray *))__pyx_f_3_sa_23HieroCachingRuleFactory_set_idmap;
@@ -80882,9 +80975,9 @@ PyMODINIT_FUNC PyInit__sa(void)
   __pyx_vtable_3_sa_HieroCachingRuleFactory.extract_phrases = (PyObject *(*)(struct __pyx_obj_3_sa_HieroCachingRuleFactory *, int, int, int *, int *, int *, int, int, int, int *, int *, int *, int, int, int))__pyx_f_3_sa_23HieroCachingRuleFactory_extract_phrases;
   __pyx_vtable_3_sa_HieroCachingRuleFactory.create_alignments = (struct __pyx_obj_3_sa_IntList *(*)(struct __pyx_obj_3_sa_HieroCachingRuleFactory *, int *, int, PyObject *, PyObject *))__pyx_f_3_sa_23HieroCachingRuleFactory_create_alignments;
   __pyx_vtable_3_sa_HieroCachingRuleFactory.extract = (PyObject *(*)(struct __pyx_obj_3_sa_HieroCachingRuleFactory *, struct __pyx_obj_3_sa_Phrase *, struct __pyx_t_3_sa_Matching *, int *, int))__pyx_f_3_sa_23HieroCachingRuleFactory_extract;
-  if (PyType_Ready(&__pyx_type_3_sa_HieroCachingRuleFactory) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (__Pyx_SetVtable(__pyx_type_3_sa_HieroCachingRuleFactory.tp_dict, __pyx_vtabptr_3_sa_HieroCachingRuleFactory) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (__Pyx_SetAttrString(__pyx_m, "HieroCachingRuleFactory", (PyObject *)&__pyx_type_3_sa_HieroCachingRuleFactory) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa_HieroCachingRuleFactory) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 228; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetVtable(__pyx_type_3_sa_HieroCachingRuleFactory.tp_dict, __pyx_vtabptr_3_sa_HieroCachingRuleFactory) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 228; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (__Pyx_SetAttrString(__pyx_m, "HieroCachingRuleFactory", (PyObject *)&__pyx_type_3_sa_HieroCachingRuleFactory) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 228; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa_HieroCachingRuleFactory = &__pyx_type_3_sa_HieroCachingRuleFactory;
   __pyx_vtabptr_3_sa_Scorer = &__pyx_vtable_3_sa_Scorer;
   __pyx_vtable_3_sa_Scorer.score = (struct __pyx_obj_3_sa_FeatureVector *(*)(struct __pyx_obj_3_sa_Scorer *, PyObject *))__pyx_f_3_sa_6Scorer_score;
@@ -80900,27 +80993,27 @@ PyMODINIT_FUNC PyInit__sa(void)
   __pyx_ptype_3_sa___pyx_scope_struct_2_genexpr = &__pyx_type_3_sa___pyx_scope_struct_2_genexpr;
   if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_3_compute_stats) < 0) {__pyx_filename = __pyx_f[9]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_3_compute_stats = &__pyx_type_3_sa___pyx_scope_struct_3_compute_stats;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_4_make_lattice) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_4_make_lattice) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_4_make_lattice = &__pyx_type_3_sa___pyx_scope_struct_4_make_lattice;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_5_genexpr) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_5_genexpr) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_5_genexpr = &__pyx_type_3_sa___pyx_scope_struct_5_genexpr;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_6_genexpr) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_6_genexpr) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_6_genexpr = &__pyx_type_3_sa___pyx_scope_struct_6_genexpr;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_7_decode_lattice) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_7_decode_lattice) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_7_decode_lattice = &__pyx_type_3_sa___pyx_scope_struct_7_decode_lattice;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_8_genexpr) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_8_genexpr) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_8_genexpr = &__pyx_type_3_sa___pyx_scope_struct_8_genexpr;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_9_decode_sentence) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_9_decode_sentence) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_9_decode_sentence = &__pyx_type_3_sa___pyx_scope_struct_9_decode_sentence;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_10_genexpr) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_10_genexpr) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_10_genexpr = &__pyx_type_3_sa___pyx_scope_struct_10_genexpr;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_11_encode_words) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_11_encode_words) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_11_encode_words = &__pyx_type_3_sa___pyx_scope_struct_11_encode_words;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_12_genexpr) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_12_genexpr) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_12_genexpr = &__pyx_type_3_sa___pyx_scope_struct_12_genexpr;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_13_decode_words) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_13_decode_words) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_13_decode_words = &__pyx_type_3_sa___pyx_scope_struct_13_decode_words;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_14_genexpr) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_14_genexpr) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_14_genexpr = &__pyx_type_3_sa___pyx_scope_struct_14_genexpr;
   if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_15___iter__) < 0) {__pyx_filename = __pyx_f[7]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_15___iter__ = &__pyx_type_3_sa___pyx_scope_struct_15___iter__;
@@ -80930,21 +81023,21 @@ PyMODINIT_FUNC PyInit__sa(void)
   __pyx_ptype_3_sa___pyx_scope_struct_17_genexpr = &__pyx_type_3_sa___pyx_scope_struct_17_genexpr;
   if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_18_alignments) < 0) {__pyx_filename = __pyx_f[7]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_18_alignments = &__pyx_type_3_sa___pyx_scope_struct_18_alignments;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_19_input) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 970; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_19_input) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_19_input = &__pyx_type_3_sa___pyx_scope_struct_19_input;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_20_genexpr) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_20_genexpr) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_20_genexpr = &__pyx_type_3_sa___pyx_scope_struct_20_genexpr;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_21_add_instance) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1877; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_21_add_instance) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 1879; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_21_add_instance = &__pyx_type_3_sa___pyx_scope_struct_21_add_instance;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_22_form_rule) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2047; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_22_form_rule) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2049; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_22_form_rule = &__pyx_type_3_sa___pyx_scope_struct_22_form_rule;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_23_genexpr) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_23_genexpr) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_23_genexpr = &__pyx_type_3_sa___pyx_scope_struct_23_genexpr;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_24_fmt_rule) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_24_fmt_rule) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_24_fmt_rule = &__pyx_type_3_sa___pyx_scope_struct_24_fmt_rule;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_25_genexpr) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_25_genexpr) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_25_genexpr = &__pyx_type_3_sa___pyx_scope_struct_25_genexpr;
-  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_26_get_f_phrases) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_26_get_f_phrases) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_26_get_f_phrases = &__pyx_type_3_sa___pyx_scope_struct_26_get_f_phrases;
   if (PyType_Ready(&__pyx_type_3_sa___pyx_scope_struct_27___iter__) < 0) {__pyx_filename = __pyx_f[13]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_ptype_3_sa___pyx_scope_struct_27___iter__ = &__pyx_type_3_sa___pyx_scope_struct_27___iter__;
@@ -81096,60 +81189,72 @@ PyMODINIT_FUNC PyInit__sa(void)
   /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":107
  *     return ALPHABET.fromstring(string, terminal)
  * 
+ * def isvar(sym):             # <<<<<<<<<<<<<<
+ *     return sym_isvar(sym)
+ * 
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_3_sa_3isvar, NULL, __pyx_n_s___sa); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__isvar, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":110
+ *     return sym_isvar(sym)
+ * 
  * def make_lattice(words):             # <<<<<<<<<<<<<<
  *     word_ids = (sym_fromstring(word, True) for word in words)
  *     return tuple(((word, None, 1), ) for word in word_ids)
  */
-  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_3_sa_3make_lattice, NULL, __pyx_n_s___sa); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_3_sa_5make_lattice, NULL, __pyx_n_s___sa); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__make_lattice, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__make_lattice, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":111
+  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":114
  *     return tuple(((word, None, 1), ) for word in word_ids)
  * 
  * def decode_lattice(lattice):             # <<<<<<<<<<<<<<
  *     return tuple((sym_tostring(sym), weight, dist) for (sym, weight, dist) in arc
  *             for arc in node for node in lattice)
  */
-  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_3_sa_5decode_lattice, NULL, __pyx_n_s___sa); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_3_sa_7decode_lattice, NULL, __pyx_n_s___sa); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__decode_lattice, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__decode_lattice, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":115
+  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":118
  *             for arc in node for node in lattice)
  * 
  * def decode_sentence(lattice):             # <<<<<<<<<<<<<<
  *     return tuple(sym_tostring(sym) for ((sym, _, _),) in lattice)
  * 
  */
-  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_3_sa_7decode_sentence, NULL, __pyx_n_s___sa); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_3_sa_9decode_sentence, NULL, __pyx_n_s___sa); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__decode_sentence, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__decode_sentence, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":118
+  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":121
  *     return tuple(sym_tostring(sym) for ((sym, _, _),) in lattice)
  * 
  * def encode_words(words):             # <<<<<<<<<<<<<<
  *     return tuple(sym_fromstring(word, True) for word in words)
  * 
  */
-  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_3_sa_9encode_words, NULL, __pyx_n_s___sa); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_3_sa_11encode_words, NULL, __pyx_n_s___sa); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__encode_words, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__encode_words, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":121
+  /* "/home/m/workspace/cdec/python/src/sa/sym.pxi":124
  *     return tuple(sym_fromstring(word, True) for word in words)
  * 
  * def decode_words(syms):             # <<<<<<<<<<<<<<
  *     return tuple(sym_tostring(sym) for sym in syms)
  */
-  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_3_sa_11decode_words, NULL, __pyx_n_s___sa); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_3_sa_13decode_words, NULL, __pyx_n_s___sa); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__decode_words, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__decode_words, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[10]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
   /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":5
@@ -81313,7 +81418,7 @@ PyMODINIT_FUNC PyInit__sa(void)
  *      'fsample_count',
  *      'paircount',
  */
-  __pyx_t_3 = PyList_New(4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyList_New(6); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_INCREF(((PyObject *)__pyx_n_s__fcount));
   PyList_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_n_s__fcount));
@@ -81324,9 +81429,15 @@ PyMODINIT_FUNC PyInit__sa(void)
   __Pyx_INCREF(((PyObject *)__pyx_n_s__paircount));
   PyList_SET_ITEM(__pyx_t_3, 2, ((PyObject *)__pyx_n_s__paircount));
   __Pyx_GIVEREF(((PyObject *)__pyx_n_s__paircount));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__bilex));
-  PyList_SET_ITEM(__pyx_t_3, 3, ((PyObject *)__pyx_n_s__bilex));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__bilex));
+  __Pyx_INCREF(((PyObject *)__pyx_n_s__bilex_f));
+  PyList_SET_ITEM(__pyx_t_3, 3, ((PyObject *)__pyx_n_s__bilex_f));
+  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__bilex_f));
+  __Pyx_INCREF(((PyObject *)__pyx_n_s__bilex_e));
+  PyList_SET_ITEM(__pyx_t_3, 4, ((PyObject *)__pyx_n_s__bilex_e));
+  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__bilex_e));
+  __Pyx_INCREF(((PyObject *)__pyx_n_s__bilex_fe));
+  PyList_SET_ITEM(__pyx_t_3, 5, ((PyObject *)__pyx_n_s__bilex_fe));
+  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__bilex_fe));
   __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_INCREF(((PyObject *)__pyx_n_s_151));
@@ -81342,7 +81453,7 @@ PyMODINIT_FUNC PyInit__sa(void)
   if (PyObject_SetAttr(__pyx_m, __pyx_n_s_151, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":37
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":39
  *     ])
  * 
  * cdef int PRECOMPUTE = 0             # <<<<<<<<<<<<<<
@@ -81351,7 +81462,7 @@ PyMODINIT_FUNC PyInit__sa(void)
  */
   __pyx_v_3_sa_PRECOMPUTE = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":38
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":40
  * 
  * cdef int PRECOMPUTE = 0
  * cdef int MERGE = 1             # <<<<<<<<<<<<<<
@@ -81360,7 +81471,7 @@ PyMODINIT_FUNC PyInit__sa(void)
  */
   __pyx_v_3_sa_MERGE = 1;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":39
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":41
  * cdef int PRECOMPUTE = 0
  * cdef int MERGE = 1
  * cdef int BAEZA_YATES = 2             # <<<<<<<<<<<<<<
@@ -81369,62 +81480,62 @@ PyMODINIT_FUNC PyInit__sa(void)
  */
   __pyx_v_3_sa_BAEZA_YATES = 2;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":42
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":44
  * 
  * # NOTE: was encoded as a non-terminal in the previous version
  * cdef int EPSILON = sym_fromstring('*EPS*', True)             # <<<<<<<<<<<<<<
  * 
  * cdef class TrieNode:
  */
-  __pyx_v_3_sa_EPSILON = __pyx_f_3_sa_sym_fromstring(__pyx_k_171, 1);
+  __pyx_v_3_sa_EPSILON = __pyx_f_3_sa_sym_fromstring(__pyx_k_173, 1);
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":65
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":67
  *     cdef public int count
  *     cdef public root
  *     def __cinit__(self, extended=False):             # <<<<<<<<<<<<<<
  *         self.count = 0
  *         self.extended = extended
  */
-  __pyx_t_3 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_k_99 = __pyx_t_3;
   __Pyx_GIVEREF(__pyx_t_3);
   __pyx_t_3 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2198
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2200
  * 
  * # Spans are _inclusive_ on both ends [i, j]
  * def span_check(vec, i, j):             # <<<<<<<<<<<<<<
  *     k = i
  *     while k <= j:
  */
-  __pyx_t_3 = PyCFunction_NewEx(&__pyx_mdef_3_sa_13span_check, NULL, __pyx_n_s___sa); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2198; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyCFunction_NewEx(&__pyx_mdef_3_sa_15span_check, NULL, __pyx_n_s___sa); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__span_check, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2198; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__span_check, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2206
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2208
  *     return True
  * 
  * def span_inc(vec, i, j):             # <<<<<<<<<<<<<<
  *     k = i
  *     while k <= j:
  */
-  __pyx_t_3 = PyCFunction_NewEx(&__pyx_mdef_3_sa_15span_inc, NULL, __pyx_n_s___sa); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2206; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyCFunction_NewEx(&__pyx_mdef_3_sa_17span_inc, NULL, __pyx_n_s___sa); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__span_inc, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2206; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__span_inc, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2212
+  /* "/home/m/workspace/cdec/python/src/sa/rulefactory.pxi":2214
  *         k += 1
  * 
  * def span_dec(vec, i, j):             # <<<<<<<<<<<<<<
  *     k = i
  *     while k <= j:
  */
-  __pyx_t_3 = PyCFunction_NewEx(&__pyx_mdef_3_sa_17span_dec, NULL, __pyx_n_s___sa); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyCFunction_NewEx(&__pyx_mdef_3_sa_19span_dec, NULL, __pyx_n_s___sa); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__span_dec, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__span_dec, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[8]; __pyx_lineno = 2214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
   /* "/home/m/workspace/cdec/python/src/sa/features.pxi":1
diff --git a/python/src/sa/rulefactory.pxi b/python/src/sa/rulefactory.pxi
index 88f77a8d..7063c2da 100644
--- a/python/src/sa/rulefactory.pxi
+++ b/python/src/sa/rulefactory.pxi
@@ -31,7 +31,9 @@ OnlineFeatureContext = namedtuple('OnlineFeatureContext',
     ['fcount',
      'fsample_count',
      'paircount',
-     'bilex'
+     'bilex_f',
+     'bilex_e',
+     'bilex_fe'
     ])
 
 cdef int PRECOMPUTE = 0
@@ -2150,7 +2152,7 @@ cdef class HieroCachingRuleFactory:
             fsample_count = self.samples_f.get(f, 0)
             d = self.phrases_fe.get(f, None)
             paircount = d.get(e, 0) if d else 0
-            return OnlineFeatureContext(fcount, fsample_count, paircount, self.bilex_fe)
+            return OnlineFeatureContext(fcount, fsample_count, paircount, self.bilex_f, self.bilex_e, self.bilex_fe)
         return None
     
     # Find all phrases that we might try to extract
diff --git a/python/src/sa/sym.pxi b/python/src/sa/sym.pxi
index 81f19ef1..f253aec0 100644
--- a/python/src/sa/sym.pxi
+++ b/python/src/sa/sym.pxi
@@ -104,6 +104,9 @@ cdef int sym_setindex(int sym, int id):
 cdef int sym_fromstring(char* string, bint terminal):
     return ALPHABET.fromstring(string, terminal)
 
+def isvar(sym):
+    return sym_isvar(sym)
+
 def make_lattice(words):
     word_ids = (sym_fromstring(word, True) for word in words)
     return tuple(((word, None, 1), ) for word in word_ids)
-- 
cgit v1.2.3


From b6fb7d74fe72c2a569b8c0448fc66ede6f1cfd67 Mon Sep 17 00:00:00 2001
From: Michael Denkowski <michael.j.denkowski@gmail.com>
Date: Mon, 28 Jan 2013 15:26:58 -0500
Subject: For now, don't use online bilex counts

---
 python/pkg/cdec/sa/extractor.py |  1 -
 python/pkg/cdec/sa/features.py  | 20 ++++++++++++++++----
 python/src/sa/_sa.c             |  2 +-
 3 files changed, 17 insertions(+), 6 deletions(-)

(limited to 'python/pkg/cdec')

diff --git a/python/pkg/cdec/sa/extractor.py b/python/pkg/cdec/sa/extractor.py
index cd3ab899..acc13cbc 100644
--- a/python/pkg/cdec/sa/extractor.py
+++ b/python/pkg/cdec/sa/extractor.py
@@ -60,7 +60,6 @@ class GrammarExtractor:
 
         # TODO: clean this up
         extended_features = []
-        extended_features.append(IsSupportedOnline)
         if online:
             extended_features.append(IsSupportedOnline)
             
diff --git a/python/pkg/cdec/sa/features.py b/python/pkg/cdec/sa/features.py
index a89499d4..cbea5dd1 100644
--- a/python/pkg/cdec/sa/features.py
+++ b/python/pkg/cdec/sa/features.py
@@ -44,7 +44,8 @@ def MaxLexEgivenF(ttable):
     def MaxLexEgivenF(ctx):
         fwords = ctx.fphrase.words
         fwords.append('NULL')
-        if not ctx.online:
+        # Always use this for now
+        if not ctx.online or ctx.online:
             maxOffScore = 0.0
             for e in ctx.ephrase.words:
                 maxScore = max(ttable.get_score(f, e, 0) for f in fwords)
@@ -59,7 +60,12 @@ def MaxLexEgivenF(ttable):
                 maxOffScore += -math.log10(maxScore) if maxScore > 0 else MAXSCORE
             for e in ctx.ephrase:
                 if not isvar(e):
-                    maxScore = max((ctx.online.bilex_fe[f][e] / ctx.online.bilex_f[f]) for f in ctx.fphrase if not isvar(f))
+                    maxScore = 0.0
+                    for f in ctx.fphrase:
+                        if not isvar(f):
+                            b_f = ctx.online.bilex_f.get(f, 0)
+                            if b_f:
+                                maxScore = max(maxScore, ctx.online.bilex_fe.get(f, {}).get(e))
                     maxOnScore += -math.log10(maxScore) if maxScore > 0 else MAXSCORE
             return (maxOffScore + maxOnScore) / 2
     return MaxLexEgivenF
@@ -68,7 +74,8 @@ def MaxLexFgivenE(ttable):
     def MaxLexFgivenE(ctx):
         ewords = ctx.ephrase.words
         ewords.append('NULL')
-        if not ctx.online:
+        # Always use this for now
+        if not ctx.online or ctx.online:
             maxOffScore = 0.0
             for f in ctx.fphrase.words:
                 maxScore = max(ttable.get_score(f, e, 1) for e in ewords)
@@ -83,7 +90,12 @@ def MaxLexFgivenE(ttable):
                 maxOffScore += -math.log10(maxScore) if maxScore > 0 else MAXSCORE
             for f in ctx.fphrase:
                 if not isvar(f):
-                    maxScore = max((ctx.online.bilex_fe[f][e] / ctx.online.bilex_e[e]) for e in ctx.ephrase if not isvar(e))
+                    maxScore = 0.0
+                    for e in ctx.ephrase:
+                        if not isvar(e):
+                            b_e = ctx.online.bilex_e.get(e, 0)
+                            if b_e:
+                                maxScore = max(maxScore, ctx.online.bilex_fe.get(f, {}).get(e, 0) / b_e )
                     maxOnScore += -math.log10(maxScore) if maxScore > 0 else MAXSCORE
             return (maxOffScore + maxOnScore) / 2
     return MaxLexFgivenE
diff --git a/python/src/sa/_sa.c b/python/src/sa/_sa.c
index 7d73b3b7..89445b45 100644
--- a/python/src/sa/_sa.c
+++ b/python/src/sa/_sa.c
@@ -1,4 +1,4 @@
-/* Generated by Cython 0.17.1 on Mon Jan 28 11:56:59 2013 */
+/* Generated by Cython 0.17.1 on Mon Jan 28 14:28:01 2013 */
 
 #define PY_SSIZE_T_CLEAN
 #include "Python.h"
-- 
cgit v1.2.3


From 42965462daaa4598cd438147fcfb1794cfa780de Mon Sep 17 00:00:00 2001
From: Michael Denkowski <michael.j.denkowski@gmail.com>
Date: Tue, 29 Jan 2013 19:15:25 -0500
Subject: fcount -> paircount

---
 python/pkg/cdec/sa/features.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'python/pkg/cdec')

diff --git a/python/pkg/cdec/sa/features.py b/python/pkg/cdec/sa/features.py
index cbea5dd1..46412cd5 100644
--- a/python/pkg/cdec/sa/features.py
+++ b/python/pkg/cdec/sa/features.py
@@ -137,6 +137,6 @@ def IsFEGreaterThanZero(ctx):
 
 def IsSupportedOnline(ctx): # Occurs in online data?
     if ctx.online:
-        return (ctx.online.fcount > 0.01)
+        return (ctx.online.paircount > 0.01)
     else:
         return False
\ No newline at end of file
-- 
cgit v1.2.3