Generated by Cython 0.26

Yellow lines hint at Python interaction.
Click on a line that starts with a "+" to see the C code that Cython generated for it.

Raw output: _grammar.pxi

 001: """ Objects for grammars and grammar rules. """
 002: 
 003: # This regex should match exactly the set of valid yield functions,
 004: # i.e., comma-separated strings of alternating occurrences from the set {0,1},
+005: YFBINARY = re.compile(
  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_re); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 5, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_compile); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 5, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__65, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 5, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_YFBINARY, __pyx_t_1) < 0) __PYX_ERR(0, 5, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
/* … */
  __pyx_tuple__65 = PyTuple_Pack(1, __pyx_kp_b_0_1_1_01_0_10_0_1_1_01_0_10); if (unlikely(!__pyx_tuple__65)) __PYX_ERR(0, 5, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__65);
  __Pyx_GIVEREF(__pyx_tuple__65);
 006: 		rb'^(?:0|1|1?(?:01)+|0?(?:10)+)(?:,(?:0|1|1?(?:01)+|0?(?:10)+))*$')
+007: YFUNARYRE = re.compile(rb'^0(?:,0)*$')
  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_re); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 7, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_compile); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 7, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__66, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 7, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_YFUNARYRE, __pyx_t_1) < 0) __PYX_ERR(0, 7, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
/* … */
  __pyx_tuple__66 = PyTuple_Pack(1, __pyx_kp_b_0_0); if (unlikely(!__pyx_tuple__66)) __PYX_ERR(0, 7, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__66);
  __Pyx_GIVEREF(__pyx_tuple__66);
 008: # Match when non-integral weights are present
+009: LCFRS_NONINT = re.compile(b'\t(?:0x)?[0-9]+[./][0-9]+(?:p-[0-9]+)?\n')
  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_re); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 9, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_compile); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 9, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__67, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 9, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_LCFRS_NONINT, __pyx_t_1) < 0) __PYX_ERR(0, 9, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
/* … */
  __pyx_tuple__67 = PyTuple_Pack(1, __pyx_kp_b_0x_0_9_0_9_p_0_9); if (unlikely(!__pyx_tuple__67)) __PYX_ERR(0, 9, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__67);
  __Pyx_GIVEREF(__pyx_tuple__67);
+010: BITPAR_NONINT = re.compile(b'(?:^|\n)[0-9]+\.[0-9]+[ \t]')
  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_re); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 10, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_compile); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 10, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__68, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 10, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_BITPAR_NONINT, __pyx_t_1) < 0) __PYX_ERR(0, 10, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
/* … */
  __pyx_tuple__68 = PyTuple_Pack(1, __pyx_kp_b_0_9_0_9); if (unlikely(!__pyx_tuple__68)) __PYX_ERR(0, 10, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__68);
  __Pyx_GIVEREF(__pyx_tuple__68);
+011: LEXICON_NONINT = re.compile(b'[ \t][0-9]+[./][0-9]+[ \t\n]')
  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_re); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 11, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_compile); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 11, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__69, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 11, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_LEXICON_NONINT, __pyx_t_1) < 0) __PYX_ERR(0, 11, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
/* … */
  __pyx_tuple__69 = PyTuple_Pack(1, __pyx_kp_b_0_9_0_9_2); if (unlikely(!__pyx_tuple__69)) __PYX_ERR(0, 11, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__69);
  __Pyx_GIVEREF(__pyx_tuple__69);
 012: # Detect rule format of bitpar
+013: BITPARRE = re.compile(rb'^[-.e0-9]+\b')
  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_re); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 13, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_compile); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 13, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__70, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 13, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_BITPARRE, __pyx_t_1) < 0) __PYX_ERR(0, 13, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
/* … */
  __pyx_tuple__70 = PyTuple_Pack(1, __pyx_kp_b_e0_9_b); if (unlikely(!__pyx_tuple__70)) __PYX_ERR(0, 13, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__70);
  __Pyx_GIVEREF(__pyx_tuple__70);
 014: 
 015: # comparison functions for sorting rules on LHS/RHS labels.
+016: cdef int cmp0(const void *p1, const void *p2) nogil:
static int __pyx_f_8discodop_10containers_cmp0(void const *__pyx_v_p1, void const *__pyx_v_p2) {
  ProbRule *__pyx_v_a;
  ProbRule *__pyx_v_b;
  int __pyx_r;
/* … */
  /* function exit code */
  __pyx_L0:;
  return __pyx_r;
}
+017: 	cdef ProbRule *a = <ProbRule *>p1
  __pyx_v_a = ((ProbRule *)__pyx_v_p1);
+018: 	cdef ProbRule *b = <ProbRule *>p2
  __pyx_v_b = ((ProbRule *)__pyx_v_p2);
+019: 	if a.lhs == b.lhs:
  __pyx_t_1 = ((__pyx_v_a->lhs == __pyx_v_b->lhs) != 0);
  if (__pyx_t_1) {
/* … */
  }
+020: 		return (a.no > b.no) - (a.no < b.no)
    __pyx_r = ((__pyx_v_a->no > __pyx_v_b->no) - (__pyx_v_a->no < __pyx_v_b->no));
    goto __pyx_L0;
+021: 	return (a.lhs > b.lhs) - (a.lhs < b.lhs)
  __pyx_r = ((__pyx_v_a->lhs > __pyx_v_b->lhs) - (__pyx_v_a->lhs < __pyx_v_b->lhs));
  goto __pyx_L0;
+022: cdef int cmp1(const void *p1, const void *p2) nogil:
static int __pyx_f_8discodop_10containers_cmp1(void const *__pyx_v_p1, void const *__pyx_v_p2) {
  ProbRule *__pyx_v_a;
  ProbRule *__pyx_v_b;
  int __pyx_r;
/* … */
  /* function exit code */
  __pyx_L0:;
  return __pyx_r;
}
+023: 	cdef ProbRule *a = <ProbRule *>p1
  __pyx_v_a = ((ProbRule *)__pyx_v_p1);
+024: 	cdef ProbRule *b = <ProbRule *>p2
  __pyx_v_b = ((ProbRule *)__pyx_v_p2);
+025: 	if a.rhs1 == b.rhs1:
  __pyx_t_1 = ((__pyx_v_a->rhs1 == __pyx_v_b->rhs1) != 0);
  if (__pyx_t_1) {
/* … */
  }
 026: 		# sort unaries by rhs1 first, then by lhs, so that we can do
 027: 		# incremental binary search for the unaries of a given rhs1.
+028: 		return (a.lhs > b.lhs) - (a.lhs < b.lhs)
    __pyx_r = ((__pyx_v_a->lhs > __pyx_v_b->lhs) - (__pyx_v_a->lhs < __pyx_v_b->lhs));
    goto __pyx_L0;
+029: 	return (a.rhs1 > b.rhs1) - (a.rhs1 < b.rhs1)
  __pyx_r = ((__pyx_v_a->rhs1 > __pyx_v_b->rhs1) - (__pyx_v_a->rhs1 < __pyx_v_b->rhs1));
  goto __pyx_L0;
+030: cdef int cmp2(const void *p1, const void *p2) nogil:
static int __pyx_f_8discodop_10containers_cmp2(void const *__pyx_v_p1, void const *__pyx_v_p2) {
  ProbRule *__pyx_v_a;
  ProbRule *__pyx_v_b;
  int __pyx_r;
/* … */
  /* function exit code */
  __pyx_L0:;
  return __pyx_r;
}
+031: 	cdef ProbRule *a = <ProbRule *>p1
  __pyx_v_a = ((ProbRule *)__pyx_v_p1);
+032: 	cdef ProbRule *b = <ProbRule *>p2
  __pyx_v_b = ((ProbRule *)__pyx_v_p2);
+033: 	if a.rhs2 == b.rhs2:
  __pyx_t_1 = ((__pyx_v_a->rhs2 == __pyx_v_b->rhs2) != 0);
  if (__pyx_t_1) {
/* … */
  }
+034: 		return (a.prob < b.prob) - (a.prob > b.prob)
    __pyx_r = ((__pyx_v_a->prob < __pyx_v_b->prob) - (__pyx_v_a->prob > __pyx_v_b->prob));
    goto __pyx_L0;
+035: 	return (a.rhs2 > b.rhs2) - (a.rhs2 < b.rhs2)
  __pyx_r = ((__pyx_v_a->rhs2 > __pyx_v_b->rhs2) - (__pyx_v_a->rhs2 < __pyx_v_b->rhs2));
  goto __pyx_L0;
 036: 
 037: 
 038: @cython.final
+039: cdef class Grammar:
struct __pyx_vtabstruct_8discodop_10containers_Grammar {
  PyObject *(*_indexrules)(struct __pyx_obj_8discodop_10containers_Grammar *, ProbRule **, int, int);
  PyObject *(*rulestr)(struct __pyx_obj_8discodop_10containers_Grammar *, int, int __pyx_skip_dispatch);
  PyObject *(*noderuleno)(struct __pyx_obj_8discodop_10containers_Grammar *, PyObject *, int __pyx_skip_dispatch);
  PyObject *(*getruleno)(struct __pyx_obj_8discodop_10containers_Grammar *, PyObject *, PyObject *, int __pyx_skip_dispatch);
  PyObject *(*yfstr)(struct __pyx_obj_8discodop_10containers_Grammar *, ProbRule);
};
static struct __pyx_vtabstruct_8discodop_10containers_Grammar *__pyx_vtabptr_8discodop_10containers_Grammar;
static PyObject *__pyx_f_8discodop_10containers_7Grammar__indexrules(struct __pyx_obj_8discodop_10containers_Grammar *, ProbRule **, int, int);
static PyObject *__pyx_f_8discodop_10containers_7Grammar_rulestr(struct __pyx_obj_8discodop_10containers_Grammar *, int, int __pyx_skip_dispatch);
static PyObject *__pyx_f_8discodop_10containers_7Grammar_noderuleno(struct __pyx_obj_8discodop_10containers_Grammar *, PyObject *, int __pyx_skip_dispatch);
static PyObject *__pyx_f_8discodop_10containers_7Grammar_getruleno(struct __pyx_obj_8discodop_10containers_Grammar *, PyObject *, PyObject *, int __pyx_skip_dispatch);
static PyObject *__pyx_f_8discodop_10containers_7Grammar_yfstr(struct __pyx_obj_8discodop_10containers_Grammar *, ProbRule);

 040: 	"""A grammar object which stores rules compactly, indexed in various ways.
 041: 
 042: 	:param rule_tuples_or_filename: either a sequence of tuples containing both
 043: 		phrasal & lexical rules, or the name of a file with the phrasal rules
 044: 		in text format; in the latter case the filename ``lexicon`` should be
 045: 		given. The text format allows for more efficient loading and is used
 046: 		internally.
 047: 	:param start: a string identifying the unique start symbol of this grammar,
 048: 		which will be used by default when parsing with this grammar
 049: 	:param altweights: a dictionary or filename with numpy arrays of
 050: 		alternative weights.
 051: 
 052: 	By default the grammar is in logprob mode;
 053: 	invoke ``grammar.switch('default', logprob=False)`` to switch.
 054: 	If the grammar only contains integral weights (frequencies), they will
 055: 	be normalized into relative frequencies; if the grammar contains any
 056: 	non-integral weights, weights will be left unchanged."""
+057: 	def __cinit__(self):
/* Python wrapper */
static int __pyx_pw_8discodop_10containers_7Grammar_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static int __pyx_pw_8discodop_10containers_7Grammar_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  int __pyx_r;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
  if (unlikely(PyTuple_GET_SIZE(__pyx_args) > 0)) {
    __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 0, 0, PyTuple_GET_SIZE(__pyx_args)); return -1;}
  if (unlikely(__pyx_kwds) && unlikely(PyDict_Size(__pyx_kwds) > 0) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "__cinit__", 0))) return -1;
  __pyx_r = __pyx_pf_8discodop_10containers_7Grammar___cinit__(((struct __pyx_obj_8discodop_10containers_Grammar *)__pyx_v_self));

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static int __pyx_pf_8discodop_10containers_7Grammar___cinit__(struct __pyx_obj_8discodop_10containers_Grammar *__pyx_v_self) {
  int __pyx_r;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("__cinit__", 0);
/* … */
  /* function exit code */
  __pyx_r = 0;
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
+058: 		self.unary = self.mapping = self.splitmapping = NULL
  __pyx_v_self->unary = NULL;
  __pyx_v_self->mapping = NULL;
  __pyx_v_self->splitmapping = NULL;
 059: 
+060: 	def __init__(self, rule_tuples_or_filename, lexiconfile=None, start='ROOT',
/* Python wrapper */
static int __pyx_pw_8discodop_10containers_7Grammar_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static int __pyx_pw_8discodop_10containers_7Grammar_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_rule_tuples_or_filename = 0;
  PyObject *__pyx_v_lexiconfile = 0;
  PyObject *__pyx_v_start = 0;
  PyObject *__pyx_v_altweights = 0;
  int __pyx_r;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_rule_tuples_or_filename,&__pyx_n_s_lexiconfile,&__pyx_n_s_start,&__pyx_n_s_altweights,0};
    PyObject* values[4] = {0,0,0,0};
    values[1] = ((PyObject *)Py_None);
    values[2] = ((PyObject *)__pyx_n_u_ROOT);
/* … */
  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static int __pyx_pf_8discodop_10containers_7Grammar_2__init__(struct __pyx_obj_8discodop_10containers_Grammar *__pyx_v_self, PyObject *__pyx_v_rule_tuples_or_filename, PyObject *__pyx_v_lexiconfile, PyObject *__pyx_v_start, PyObject *__pyx_v_altweights) {
  int __pyx_v_n;
  PyObject *__pyx_v_rules = NULL;
  PyObject *__pyx_v_lexicon = NULL;
  PyObject *__pyx_v_writegrammar = NULL;
  size_t __pyx_v_lhs;
  PyObject *__pyx_v_nonint = NULL;
  int __pyx_r;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("__init__", 0);
/* … */
  /* function exit code */
  __pyx_r = 0;
  goto __pyx_L0;
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_AddTraceback("discodop.containers.Grammar.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = -1;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_rules);
  __Pyx_XDECREF(__pyx_v_lexicon);
  __Pyx_XDECREF(__pyx_v_writegrammar);
  __Pyx_XDECREF(__pyx_v_nonint);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
+061: 			altweights=None):
    values[3] = ((PyObject *)Py_None);
    if (unlikely(__pyx_kwds)) {
      Py_ssize_t kw_args;
      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
      switch (pos_args) {
        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
        CYTHON_FALLTHROUGH;
        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = PyDict_Size(__pyx_kwds);
      switch (pos_args) {
        case  0:
        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_rule_tuples_or_filename)) != 0)) kw_args--;
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (kw_args > 0) {
          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_lexiconfile);
          if (value) { values[1] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (kw_args > 0) {
          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_start);
          if (value) { values[2] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  3:
        if (kw_args > 0) {
          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_altweights);
          if (value) { values[3] = value; kw_args--; }
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 60, __pyx_L3_error)
      }
    } else {
      switch (PyTuple_GET_SIZE(__pyx_args)) {
        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
        CYTHON_FALLTHROUGH;
        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        break;
        default: goto __pyx_L5_argtuple_error;
      }
    }
    __pyx_v_rule_tuples_or_filename = values[0];
    __pyx_v_lexiconfile = values[1];
    __pyx_v_start = values[2];
    __pyx_v_altweights = values[3];
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("__init__", 0, 1, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 60, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("discodop.containers.Grammar.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return -1;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_8discodop_10containers_7Grammar_2__init__(((struct __pyx_obj_8discodop_10containers_Grammar *)__pyx_v_self), __pyx_v_rule_tuples_or_filename, __pyx_v_lexiconfile, __pyx_v_start, __pyx_v_altweights);
 062: 		cdef int n
+063: 		self.mapping = self.splitmapping = self.bylhs = NULL
  __pyx_v_self->mapping = NULL;
  __pyx_v_self->splitmapping = NULL;
  __pyx_v_self->bylhs = NULL;
+064: 		self.start = start
  if (!(likely(PyUnicode_CheckExact(__pyx_v_start))||((__pyx_v_start) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_start)->tp_name), 0))) __PYX_ERR(0, 64, __pyx_L1_error)
  __pyx_t_1 = __pyx_v_start;
  __Pyx_INCREF(__pyx_t_1);
  __Pyx_GIVEREF(__pyx_t_1);
  __Pyx_GOTREF(__pyx_v_self->start);
  __Pyx_DECREF(__pyx_v_self->start);
  __pyx_v_self->start = ((PyObject*)__pyx_t_1);
  __pyx_t_1 = 0;
+065: 		self.numunary = self.numbinary = 0
  __pyx_v_self->numunary = 0;
  __pyx_v_self->numbinary = 0;
+066: 		self.logprob = True
  __pyx_v_self->logprob = 1;
+067: 		self.toid = StringIntDict()
  __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_8discodop_10containers_StringIntDict), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 67, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_GIVEREF(__pyx_t_1);
  __Pyx_GOTREF(__pyx_v_self->toid);
  __Pyx_DECREF(((PyObject *)__pyx_v_self->toid));
  __pyx_v_self->toid = ((struct __pyx_obj_8discodop_10containers_StringIntDict *)__pyx_t_1);
  __pyx_t_1 = 0;
+068: 		self.tolabel = StringList()
  __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_8discodop_10containers_StringList), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 68, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_GIVEREF(__pyx_t_1);
  __Pyx_GOTREF(__pyx_v_self->tolabel);
  __Pyx_DECREF(((PyObject *)__pyx_v_self->tolabel));
  __pyx_v_self->tolabel = ((struct __pyx_obj_8discodop_10containers_StringList *)__pyx_t_1);
  __pyx_t_1 = 0;
+069: 		self.currentmodel = 'default'
  __Pyx_INCREF(__pyx_n_u_default);
  __Pyx_GIVEREF(__pyx_n_u_default);
  __Pyx_GOTREF(__pyx_v_self->currentmodel);
  __Pyx_DECREF(__pyx_v_self->currentmodel);
  __pyx_v_self->currentmodel = __pyx_n_u_default;
+070: 		if isinstance(altweights, dict):
  __pyx_t_2 = PyDict_Check(__pyx_v_altweights); 
  __pyx_t_3 = (__pyx_t_2 != 0);
  if (__pyx_t_3) {
/* … */
    goto __pyx_L3;
  }
+071: 			self.models = altweights
    __Pyx_INCREF(__pyx_v_altweights);
    __Pyx_GIVEREF(__pyx_v_altweights);
    __Pyx_GOTREF(__pyx_v_self->models);
    __Pyx_DECREF(__pyx_v_self->models);
    __pyx_v_self->models = __pyx_v_altweights;
+072: 			self.altweightsfile = None
    __Pyx_INCREF(Py_None);
    __Pyx_GIVEREF(Py_None);
    __Pyx_GOTREF(__pyx_v_self->altweightsfile);
    __Pyx_DECREF(__pyx_v_self->altweightsfile);
    __pyx_v_self->altweightsfile = ((PyObject*)Py_None);
+073: 		elif altweights is not None:
  __pyx_t_3 = (__pyx_v_altweights != Py_None);
  __pyx_t_2 = (__pyx_t_3 != 0);
  if (__pyx_t_2) {
/* … */
    goto __pyx_L3;
  }
+074: 			self.models = None
    __Pyx_INCREF(Py_None);
    __Pyx_GIVEREF(Py_None);
    __Pyx_GOTREF(__pyx_v_self->models);
    __Pyx_DECREF(__pyx_v_self->models);
    __pyx_v_self->models = Py_None;
+075: 			self.altweightsfile = altweights
    if (!(likely(PyUnicode_CheckExact(__pyx_v_altweights))||((__pyx_v_altweights) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_altweights)->tp_name), 0))) __PYX_ERR(0, 75, __pyx_L1_error)
    __pyx_t_1 = __pyx_v_altweights;
    __Pyx_INCREF(__pyx_t_1);
    __Pyx_GIVEREF(__pyx_t_1);
    __Pyx_GOTREF(__pyx_v_self->altweightsfile);
    __Pyx_DECREF(__pyx_v_self->altweightsfile);
    __pyx_v_self->altweightsfile = ((PyObject*)__pyx_t_1);
    __pyx_t_1 = 0;
 076: 		else:
+077: 			self.models = {}
  /*else*/ {
    __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 77, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_GIVEREF(__pyx_t_1);
    __Pyx_GOTREF(__pyx_v_self->models);
    __Pyx_DECREF(__pyx_v_self->models);
    __pyx_v_self->models = __pyx_t_1;
    __pyx_t_1 = 0;
+078: 			self.altweightsfile = None
    __Pyx_INCREF(Py_None);
    __Pyx_GIVEREF(Py_None);
    __Pyx_GOTREF(__pyx_v_self->altweightsfile);
    __Pyx_DECREF(__pyx_v_self->altweightsfile);
    __pyx_v_self->altweightsfile = ((PyObject*)Py_None);
  }
  __pyx_L3:;
 079: 
+080: 		rules = lexicon = None
  __Pyx_INCREF(Py_None);
  __pyx_v_rules = Py_None;
  __Pyx_INCREF(Py_None);
  __pyx_v_lexicon = Py_None;
+081: 		if rule_tuples_or_filename and isinstance(rule_tuples_or_filename, str):
  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_rule_tuples_or_filename); if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 81, __pyx_L1_error)
  if (__pyx_t_3) {
  } else {
    __pyx_t_2 = __pyx_t_3;
    goto __pyx_L5_bool_binop_done;
  }
  __pyx_t_3 = PyUnicode_Check(__pyx_v_rule_tuples_or_filename); 
  __pyx_t_4 = (__pyx_t_3 != 0);
  __pyx_t_2 = __pyx_t_4;
  __pyx_L5_bool_binop_done:;
  if (__pyx_t_2) {
/* … */
    goto __pyx_L4;
  }
+082: 			if not isinstance(lexiconfile, str):
    __pyx_t_2 = PyUnicode_Check(__pyx_v_lexiconfile); 
    __pyx_t_4 = ((!(__pyx_t_2 != 0)) != 0);
    if (__pyx_t_4) {
/* … */
    }
+083: 				raise ValueError('expected lexicon filename.')
      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 83, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_Raise(__pyx_t_1, 0, 0, 0);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __PYX_ERR(0, 83, __pyx_L1_error)
/* … */
  __pyx_tuple_ = PyTuple_Pack(1, __pyx_kp_u_expected_lexicon_filename); if (unlikely(!__pyx_tuple_)) __PYX_ERR(0, 83, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple_);
  __Pyx_GIVEREF(__pyx_tuple_);
+084: 			self.rulesfile = rule_tuples_or_filename
    if (!(likely(PyUnicode_CheckExact(__pyx_v_rule_tuples_or_filename))||((__pyx_v_rule_tuples_or_filename) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_rule_tuples_or_filename)->tp_name), 0))) __PYX_ERR(0, 84, __pyx_L1_error)
    __pyx_t_1 = __pyx_v_rule_tuples_or_filename;
    __Pyx_INCREF(__pyx_t_1);
    __Pyx_GIVEREF(__pyx_t_1);
    __Pyx_GOTREF(__pyx_v_self->rulesfile);
    __Pyx_DECREF(__pyx_v_self->rulesfile);
    __pyx_v_self->rulesfile = ((PyObject*)__pyx_t_1);
    __pyx_t_1 = 0;
+085: 			self.lexiconfile = lexiconfile
    if (!(likely(PyUnicode_CheckExact(__pyx_v_lexiconfile))||((__pyx_v_lexiconfile) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_lexiconfile)->tp_name), 0))) __PYX_ERR(0, 85, __pyx_L1_error)
    __pyx_t_1 = __pyx_v_lexiconfile;
    __Pyx_INCREF(__pyx_t_1);
    __Pyx_GIVEREF(__pyx_t_1);
    __Pyx_GOTREF(__pyx_v_self->lexiconfile);
    __Pyx_DECREF(__pyx_v_self->lexiconfile);
    __pyx_v_self->lexiconfile = ((PyObject*)__pyx_t_1);
    __pyx_t_1 = 0;
+086: 			self.ruletuples = None
    __Pyx_INCREF(Py_None);
    __Pyx_GIVEREF(Py_None);
    __Pyx_GOTREF(__pyx_v_self->ruletuples);
    __Pyx_DECREF(__pyx_v_self->ruletuples);
    __pyx_v_self->ruletuples = Py_None;
+087: 			rules = readbytes(rule_tuples_or_filename)
    __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_readbytes); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 87, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __pyx_t_6 = NULL;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5);
      if (likely(__pyx_t_6)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
        __Pyx_INCREF(__pyx_t_6);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_5, function);
      }
    }
    if (!__pyx_t_6) {
      __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_v_rule_tuples_or_filename); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 87, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
    } else {
      #if CYTHON_FAST_PYCALL
      if (PyFunction_Check(__pyx_t_5)) {
        PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_v_rule_tuples_or_filename};
        __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 87, __pyx_L1_error)
        __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
        __Pyx_GOTREF(__pyx_t_1);
      } else
      #endif
      #if CYTHON_FAST_PYCCALL
      if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
        PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_v_rule_tuples_or_filename};
        __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 87, __pyx_L1_error)
        __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
        __Pyx_GOTREF(__pyx_t_1);
      } else
      #endif
      {
        __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 87, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_7);
        __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __pyx_t_6 = NULL;
        __Pyx_INCREF(__pyx_v_rule_tuples_or_filename);
        __Pyx_GIVEREF(__pyx_v_rule_tuples_or_filename);
        PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_v_rule_tuples_or_filename);
        __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 87, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      }
    }
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    __Pyx_DECREF_SET(__pyx_v_rules, __pyx_t_1);
    __pyx_t_1 = 0;
+088: 			lexicon = readbytes(lexiconfile)
    __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_readbytes); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 88, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __pyx_t_7 = NULL;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
      if (likely(__pyx_t_7)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
        __Pyx_INCREF(__pyx_t_7);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_5, function);
      }
    }
    if (!__pyx_t_7) {
      __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_v_lexiconfile); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 88, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
    } else {
      #if CYTHON_FAST_PYCALL
      if (PyFunction_Check(__pyx_t_5)) {
        PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_v_lexiconfile};
        __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 88, __pyx_L1_error)
        __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
        __Pyx_GOTREF(__pyx_t_1);
      } else
      #endif
      #if CYTHON_FAST_PYCCALL
      if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
        PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_v_lexiconfile};
        __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 88, __pyx_L1_error)
        __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
        __Pyx_GOTREF(__pyx_t_1);
      } else
      #endif
      {
        __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 88, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_6);
        __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_7); __pyx_t_7 = NULL;
        __Pyx_INCREF(__pyx_v_lexiconfile);
        __Pyx_GIVEREF(__pyx_v_lexiconfile);
        PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_v_lexiconfile);
        __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_6, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 88, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
      }
    }
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    __Pyx_DECREF_SET(__pyx_v_lexicon, __pyx_t_1);
    __pyx_t_1 = 0;
+089: 			self.bitpar = BITPARRE.match(rules)
    __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_BITPARRE); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 89, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_match); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 89, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    __pyx_t_5 = NULL;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_6))) {
      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_6);
      if (likely(__pyx_t_5)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
        __Pyx_INCREF(__pyx_t_5);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_6, function);
      }
    }
    if (!__pyx_t_5) {
      __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_rules); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 89, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
    } else {
      #if CYTHON_FAST_PYCALL
      if (PyFunction_Check(__pyx_t_6)) {
        PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_v_rules};
        __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 89, __pyx_L1_error)
        __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
        __Pyx_GOTREF(__pyx_t_1);
      } else
      #endif
      #if CYTHON_FAST_PYCCALL
      if (__Pyx_PyFastCFunction_Check(__pyx_t_6)) {
        PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_v_rules};
        __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 89, __pyx_L1_error)
        __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
        __Pyx_GOTREF(__pyx_t_1);
      } else
      #endif
      {
        __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 89, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_7);
        __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __pyx_t_5 = NULL;
        __Pyx_INCREF(__pyx_v_rules);
        __Pyx_GIVEREF(__pyx_v_rules);
        PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_v_rules);
        __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 89, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      }
    }
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 89, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_v_self->bitpar = __pyx_t_4;
+090: 		elif rule_tuples_or_filename and isinstance(
  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_rule_tuples_or_filename); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 90, __pyx_L1_error)
  if (__pyx_t_2) {
  } else {
    __pyx_t_4 = __pyx_t_2;
    goto __pyx_L8_bool_binop_done;
  }
/* … */
  __pyx_t_3 = (__pyx_t_2 != 0);
  __pyx_t_4 = __pyx_t_3;
  __pyx_L8_bool_binop_done:;
  if (__pyx_t_4) {
/* … */
    goto __pyx_L4;
  }
+091: 				rule_tuples_or_filename[0], tuple):
  __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_rule_tuples_or_filename, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 91, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = PyTuple_Check(__pyx_t_1); 
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 092: 			# convert tuples to strings with text format
+093: 			from .grammar import writegrammar
    __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 93, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_INCREF(__pyx_n_s_writegrammar);
    __Pyx_GIVEREF(__pyx_n_s_writegrammar);
    PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_writegrammar);
    __pyx_t_6 = __Pyx_Import(__pyx_n_s_grammar, __pyx_t_1, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 93, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_6, __pyx_n_s_writegrammar); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 93, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_INCREF(__pyx_t_1);
    __pyx_v_writegrammar = __pyx_t_1;
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+094: 			self.rulesfile = self.lexiconfile = None
    __Pyx_INCREF(Py_None);
    __Pyx_GIVEREF(Py_None);
    __Pyx_GOTREF(__pyx_v_self->rulesfile);
    __Pyx_DECREF(__pyx_v_self->rulesfile);
    __pyx_v_self->rulesfile = ((PyObject*)Py_None);
    __Pyx_INCREF(Py_None);
    __Pyx_GIVEREF(Py_None);
    __Pyx_GOTREF(__pyx_v_self->lexiconfile);
    __Pyx_DECREF(__pyx_v_self->lexiconfile);
    __pyx_v_self->lexiconfile = ((PyObject*)Py_None);
+095: 			self.ruletuples = rule_tuples_or_filename
    __Pyx_INCREF(__pyx_v_rule_tuples_or_filename);
    __Pyx_GIVEREF(__pyx_v_rule_tuples_or_filename);
    __Pyx_GOTREF(__pyx_v_self->ruletuples);
    __Pyx_DECREF(__pyx_v_self->ruletuples);
    __pyx_v_self->ruletuples = __pyx_v_rule_tuples_or_filename;
+096: 			rules, lexicon = writegrammar(
    __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 96, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __Pyx_INCREF(__pyx_v_rule_tuples_or_filename);
    __Pyx_GIVEREF(__pyx_v_rule_tuples_or_filename);
    PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_v_rule_tuples_or_filename);
/* … */
    __pyx_t_7 = __Pyx_PyObject_Call(__pyx_v_writegrammar, __pyx_t_6, __pyx_t_1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 96, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_7);
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    if ((likely(PyTuple_CheckExact(__pyx_t_7))) || (PyList_CheckExact(__pyx_t_7))) {
      PyObject* sequence = __pyx_t_7;
      #if !CYTHON_COMPILING_IN_PYPY
      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_ERR(0, 96, __pyx_L1_error)
      }
      #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
      if (likely(PyTuple_CheckExact(sequence))) {
        __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); 
        __pyx_t_6 = PyTuple_GET_ITEM(sequence, 1); 
      } else {
        __pyx_t_1 = PyList_GET_ITEM(sequence, 0); 
        __pyx_t_6 = PyList_GET_ITEM(sequence, 1); 
      }
      __Pyx_INCREF(__pyx_t_1);
      __Pyx_INCREF(__pyx_t_6);
      #else
      __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 96, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 96, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      #endif
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    } else {
      Py_ssize_t index = -1;
      __pyx_t_5 = PyObject_GetIter(__pyx_t_7); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 96, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      __pyx_t_8 = Py_TYPE(__pyx_t_5)->tp_iternext;
      index = 0; __pyx_t_1 = __pyx_t_8(__pyx_t_5); if (unlikely(!__pyx_t_1)) goto __pyx_L10_unpacking_failed;
      __Pyx_GOTREF(__pyx_t_1);
      index = 1; __pyx_t_6 = __pyx_t_8(__pyx_t_5); if (unlikely(!__pyx_t_6)) goto __pyx_L10_unpacking_failed;
      __Pyx_GOTREF(__pyx_t_6);
      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_5), 2) < 0) __PYX_ERR(0, 96, __pyx_L1_error)
      __pyx_t_8 = NULL;
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      goto __pyx_L11_unpacking_done;
      __pyx_L10_unpacking_failed:;
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      __pyx_t_8 = NULL;
      if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
      __PYX_ERR(0, 96, __pyx_L1_error)
      __pyx_L11_unpacking_done:;
    }
    __Pyx_DECREF_SET(__pyx_v_rules, __pyx_t_1);
    __pyx_t_1 = 0;
    __Pyx_DECREF_SET(__pyx_v_lexicon, __pyx_t_6);
    __pyx_t_6 = 0;
+097: 					rule_tuples_or_filename, bitpar=False)
    __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 97, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_bitpar, Py_False) < 0) __PYX_ERR(0, 97, __pyx_L1_error)
+098: 			rules, lexicon = rules.encode('utf8'), lexicon.encode('utf8')
    __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_rules, __pyx_n_s_encode); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 98, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_7);
    __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 98, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_lexicon, __pyx_n_s_encode); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 98, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_7);
/* … */
  __pyx_tuple__2 = PyTuple_Pack(1, __pyx_n_u_utf8); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(0, 98, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__2);
  __Pyx_GIVEREF(__pyx_tuple__2);
    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 98, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    __Pyx_DECREF_SET(__pyx_v_rules, __pyx_t_6);
    __pyx_t_6 = 0;
    __Pyx_DECREF_SET(__pyx_v_lexicon, __pyx_t_1);
    __pyx_t_1 = 0;
  __pyx_tuple__3 = PyTuple_Pack(1, __pyx_n_u_utf8); if (unlikely(!__pyx_tuple__3)) __PYX_ERR(0, 98, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__3);
  __Pyx_GIVEREF(__pyx_tuple__3);
+099: 			self.bitpar = False
    __pyx_v_self->bitpar = 0;
 100: 		else:
+101: 			raise ValueError(
  /*else*/ {
/* … */
    __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 101, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __Pyx_GIVEREF(__pyx_t_1);
    PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_1);
    __pyx_t_1 = 0;
    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_6, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 101, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    __Pyx_Raise(__pyx_t_1, 0, 0, 0);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __PYX_ERR(0, 101, __pyx_L1_error)
  }
  __pyx_L4:;
 102: 					'expected non-empty sequence of tuples or unicode string.'
+103: 					'got: %r' % type(rule_tuples_or_filename))
    __pyx_t_1 = PyUnicode_Format(__pyx_kp_u_expected_non_empty_sequence_of_t, ((PyObject *)Py_TYPE(__pyx_v_rule_tuples_or_filename))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 103, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
 104: 
 105: 		# collect non-terminal labels; count number of rules in each category
 106: 		# for allocation purposes.
+107: 		self._convertrules(rules)
  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_convertrules); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 107, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __pyx_t_7 = NULL;
  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
    __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6);
    if (likely(__pyx_t_7)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
      __Pyx_INCREF(__pyx_t_7);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_6, function);
    }
  }
  if (!__pyx_t_7) {
    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_rules); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 107, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
  } else {
    #if CYTHON_FAST_PYCALL
    if (PyFunction_Check(__pyx_t_6)) {
      PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_v_rules};
      __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 107, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
      __Pyx_GOTREF(__pyx_t_1);
    } else
    #endif
    #if CYTHON_FAST_PYCCALL
    if (__Pyx_PyFastCFunction_Check(__pyx_t_6)) {
      PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_v_rules};
      __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 107, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
      __Pyx_GOTREF(__pyx_t_1);
    } else
    #endif
    {
      __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 107, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_7); __pyx_t_7 = NULL;
      __Pyx_INCREF(__pyx_v_rules);
      __Pyx_GIVEREF(__pyx_v_rules);
      PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_v_rules);
      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 107, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    }
  }
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+108: 		self._convertlexicon(lexicon)
  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_convertlexicon); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 108, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __pyx_t_5 = NULL;
  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
    __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_6);
    if (likely(__pyx_t_5)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
      __Pyx_INCREF(__pyx_t_5);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_6, function);
    }
  }
  if (!__pyx_t_5) {
    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_lexicon); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 108, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
  } else {
    #if CYTHON_FAST_PYCALL
    if (PyFunction_Check(__pyx_t_6)) {
      PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_v_lexicon};
      __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 108, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
      __Pyx_GOTREF(__pyx_t_1);
    } else
    #endif
    #if CYTHON_FAST_PYCCALL
    if (__Pyx_PyFastCFunction_Check(__pyx_t_6)) {
      PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_v_lexicon};
      __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 108, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
      __Pyx_GOTREF(__pyx_t_1);
    } else
    #endif
    {
      __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 108, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __pyx_t_5 = NULL;
      __Pyx_INCREF(__pyx_v_lexicon);
      __Pyx_GIVEREF(__pyx_v_lexicon);
      PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_v_lexicon);
      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 108, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    }
  }
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+109: 		self.nonterminals = self.toid.ob.size()
  __pyx_v_self->nonterminals = __pyx_v_self->toid->ob.size();
+110: 		self._allocate()
  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_allocate); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 110, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __pyx_t_7 = NULL;
  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
    __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6);
    if (likely(__pyx_t_7)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
      __Pyx_INCREF(__pyx_t_7);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_6, function);
    }
  }
  if (__pyx_t_7) {
    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_t_7); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 110, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
  } else {
    __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 110, __pyx_L1_error)
  }
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 111: 		# index & filter phrasal rules in different ways
+112: 		self._indexrules(self.bylhs, 0, 0)
  __pyx_t_1 = __pyx_f_8discodop_10containers_7Grammar__indexrules(__pyx_v_self, __pyx_v_self->bylhs, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 112, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 113: 		# check whether RHS labels occur as LHS of phrasal and/or lexical rule
+114: 		for lhs in range(1, self.nonterminals):
  __pyx_t_9 = __pyx_v_self->nonterminals;
  for (__pyx_t_10 = 1; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
    __pyx_v_lhs = __pyx_t_10;
+115: 			if (self.bylhs[lhs][0].lhs != lhs and
    __pyx_t_3 = ((((__pyx_v_self->bylhs[__pyx_v_lhs])[0]).lhs != __pyx_v_lhs) != 0);
    if (__pyx_t_3) {
    } else {
      __pyx_t_4 = __pyx_t_3;
      goto __pyx_L15_bool_binop_done;
    }
/* … */
    if (__pyx_t_4) {
/* … */
    }
  }
+116: 					self.lexicalbylhs.find(lhs) == self.lexicalbylhs.end()):
    __pyx_t_3 = ((__pyx_v_self->lexicalbylhs.find(__pyx_v_lhs) == __pyx_v_self->lexicalbylhs.end()) != 0);
    __pyx_t_4 = __pyx_t_3;
    __pyx_L15_bool_binop_done:;
+117: 				raise ValueError('symbol %r has not been seen as LHS '
      __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 117, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_GIVEREF(__pyx_t_6);
      PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_6);
      __pyx_t_6 = 0;
      __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_1, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 117, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __Pyx_Raise(__pyx_t_6, 0, 0, 0);
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
      __PYX_ERR(0, 117, __pyx_L1_error)
+118: 					'in any rule.' % self.tolabel[lhs])
      __pyx_t_1 = __Pyx_GetItemInt(((PyObject *)__pyx_v_self->tolabel), __pyx_v_lhs, size_t, 0, __Pyx_PyInt_FromSize_t, 0, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 118, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_6 = PyUnicode_Format(__pyx_kp_u_symbol_r_has_not_been_seen_as_LH, __pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 118, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+119: 		self._indexrules(self.unary, 1, 2)
  __pyx_t_6 = __pyx_f_8discodop_10containers_7Grammar__indexrules(__pyx_v_self, __pyx_v_self->unary, 1, 2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 119, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+120: 		self._indexrules(self.lbinary, 1, 3)
  __pyx_t_6 = __pyx_f_8discodop_10containers_7Grammar__indexrules(__pyx_v_self, __pyx_v_self->lbinary, 1, 3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 120, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+121: 		self._indexrules(self.rbinary, 2, 3)
  __pyx_t_6 = __pyx_f_8discodop_10containers_7Grammar__indexrules(__pyx_v_self, __pyx_v_self->rbinary, 2, 3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 121, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
 122: 		# indexing requires sorting; this map gives the new index
 123: 		# given an original rule number (useful with the rulestr method).
+124: 		for n in range(self.numrules):
  __pyx_t_9 = __pyx_v_self->numrules;
  for (__pyx_t_11 = 0; __pyx_t_11 < __pyx_t_9; __pyx_t_11+=1) {
    __pyx_v_n = __pyx_t_11;
+125: 			self.revrulemap[self.bylhs[0][n].no] = n
    (__pyx_v_self->revrulemap[((__pyx_v_self->bylhs[0])[__pyx_v_n]).no]) = __pyx_v_n;
  }
 126: 		# if the grammar only has integral weights (frequencies),
 127: 		# normalize them into relative frequencies.
+128: 		nonint = BITPAR_NONINT if self.bitpar else LCFRS_NONINT
  if ((__pyx_v_self->bitpar != 0)) {
    __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_BITPAR_NONINT); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 128, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_6 = __pyx_t_1;
    __pyx_t_1 = 0;
  } else {
    __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_LCFRS_NONINT); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 128, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_6 = __pyx_t_1;
    __pyx_t_1 = 0;
  }
  __pyx_v_nonint = __pyx_t_6;
  __pyx_t_6 = 0;
+129: 		if nonint.search(rules) is None:
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_nonint, __pyx_n_s_search); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 129, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_7 = NULL;
  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_1))) {
    __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_1);
    if (likely(__pyx_t_7)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
      __Pyx_INCREF(__pyx_t_7);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_1, function);
    }
  }
  if (!__pyx_t_7) {
    __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_v_rules); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 129, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
  } else {
    #if CYTHON_FAST_PYCALL
    if (PyFunction_Check(__pyx_t_1)) {
      PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_v_rules};
      __pyx_t_6 = __Pyx_PyFunction_FastCall(__pyx_t_1, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 129, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
      __Pyx_GOTREF(__pyx_t_6);
    } else
    #endif
    #if CYTHON_FAST_PYCCALL
    if (__Pyx_PyFastCFunction_Check(__pyx_t_1)) {
      PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_v_rules};
      __pyx_t_6 = __Pyx_PyCFunction_FastCall(__pyx_t_1, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 129, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
      __Pyx_GOTREF(__pyx_t_6);
    } else
    #endif
    {
      __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 129, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_7); __pyx_t_7 = NULL;
      __Pyx_INCREF(__pyx_v_rules);
      __Pyx_GIVEREF(__pyx_v_rules);
      PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_v_rules);
      __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_5, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 129, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    }
  }
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_4 = (__pyx_t_6 == Py_None);
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  __pyx_t_3 = (__pyx_t_4 != 0);
  if (__pyx_t_3) {
/* … */
  }
+130: 			self._normalize()
    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_normalize); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 130, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_5 = NULL;
    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_1))) {
      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_1);
      if (likely(__pyx_t_5)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
        __Pyx_INCREF(__pyx_t_5);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_1, function);
      }
    }
    if (__pyx_t_5) {
      __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 130, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    } else {
      __pyx_t_6 = __Pyx_PyObject_CallNoArg(__pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 130, __pyx_L1_error)
    }
    __Pyx_GOTREF(__pyx_t_6);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+131: 		del rules, lexicon
  __Pyx_DECREF(__pyx_v_rules);
  __pyx_v_rules = NULL;
  __Pyx_DECREF(__pyx_v_lexicon);
  __pyx_v_lexicon = NULL;
 132: 
+133: 	def _convertrules(self, bytes rules):
/* Python wrapper */
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_5_convertrules(PyObject *__pyx_v_self, PyObject *__pyx_v_rules); /*proto*/
static char __pyx_doc_8discodop_10containers_7Grammar_4_convertrules[] = "Grammar._convertrules(self, bytes rules)\nCount unary & binary rules; make a canonical list of all\n\t\tnon-terminal labels and assign them unique IDs.";
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_5_convertrules(PyObject *__pyx_v_self, PyObject *__pyx_v_rules) {
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_convertrules (wrapper)", 0);
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rules), (&PyBytes_Type), 1, "rules", 1))) __PYX_ERR(0, 133, __pyx_L1_error)
  __pyx_r = __pyx_pf_8discodop_10containers_7Grammar_4_convertrules(((struct __pyx_obj_8discodop_10containers_Grammar *)__pyx_v_self), ((PyObject*)__pyx_v_rules));

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_8discodop_10containers_7Grammar_4_convertrules(struct __pyx_obj_8discodop_10containers_Grammar *__pyx_v_self, PyObject *__pyx_v_rules) {
  uint32_t __pyx_v_n;
  uint32_t __pyx_v_m;
  Prob __pyx_v_w;
  ProbRule __pyx_v_cur;
  Rule __pyx_v_key;
  std::string __pyx_v_yf;
  std::string __pyx_v_weight;
  uint8_t __pyx_v_fanout;
  uint8_t __pyx_v_rhs1fanout;
  uint8_t __pyx_v_rhs2fanout;
  char const *__pyx_v_buf;
  char const *__pyx_v_prev;
  std::vector<std::string>  __pyx_v_fields;
  std::vector<std::string>  __pyx_v_rule;
  PyObject *__pyx_v_Epsilon = NULL;
  PyObject *__pyx_v_root = NULL;
  char __pyx_v_a;
  spp::sparse_hash_map<std::string,Label> ::iterator __pyx_v_it;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_convertrules", 0);
/* … */
  /* function exit code */
  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_9);
  __Pyx_XDECREF(__pyx_t_10);
  __Pyx_XDECREF(__pyx_t_11);
  __Pyx_XDECREF(__pyx_t_15);
  __Pyx_AddTraceback("discodop.containers.Grammar._convertrules", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_Epsilon);
  __Pyx_XDECREF(__pyx_v_root);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 134: 		"""Count unary & binary rules; make a canonical list of all
 135: 		non-terminal labels and assign them unique IDs."""
+136: 		cdef uint32_t n = 0, m
  __pyx_v_n = 0;
 137: 		cdef Prob w
 138: 		cdef ProbRule cur
 139: 		cdef Rule key
+140: 		cdef string yf = b'<none>'
  __pyx_t_1 = __pyx_convert_string_from_py_std__in_string(__pyx_kp_b_none); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 140, __pyx_L1_error)
  __pyx_v_yf = __pyx_t_1;
 141: 		cdef string weight
+142: 		cdef uint8_t fanout = 1, rhs1fanout = 1, rhs2fanout = 1
  __pyx_v_fanout = 1;
  __pyx_v_rhs1fanout = 1;
  __pyx_v_rhs2fanout = 1;
+143: 		cdef const char *buf = <const char*>rules
  __pyx_t_2 = __Pyx_PyObject_AsString(__pyx_v_rules); if (unlikely((!__pyx_t_2) && PyErr_Occurred())) __PYX_ERR(0, 143, __pyx_L1_error)
  __pyx_v_buf = ((char const *)__pyx_t_2);
 144: 		cdef const char *prev
 145: 		cdef vector[string] fields
 146: 		cdef vector[string] rule
 147: 		# Epsilon gets ID 0, only occurs implicitly in RHS of lexical rules.
+148: 		Epsilon = b'Epsilon'
  __Pyx_INCREF(__pyx_n_b_Epsilon);
  __pyx_v_Epsilon = __pyx_n_b_Epsilon;
+149: 		root = self.start.encode('utf8')
  if (unlikely(__pyx_v_self->start == Py_None)) {
    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "encode");
    __PYX_ERR(0, 149, __pyx_L1_error)
  }
  __pyx_t_3 = PyUnicode_AsUTF8String(__pyx_v_self->start); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 149, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_v_root = __pyx_t_3;
  __pyx_t_3 = 0;
+150: 		self.toid.ob[Epsilon] = 0
  __pyx_t_1 = __pyx_convert_string_from_py_std__in_string(__pyx_v_Epsilon); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 150, __pyx_L1_error)
  (__pyx_v_self->toid->ob[__pyx_t_1]) = 0;
+151: 		self.toid.ob[root] = 1
  __pyx_t_1 = __pyx_convert_string_from_py_std__in_string(__pyx_v_root); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 151, __pyx_L1_error)
  (__pyx_v_self->toid->ob[__pyx_t_1]) = 1;
+152: 		self.tolabel.ob.push_back(Epsilon)
  __pyx_t_1 = __pyx_convert_string_from_py_std__in_string(__pyx_v_Epsilon); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 152, __pyx_L1_error)
  try {
    __pyx_v_self->tolabel->ob.push_back(__pyx_t_1);
  } catch(...) {
    __Pyx_CppExn2PyErr();
    __PYX_ERR(0, 152, __pyx_L1_error)
  }
+153: 		self.tolabel.ob.push_back(root)
  __pyx_t_1 = __pyx_convert_string_from_py_std__in_string(__pyx_v_root); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 153, __pyx_L1_error)
  try {
    __pyx_v_self->tolabel->ob.push_back(__pyx_t_1);
  } catch(...) {
    __Pyx_CppExn2PyErr();
    __PYX_ERR(0, 153, __pyx_L1_error)
  }
+154: 		self.fanout.push_back(0)
  try {
    __pyx_v_self->fanout.push_back(0);
  } catch(...) {
    __Pyx_CppExn2PyErr();
    __PYX_ERR(0, 154, __pyx_L1_error)
  }
+155: 		self.fanout.push_back(1)
  try {
    __pyx_v_self->fanout.push_back(1);
  } catch(...) {
    __Pyx_CppExn2PyErr();
    __PYX_ERR(0, 155, __pyx_L1_error)
  }
+156: 		while True:
  while (1) {
+157: 			fields.clear()
    __pyx_v_fields.clear();
+158: 			prev = buf
    __pyx_v_prev = __pyx_v_buf;
+159: 			buf = readfields(buf, fields)
    __pyx_v_buf = __pyx_f_8discodop_10containers_readfields(__pyx_v_buf, __pyx_v_fields);
+160: 			if buf is NULL:
    __pyx_t_4 = ((__pyx_v_buf == NULL) != 0);
    if (__pyx_t_4) {
/* … */
    }
+161: 				break
      goto __pyx_L4_break;
+162: 			elif fields.size() == 0:
    __pyx_t_4 = ((__pyx_v_fields.size() == 0) != 0);
    if (__pyx_t_4) {
/* … */
    }
+163: 				continue
      goto __pyx_L3_continue;
+164: 			if self.bitpar:
    __pyx_t_4 = (__pyx_v_self->bitpar != 0);
    if (__pyx_t_4) {
/* … */
      goto __pyx_L6;
    }
+165: 				weight = fields[0]
      __pyx_v_weight = (__pyx_v_fields[0]);
+166: 				fields.erase(fields.begin())
      __pyx_v_fields.erase(__pyx_v_fields.begin());
+167: 				rule = fields
      __pyx_v_rule = __pyx_v_fields;
 168: 				# NB: leave yf at b'<none>'
+169: 				if rule.size() > 1:
      __pyx_t_4 = ((__pyx_v_rule.size() > 1) != 0);
      if (__pyx_t_4) {
/* … */
        goto __pyx_L7;
      }
+170: 					cur.args, cur.lengths = 0b10, 0b10
        __pyx_t_5 = 2;
        __pyx_t_6 = 2;
        __pyx_v_cur.args = __pyx_t_5;
        __pyx_v_cur.lengths = __pyx_t_6;
 171: 				else:
+172: 					cur.args, cur.lengths = 0b0, 0b1
      /*else*/ {
        __pyx_t_6 = 0;
        __pyx_t_5 = 1;
        __pyx_v_cur.args = __pyx_t_6;
        __pyx_v_cur.lengths = __pyx_t_5;
      }
      __pyx_L7:;
 173: 			else:
+174: 				weight = fields[fields.size() - 1]
    /*else*/ {
      __pyx_v_weight = (__pyx_v_fields[(__pyx_v_fields.size() - 1)]);
+175: 				yf = fields[fields.size() - 2]
      __pyx_v_yf = (__pyx_v_fields[(__pyx_v_fields.size() - 2)]);
+176: 				fields.pop_back()
      __pyx_v_fields.pop_back();
+177: 				fields.pop_back()
      __pyx_v_fields.pop_back();
+178: 				rule = fields
      __pyx_v_rule = __pyx_v_fields;
+179: 				cur.lengths = cur.args = m = 0
      __pyx_v_cur.lengths = 0;
      __pyx_v_cur.args = 0;
      __pyx_v_m = 0;
+180: 				fanout = 1
      __pyx_v_fanout = 1;
+181: 				rhs1fanout = rhs2fanout = 0
      __pyx_v_rhs1fanout = 0;
      __pyx_v_rhs2fanout = 0;
+182: 				for a in yf:
      __pyx_t_7 = __pyx_v_yf.begin();
      for (;;) {
        if (!(__pyx_t_7 != __pyx_v_yf.end())) break;
        __pyx_t_8 = *__pyx_t_7;
        ++__pyx_t_7;
        __pyx_v_a = __pyx_t_8;
/* … */
        __pyx_L8_continue:;
      }
+183: 					if a == b',':
        switch (__pyx_v_a) {
          case ',':
/* … */
          break;
+184: 						cur.lengths |= 1 << (m - 1)
          __pyx_v_cur.lengths = (__pyx_v_cur.lengths | (1 << (__pyx_v_m - 1)));
+185: 						fanout += 1
          __pyx_v_fanout = (__pyx_v_fanout + 1);
+186: 						continue
          goto __pyx_L8_continue;
+187: 					elif a == b'0':
          case '0':
/* … */
          break;
+188: 						rhs1fanout += 1
          __pyx_v_rhs1fanout = (__pyx_v_rhs1fanout + 1);
+189: 					elif a == b'1':
          case '1':
/* … */
          break;
          default:
+190: 						cur.args += 1 << m
          __pyx_v_cur.args = (__pyx_v_cur.args + (1 << __pyx_v_m));
+191: 						rhs2fanout += 1
          __pyx_v_rhs2fanout = (__pyx_v_rhs2fanout + 1);
 192: 					else:
+193: 						raise ValueError('invalid symbol in yield function: %r'
          __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 193, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_10);
          __Pyx_GIVEREF(__pyx_t_9);
          PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_9);
          __pyx_t_9 = 0;
          __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_10, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 193, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_9);
          __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
          __Pyx_Raise(__pyx_t_9, 0, 0, 0);
          __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
          __PYX_ERR(0, 193, __pyx_L1_error)
          break;
        }
+194: 								' (not in set [01,])\n%s' % (
          __pyx_t_9 = PyUnicode_Format(__pyx_kp_u_invalid_symbol_in_yield_function, __pyx_t_10); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 194, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_9);
          __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+195: 								a, prev[:buf - prev].decode('utf8')))
          __pyx_t_3 = __Pyx_PyInt_From_char(__pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 195, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_3);
          __pyx_t_9 = __Pyx_decode_c_string(__pyx_v_prev, 0, (__pyx_v_buf - __pyx_v_prev), NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 195, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_9);
          __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 195, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_10);
          __Pyx_GIVEREF(__pyx_t_3);
          PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_3);
          __Pyx_GIVEREF(__pyx_t_9);
          PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_t_9);
          __pyx_t_3 = 0;
          __pyx_t_9 = 0;
+196: 					m += 1
        __pyx_v_m = (__pyx_v_m + 1);
+197: 				cur.lengths |= 1 << (m - 1)
      __pyx_v_cur.lengths = (__pyx_v_cur.lengths | (1 << (__pyx_v_m - 1)));
+198: 				if m >= (8 * sizeof(cur.args)):
      __pyx_t_4 = ((__pyx_v_m >= (8 * (sizeof(__pyx_v_cur.args)))) != 0);
      if (__pyx_t_4) {
/* … */
      }
+199: 					raise ValueError(
        __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 199, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_11);
        __Pyx_GIVEREF(__pyx_t_3);
        PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_3);
        __pyx_t_3 = 0;
        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_11, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 199, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_3);
        __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
        __Pyx_Raise(__pyx_t_3, 0, 0, 0);
        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
        __PYX_ERR(0, 199, __pyx_L1_error)
 200: 							'Parsing complexity (%d) too high (max %d).\n'
+201: 							'Rule: %s' % (m, (8 * sizeof(cur.args)),
        __pyx_t_9 = __Pyx_PyInt_From_uint32_t(__pyx_v_m); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 201, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_9);
        __pyx_t_10 = __Pyx_PyInt_FromSize_t((8 * (sizeof(__pyx_v_cur.args)))); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 201, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_10);
/* … */
        __pyx_t_11 = PyTuple_New(3); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 201, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_11);
        __Pyx_GIVEREF(__pyx_t_9);
        PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_9);
        __Pyx_GIVEREF(__pyx_t_10);
        PyTuple_SET_ITEM(__pyx_t_11, 1, __pyx_t_10);
        __Pyx_GIVEREF(__pyx_t_3);
        PyTuple_SET_ITEM(__pyx_t_11, 2, __pyx_t_3);
        __pyx_t_9 = 0;
        __pyx_t_10 = 0;
        __pyx_t_3 = 0;
        __pyx_t_3 = PyUnicode_Format(__pyx_kp_u_Parsing_complexity_d_too_high_ma, __pyx_t_11); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 201, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_3);
        __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+202: 							prev[:buf - prev].decode('utf8')))
        __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_prev, 0, (__pyx_v_buf - __pyx_v_prev), NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 202, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_3);
+203: 				if rule.size() == 2:
      __pyx_t_4 = ((__pyx_v_rule.size() == 2) != 0);
      if (__pyx_t_4) {
/* … */
        goto __pyx_L11;
      }
 204: 					# if not YFUNARYRE.match(yf):
+205: 					if rhs1fanout == 0 or rhs2fanout != 0:
        __pyx_t_12 = ((__pyx_v_rhs1fanout == 0) != 0);
        if (!__pyx_t_12) {
        } else {
          __pyx_t_4 = __pyx_t_12;
          goto __pyx_L13_bool_binop_done;
        }
        __pyx_t_12 = ((__pyx_v_rhs2fanout != 0) != 0);
        __pyx_t_4 = __pyx_t_12;
        __pyx_L13_bool_binop_done:;
        if (__pyx_t_4) {
/* … */
        }
+206: 						raise ValueError('expected unary yield function: '
          __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 206, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_10);
          __Pyx_GIVEREF(__pyx_t_11);
          PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_11);
          __pyx_t_11 = 0;
          __pyx_t_11 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_10, NULL); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 206, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_11);
          __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
          __Pyx_Raise(__pyx_t_11, 0, 0, 0);
          __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
          __PYX_ERR(0, 206, __pyx_L1_error)
+207: 								'%r\t%r' % (yf, rule))
          __pyx_t_3 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_yf); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 207, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_3);
          __pyx_t_11 = __pyx_convert_vector_to_py_std_3a__3a_string(__pyx_v_rule); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 207, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_11);
          __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 207, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_10);
          __Pyx_GIVEREF(__pyx_t_3);
          PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_3);
          __Pyx_GIVEREF(__pyx_t_11);
          PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_t_11);
          __pyx_t_3 = 0;
          __pyx_t_11 = 0;
          __pyx_t_11 = PyUnicode_Format(__pyx_kp_u_expected_unary_yield_function_r, __pyx_t_10); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 207, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_11);
          __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+208: 				elif rule.size() == 3:
      __pyx_t_4 = ((__pyx_v_rule.size() == 3) != 0);
      if (__pyx_t_4) {
/* … */
      }
      __pyx_L11:;
    }
    __pyx_L6:;
 209: 					# if not YFBINARY.match(yf):
+210: 					if rhs1fanout == 0 or rhs2fanout == 0:
        __pyx_t_12 = ((__pyx_v_rhs1fanout == 0) != 0);
        if (!__pyx_t_12) {
        } else {
          __pyx_t_4 = __pyx_t_12;
          goto __pyx_L16_bool_binop_done;
        }
        __pyx_t_12 = ((__pyx_v_rhs2fanout == 0) != 0);
        __pyx_t_4 = __pyx_t_12;
        __pyx_L16_bool_binop_done:;
        if (__pyx_t_4) {
/* … */
        }
+211: 						raise ValueError('expected binary yield function: '
          __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 211, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_3);
          __Pyx_GIVEREF(__pyx_t_10);
          PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_10);
          __pyx_t_10 = 0;
          __pyx_t_10 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 211, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_10);
          __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
          __Pyx_Raise(__pyx_t_10, 0, 0, 0);
          __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
          __PYX_ERR(0, 211, __pyx_L1_error)
+212: 								'%r\t%r' % (yf, rule))
          __pyx_t_11 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_yf); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 212, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_11);
          __pyx_t_10 = __pyx_convert_vector_to_py_std_3a__3a_string(__pyx_v_rule); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 212, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_10);
          __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 212, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_3);
          __Pyx_GIVEREF(__pyx_t_11);
          PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_11);
          __Pyx_GIVEREF(__pyx_t_10);
          PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_10);
          __pyx_t_11 = 0;
          __pyx_t_10 = 0;
          __pyx_t_10 = PyUnicode_Format(__pyx_kp_u_expected_binary_yield_function_r, __pyx_t_3); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 212, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_10);
          __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 213: 					# if b'0' not in yf or b'1' not in yf:
 214: 					# 	raise ValueError('mismatch between non-terminals and '
 215: 					# 			'yield function: %s' %
 216: 					# 			prev[:buf - prev].decode('utf8'))
+217: 			it = self.toid.ob.find(rule[0])
    __pyx_v_it = __pyx_v_self->toid->ob.find((__pyx_v_rule[0]));
+218: 			if it == self.toid.ob.end():
    __pyx_t_4 = ((__pyx_v_it == __pyx_v_self->toid->ob.end()) != 0);
    if (__pyx_t_4) {
/* … */
      goto __pyx_L18;
    }
+219: 				cur.lhs = self.toid.ob[rule[0]] = self.tolabel.ob.size()
      __pyx_t_13 = __pyx_v_self->tolabel->ob.size();
      __pyx_v_cur.lhs = __pyx_t_13;
      (__pyx_v_self->toid->ob[(__pyx_v_rule[0])]) = __pyx_t_13;
+220: 				self.tolabel.ob.push_back(rule[0])
      try {
        __pyx_v_self->tolabel->ob.push_back((__pyx_v_rule[0]));
      } catch(...) {
        __Pyx_CppExn2PyErr();
        __PYX_ERR(0, 220, __pyx_L1_error)
      }
+221: 				self.fanout.push_back(fanout)
      try {
        __pyx_v_self->fanout.push_back(__pyx_v_fanout);
      } catch(...) {
        __Pyx_CppExn2PyErr();
        __PYX_ERR(0, 221, __pyx_L1_error)
      }
+222: 				if fanout > self.maxfanout:
      __pyx_t_4 = ((__pyx_v_fanout > __pyx_v_self->maxfanout) != 0);
      if (__pyx_t_4) {
/* … */
      }
+223: 					self.maxfanout = fanout
        __pyx_v_self->maxfanout = __pyx_v_fanout;
 224: 			else:
+225: 				cur.lhs = dereference(it).second
    /*else*/ {
      __pyx_t_14 = (*__pyx_v_it).second;
      __pyx_v_cur.lhs = __pyx_t_14;
+226: 				if self.fanout[cur.lhs] != fanout:
      __pyx_t_4 = (((__pyx_v_self->fanout[__pyx_v_cur.lhs]) != __pyx_v_fanout) != 0);
      if (__pyx_t_4) {
/* … */
      }
    }
    __pyx_L18:;
+227: 					raise ValueError("conflicting fanouts for symbol "
        __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 227, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_15);
        __Pyx_GIVEREF(__pyx_t_9);
        PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_t_9);
        __pyx_t_9 = 0;
        __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_15, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 227, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_9);
        __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
        __Pyx_Raise(__pyx_t_9, 0, 0, 0);
        __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
        __PYX_ERR(0, 227, __pyx_L1_error)
 228: 						"%r.\nprevious: %d; this non-terminal: %d. rule:\n%s"
+229: 						% (rule[0], self.fanout[cur.lhs], fanout,
        __pyx_t_10 = __pyx_convert_PyBytes_string_to_py_std__in_string((__pyx_v_rule[0])); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 229, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_10);
        __pyx_t_3 = __Pyx_PyInt_From_uint8_t((__pyx_v_self->fanout[__pyx_v_cur.lhs])); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 229, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_3);
        __pyx_t_11 = __Pyx_PyInt_From_uint8_t(__pyx_v_fanout); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 229, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_11);
/* … */
        __pyx_t_15 = PyTuple_New(4); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 229, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_15);
        __Pyx_GIVEREF(__pyx_t_10);
        PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_t_10);
        __Pyx_GIVEREF(__pyx_t_3);
        PyTuple_SET_ITEM(__pyx_t_15, 1, __pyx_t_3);
        __Pyx_GIVEREF(__pyx_t_11);
        PyTuple_SET_ITEM(__pyx_t_15, 2, __pyx_t_11);
        __Pyx_GIVEREF(__pyx_t_9);
        PyTuple_SET_ITEM(__pyx_t_15, 3, __pyx_t_9);
        __pyx_t_10 = 0;
        __pyx_t_3 = 0;
        __pyx_t_11 = 0;
        __pyx_t_9 = 0;
        __pyx_t_9 = PyUnicode_Format(__pyx_kp_u_conflicting_fanouts_for_symbol_r, __pyx_t_15); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 229, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_9);
        __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
+230: 						prev[:buf - prev].decode('utf8')))
        __pyx_t_9 = __Pyx_decode_c_string(__pyx_v_prev, 0, (__pyx_v_buf - __pyx_v_prev), NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 230, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_9);
+231: 			it = self.toid.ob.find(rule[1])
    __pyx_v_it = __pyx_v_self->toid->ob.find((__pyx_v_rule[1]));
+232: 			if it == self.toid.ob.end():
    __pyx_t_4 = ((__pyx_v_it == __pyx_v_self->toid->ob.end()) != 0);
    if (__pyx_t_4) {
/* … */
      goto __pyx_L21;
    }
+233: 				cur.rhs1 = self.toid.ob[rule[1]] = self.tolabel.ob.size()
      __pyx_t_13 = __pyx_v_self->tolabel->ob.size();
      __pyx_v_cur.rhs1 = __pyx_t_13;
      (__pyx_v_self->toid->ob[(__pyx_v_rule[1])]) = __pyx_t_13;
+234: 				self.tolabel.ob.push_back(rule[1])
      try {
        __pyx_v_self->tolabel->ob.push_back((__pyx_v_rule[1]));
      } catch(...) {
        __Pyx_CppExn2PyErr();
        __PYX_ERR(0, 234, __pyx_L1_error)
      }
+235: 				self.fanout.push_back(rhs1fanout)
      try {
        __pyx_v_self->fanout.push_back(__pyx_v_rhs1fanout);
      } catch(...) {
        __Pyx_CppExn2PyErr();
        __PYX_ERR(0, 235, __pyx_L1_error)
      }
 236: 			else:
+237: 				cur.rhs1 = dereference(it).second
    /*else*/ {
      __pyx_t_14 = (*__pyx_v_it).second;
      __pyx_v_cur.rhs1 = __pyx_t_14;
    }
    __pyx_L21:;
+238: 			if cur.lhs == 0 or cur.rhs1 == 0:
    __pyx_t_12 = ((__pyx_v_cur.lhs == 0) != 0);
    if (!__pyx_t_12) {
    } else {
      __pyx_t_4 = __pyx_t_12;
      goto __pyx_L23_bool_binop_done;
    }
    __pyx_t_12 = ((__pyx_v_cur.rhs1 == 0) != 0);
    __pyx_t_4 = __pyx_t_12;
    __pyx_L23_bool_binop_done:;
    if (__pyx_t_4) {
/* … */
    }
+239: 				raise ValueError('Epsilon symbol may only occur '
      __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 239, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_9);
      __Pyx_GIVEREF(__pyx_t_15);
      PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_15);
      __pyx_t_15 = 0;
      __pyx_t_15 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_9, NULL); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 239, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_15);
      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
      __Pyx_Raise(__pyx_t_15, 0, 0, 0);
      __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
      __PYX_ERR(0, 239, __pyx_L1_error)
+240: 						'in RHS of lexical rules:\n%s' %
      __pyx_t_15 = PyUnicode_Format(__pyx_kp_u_Epsilon_symbol_may_only_occur_in, __pyx_t_9); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 240, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_15);
      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+241: 						prev[:buf - prev].decode('utf8'))
      __pyx_t_9 = __Pyx_decode_c_string(__pyx_v_prev, 0, (__pyx_v_buf - __pyx_v_prev), NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 241, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_9);
+242: 			if rule.size() == 2:
    __pyx_t_4 = ((__pyx_v_rule.size() == 2) != 0);
    if (__pyx_t_4) {
/* … */
      goto __pyx_L25;
    }
+243: 				self.numunary += 1
      __pyx_v_self->numunary = (__pyx_v_self->numunary + 1);
+244: 				cur.rhs2 = 0
      __pyx_v_cur.rhs2 = 0;
+245: 			elif rule.size() == 3:
    __pyx_t_4 = ((__pyx_v_rule.size() == 3) != 0);
    if (__pyx_t_4) {
/* … */
      goto __pyx_L25;
    }
+246: 				self.numbinary += 1
      __pyx_v_self->numbinary = (__pyx_v_self->numbinary + 1);
+247: 				it = self.toid.ob.find(rule[2])
      __pyx_v_it = __pyx_v_self->toid->ob.find((__pyx_v_rule[2]));
+248: 				if it == self.toid.ob.end():
      __pyx_t_4 = ((__pyx_v_it == __pyx_v_self->toid->ob.end()) != 0);
      if (__pyx_t_4) {
/* … */
        goto __pyx_L26;
      }
+249: 					cur.rhs2 = self.toid.ob[rule[2]] = self.tolabel.ob.size()
        __pyx_t_13 = __pyx_v_self->tolabel->ob.size();
        __pyx_v_cur.rhs2 = __pyx_t_13;
        (__pyx_v_self->toid->ob[(__pyx_v_rule[2])]) = __pyx_t_13;
+250: 					self.tolabel.ob.push_back(rule[2])
        try {
          __pyx_v_self->tolabel->ob.push_back((__pyx_v_rule[2]));
        } catch(...) {
          __Pyx_CppExn2PyErr();
          __PYX_ERR(0, 250, __pyx_L1_error)
        }
+251: 					self.fanout.push_back(rhs2fanout)
        try {
          __pyx_v_self->fanout.push_back(__pyx_v_rhs2fanout);
        } catch(...) {
          __Pyx_CppExn2PyErr();
          __PYX_ERR(0, 251, __pyx_L1_error)
        }
 252: 				else:
+253: 					cur.rhs2 = dereference(it).second
      /*else*/ {
        __pyx_t_14 = (*__pyx_v_it).second;
        __pyx_v_cur.rhs2 = __pyx_t_14;
      }
      __pyx_L26:;
+254: 				if cur.rhs2 == 0:
      __pyx_t_4 = ((__pyx_v_cur.rhs2 == 0) != 0);
      if (__pyx_t_4) {
/* … */
      }
+255: 					raise ValueError('Epsilon symbol may only occur '
        __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 255, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_15);
        __Pyx_GIVEREF(__pyx_t_9);
        PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_t_9);
        __pyx_t_9 = 0;
        __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_15, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 255, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_9);
        __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
        __Pyx_Raise(__pyx_t_9, 0, 0, 0);
        __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
        __PYX_ERR(0, 255, __pyx_L1_error)
 256: 							'in RHS of lexical rules:\n%s'
+257: 						% prev[:buf - prev].decode('utf8'))
        __pyx_t_15 = __Pyx_decode_c_string(__pyx_v_prev, 0, (__pyx_v_buf - __pyx_v_prev), NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 257, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_15);
        __pyx_t_9 = PyUnicode_Format(__pyx_kp_u_Epsilon_symbol_may_only_occur_in, __pyx_t_15); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 257, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_9);
        __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
+258: 			elif rule.size() < 2:
    __pyx_t_4 = ((__pyx_v_rule.size() < 2) != 0);
    if (__pyx_t_4) {
/* … */
    }
+259: 				raise ValueError('Not enough nonterminals:\n%s'
      __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 259, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_9);
      __Pyx_GIVEREF(__pyx_t_15);
      PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_15);
      __pyx_t_15 = 0;
      __pyx_t_15 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_9, NULL); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 259, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_15);
      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
      __Pyx_Raise(__pyx_t_15, 0, 0, 0);
      __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
      __PYX_ERR(0, 259, __pyx_L1_error)
+260: 						% prev[:buf - prev].decode('utf8'))
      __pyx_t_9 = __Pyx_decode_c_string(__pyx_v_prev, 0, (__pyx_v_buf - __pyx_v_prev), NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 260, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_9);
      __pyx_t_15 = PyUnicode_Format(__pyx_kp_u_Not_enough_nonterminals_s, __pyx_t_9); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 260, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_15);
      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
 261: 			else:
+262: 				raise ValueError('Grammar not binarized:\n%s'
    /*else*/ {
/* … */
      __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 262, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_15);
      __Pyx_GIVEREF(__pyx_t_9);
      PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_t_9);
      __pyx_t_9 = 0;
      __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_15, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 262, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_9);
      __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
      __Pyx_Raise(__pyx_t_9, 0, 0, 0);
      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
      __PYX_ERR(0, 262, __pyx_L1_error)
    }
    __pyx_L25:;
+263: 						% prev[:buf - prev].decode('utf8'))
      __pyx_t_15 = __Pyx_decode_c_string(__pyx_v_prev, 0, (__pyx_v_buf - __pyx_v_prev), NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 263, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_15);
      __pyx_t_9 = PyUnicode_Format(__pyx_kp_u_Grammar_not_binarized_s, __pyx_t_15); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 263, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_9);
      __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
+264: 			if cur.rhs1 == 1 or cur.rhs2 == 1:
    __pyx_t_12 = ((__pyx_v_cur.rhs1 == 1) != 0);
    if (!__pyx_t_12) {
    } else {
      __pyx_t_4 = __pyx_t_12;
      goto __pyx_L29_bool_binop_done;
    }
    __pyx_t_12 = ((__pyx_v_cur.rhs2 == 1) != 0);
    __pyx_t_4 = __pyx_t_12;
    __pyx_L29_bool_binop_done:;
    if (__pyx_t_4) {
/* … */
    }
+265: 				raise ValueError('Start symbol should only occur on LHS:\n%s'
      __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 265, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_9);
      __Pyx_GIVEREF(__pyx_t_15);
      PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_15);
      __pyx_t_15 = 0;
      __pyx_t_15 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_9, NULL); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 265, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_15);
      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
      __Pyx_Raise(__pyx_t_15, 0, 0, 0);
      __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
      __PYX_ERR(0, 265, __pyx_L1_error)
+266: 						% prev[:buf - prev].decode('utf8'))
      __pyx_t_9 = __Pyx_decode_c_string(__pyx_v_prev, 0, (__pyx_v_buf - __pyx_v_prev), NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 266, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_9);
      __pyx_t_15 = PyUnicode_Format(__pyx_kp_u_Start_symbol_should_only_occur_o, __pyx_t_9); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 266, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_15);
      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+267: 			w = convertweight(weight.c_str())
    __pyx_v_w = __pyx_f_8discodop_10containers_convertweight(__pyx_v_weight.c_str());
+268: 			if w <= 0:
    __pyx_t_4 = ((__pyx_v_w <= 0.0) != 0);
    if (__pyx_t_4) {
/* … */
    }
+269: 				raise ValueError('Expected positive non-zero weight\n%s'
      __pyx_t_15 = PyTuple_New(1); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 269, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_15);
      __Pyx_GIVEREF(__pyx_t_9);
      PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_t_9);
      __pyx_t_9 = 0;
      __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_15, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 269, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_9);
      __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
      __Pyx_Raise(__pyx_t_9, 0, 0, 0);
      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
      __PYX_ERR(0, 269, __pyx_L1_error)
+270: 						% prev[:buf - prev].decode('utf8'))
      __pyx_t_15 = __Pyx_decode_c_string(__pyx_v_prev, 0, (__pyx_v_buf - __pyx_v_prev), NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 270, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_15);
      __pyx_t_9 = PyUnicode_Format(__pyx_kp_u_Expected_positive_non_zero_weigh, __pyx_t_15); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 270, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_9);
      __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
+271: 			cur.no = n
    __pyx_v_cur.no = __pyx_v_n;
+272: 			cur.prob = fabs(log(w))
    __pyx_v_cur.prob = fabs(log(__pyx_v_w));
+273: 			self.buf.push_back(cur)
    try {
      __pyx_v_self->buf.push_back(__pyx_v_cur);
    } catch(...) {
      __Pyx_CppExn2PyErr();
      __PYX_ERR(0, 273, __pyx_L1_error)
    }
+274: 			self.defaultmodel.push_back(w)
    try {
      __pyx_v_self->defaultmodel.push_back(__pyx_v_w);
    } catch(...) {
      __Pyx_CppExn2PyErr();
      __PYX_ERR(0, 274, __pyx_L1_error)
    }
+275: 			key.lhs, key.rhs1, key.rhs2 = cur.lhs, cur.rhs1, cur.rhs2
    __pyx_t_14 = __pyx_v_cur.lhs;
    __pyx_t_16 = __pyx_v_cur.rhs1;
    __pyx_t_17 = __pyx_v_cur.rhs2;
    __pyx_v_key.lhs = __pyx_t_14;
    __pyx_v_key.rhs1 = __pyx_t_16;
    __pyx_v_key.rhs2 = __pyx_t_17;
+276: 			key.args, key.lengths = cur.args, cur.lengths
    __pyx_t_5 = __pyx_v_cur.args;
    __pyx_t_6 = __pyx_v_cur.lengths;
    __pyx_v_key.args = __pyx_t_5;
    __pyx_v_key.lengths = __pyx_t_6;
+277: 			self.rulenos[key] = n
    (__pyx_v_self->rulenos[__pyx_v_key]) = __pyx_v_n;
+278: 			n += 1
    __pyx_v_n = (__pyx_v_n + 1);
    __pyx_L3_continue:;
  }
  __pyx_L4_break:;
 279: 
+280: 		self.numrules = self.numunary + self.numbinary
  __pyx_v_self->numrules = (__pyx_v_self->numunary + __pyx_v_self->numbinary);
+281: 		self.phrasalnonterminals = self.toid.ob.size()
  __pyx_v_self->phrasalnonterminals = __pyx_v_self->toid->ob.size();
+282: 		if not self.numrules:
  __pyx_t_4 = ((!(__pyx_v_self->numrules != 0)) != 0);
  if (__pyx_t_4) {
/* … */
  }
+283: 			raise ValueError('No rules found')
    __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 283, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_9);
    __Pyx_Raise(__pyx_t_9, 0, 0, 0);
    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
    __PYX_ERR(0, 283, __pyx_L1_error)
/* … */
  __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_u_No_rules_found); if (unlikely(!__pyx_tuple__4)) __PYX_ERR(0, 283, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__4);
  __Pyx_GIVEREF(__pyx_tuple__4);
 284: 
+285: 	def _convertlexicon(self, bytes lexicon):
/* Python wrapper */
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_7_convertlexicon(PyObject *__pyx_v_self, PyObject *__pyx_v_lexicon); /*proto*/
static char __pyx_doc_8discodop_10containers_7Grammar_6_convertlexicon[] = "Grammar._convertlexicon(self, bytes lexicon)\n Make objects for lexical rules. ";
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_7_convertlexicon(PyObject *__pyx_v_self, PyObject *__pyx_v_lexicon) {
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_convertlexicon (wrapper)", 0);
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lexicon), (&PyBytes_Type), 1, "lexicon", 1))) __PYX_ERR(0, 285, __pyx_L1_error)
  __pyx_r = __pyx_pf_8discodop_10containers_7Grammar_6_convertlexicon(((struct __pyx_obj_8discodop_10containers_Grammar *)__pyx_v_self), ((PyObject*)__pyx_v_lexicon));

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_8discodop_10containers_7Grammar_6_convertlexicon(struct __pyx_obj_8discodop_10containers_Grammar *__pyx_v_self, PyObject *__pyx_v_lexicon) {
  int __pyx_v_x;
  Prob __pyx_v_w;
  char const *__pyx_v_buf;
  char const *__pyx_v_prev;
  std::vector<std::string>  __pyx_v_fields;
  std::string __pyx_v_tag;
  std::string __pyx_v_weight;
  std::string __pyx_v_word;
  LexicalRule __pyx_v_lexrule;
  uint32_t __pyx_v_lexruleno;
  std::vector<std::string> ::size_type __pyx_v_n;
  spp::sparse_hash_map<std::string,Label> ::iterator __pyx_v_it;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_convertlexicon", 0);
/* … */
  /* function exit code */
  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_AddTraceback("discodop.containers.Grammar._convertlexicon", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 286: 		""" Make objects for lexical rules. """
 287: 		cdef int x
 288: 		cdef Prob w
+289: 		cdef const char *buf = <const char*>lexicon
  __pyx_t_1 = __Pyx_PyObject_AsString(__pyx_v_lexicon); if (unlikely((!__pyx_t_1) && PyErr_Occurred())) __PYX_ERR(0, 289, __pyx_L1_error)
  __pyx_v_buf = ((char const *)__pyx_t_1);
 290: 		cdef const char *prev
 291: 		cdef vector[string] fields
 292: 		cdef string tag, weight
 293: 		cdef string word
 294: 		cdef LexicalRule lexrule
 295: 		cdef uint32_t lexruleno
 296: 
+297: 		while True:
  while (1) {
+298: 			fields.clear()
    __pyx_v_fields.clear();
+299: 			prev = buf
    __pyx_v_prev = __pyx_v_buf;
+300: 			buf = readfields(buf, fields)
    __pyx_v_buf = __pyx_f_8discodop_10containers_readfields(__pyx_v_buf, __pyx_v_fields);
+301: 			if buf is NULL:
    __pyx_t_2 = ((__pyx_v_buf == NULL) != 0);
    if (__pyx_t_2) {
/* … */
    }
+302: 				break
      goto __pyx_L4_break;
+303: 			elif fields.size() == 0:
    __pyx_t_2 = ((__pyx_v_fields.size() == 0) != 0);
    if (__pyx_t_2) {
/* … */
    }
+304: 				continue
      goto __pyx_L3_continue;
+305: 			elif fields.size() == 1:
    __pyx_t_2 = ((__pyx_v_fields.size() == 1) != 0);
    if (__pyx_t_2) {
/* … */
    }
+306: 				raise ValueError('Expected: word<TAB>tag1<SPACE>weight1...'
      __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 306, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_GIVEREF(__pyx_t_4);
      PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
      __pyx_t_4 = 0;
      __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 306, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      __Pyx_Raise(__pyx_t_4, 0, 0, 0);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      __PYX_ERR(0, 306, __pyx_L1_error)
+307: 						'Got: %r' % prev[:buf - prev].decode('utf8'))
      __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_prev, 0, (__pyx_v_buf - __pyx_v_prev), NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 307, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __pyx_t_4 = PyUnicode_Format(__pyx_kp_u_Expected_word_TAB_tag1_SPACE_wei, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 307, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+308: 			word = fields[0]
    __pyx_v_word = (__pyx_v_fields[0]);
+309: 			if self.lexicalbyword.find(word) != self.lexicalbyword.end():
    __pyx_t_2 = ((__pyx_v_self->lexicalbyword.find(__pyx_v_word) != __pyx_v_self->lexicalbyword.end()) != 0);
    if (__pyx_t_2) {
/* … */
    }
+310: 				raise ValueError('word %r appears more than once '
      __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 310, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_GIVEREF(__pyx_t_3);
      PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
      __pyx_t_3 = 0;
      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 310, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      __Pyx_Raise(__pyx_t_3, 0, 0, 0);
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      __PYX_ERR(0, 310, __pyx_L1_error)
+311: 						'in lexicon file' % unescape(word.decode('utf8')))
      __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_unescape); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 311, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __pyx_t_5 = __Pyx_decode_cpp_string(__pyx_v_word, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 311, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __pyx_t_6 = NULL;
      if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
        __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_3);
        if (likely(__pyx_t_6)) {
          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
          __Pyx_INCREF(__pyx_t_6);
          __Pyx_INCREF(function);
          __Pyx_DECREF_SET(__pyx_t_3, function);
        }
      }
      if (!__pyx_t_6) {
        __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 311, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
        __Pyx_GOTREF(__pyx_t_4);
      } else {
        #if CYTHON_FAST_PYCALL
        if (PyFunction_Check(__pyx_t_3)) {
          PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_5};
          __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 311, __pyx_L1_error)
          __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
          __Pyx_GOTREF(__pyx_t_4);
          __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
        } else
        #endif
        #if CYTHON_FAST_PYCCALL
        if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
          PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_5};
          __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 311, __pyx_L1_error)
          __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
          __Pyx_GOTREF(__pyx_t_4);
          __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
        } else
        #endif
        {
          __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 311, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_7);
          __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __pyx_t_6 = NULL;
          __Pyx_GIVEREF(__pyx_t_5);
          PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_5);
          __pyx_t_5 = 0;
          __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_7, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 311, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_4);
          __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
        }
      }
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      __pyx_t_3 = PyUnicode_Format(__pyx_kp_u_word_r_appears_more_than_once_in, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 311, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+312: 			for n in range(1, fields.size()):
    __pyx_t_8 = __pyx_v_fields.size();
    for (__pyx_t_9 = 1; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) {
      __pyx_v_n = __pyx_t_9;
+313: 				x = fields[n].find_first_of(ord(b' '))
      __pyx_v_x = (__pyx_v_fields[__pyx_v_n]).find_first_of(32);
+314: 				if x > fields[n].size():
      __pyx_t_2 = ((__pyx_v_x > (__pyx_v_fields[__pyx_v_n]).size()) != 0);
      if (__pyx_t_2) {
/* … */
      }
+315: 					raise ValueError('Expected: word<TAB>tag1<SPACE>weight1'
        __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 315, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_3);
        __Pyx_GIVEREF(__pyx_t_4);
        PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
        __pyx_t_4 = 0;
        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 315, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
        __Pyx_Raise(__pyx_t_4, 0, 0, 0);
        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
        __PYX_ERR(0, 315, __pyx_L1_error)
 316: 							'<TAB>tag2<SPACE>weight2...\n'
+317: 							'Got: %r' % prev[:buf - prev].decode('utf8'))
        __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_prev, 0, (__pyx_v_buf - __pyx_v_prev), NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 317, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_3);
        __pyx_t_4 = PyUnicode_Format(__pyx_kp_u_Expected_word_TAB_tag1_SPACE_wei_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 317, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+318: 				tag = string(fields[n].c_str(), x)
      try {
        __pyx_t_10 = std::string((__pyx_v_fields[__pyx_v_n]).c_str(), __pyx_v_x);
      } catch(...) {
        __Pyx_CppExn2PyErr();
        __PYX_ERR(0, 318, __pyx_L1_error)
      }
      __pyx_v_tag = __pyx_t_10;
+319: 				weight = string(fields[n].c_str() + x + 1)
      try {
        __pyx_t_10 = std::string((((__pyx_v_fields[__pyx_v_n]).c_str() + __pyx_v_x) + 1));
      } catch(...) {
        __Pyx_CppExn2PyErr();
        __PYX_ERR(0, 319, __pyx_L1_error)
      }
      __pyx_v_weight = __pyx_t_10;
+320: 				it = self.toid.ob.find(tag)
      __pyx_v_it = __pyx_v_self->toid->ob.find(__pyx_v_tag);
+321: 				if it == self.toid.ob.end():
      __pyx_t_2 = ((__pyx_v_it == __pyx_v_self->toid->ob.end()) != 0);
      if (__pyx_t_2) {
/* … */
        goto __pyx_L10;
      }
+322: 					self.toid.ob[tag] = self.tolabel.ob.size()
        (__pyx_v_self->toid->ob[__pyx_v_tag]) = __pyx_v_self->tolabel->ob.size();
+323: 					self.tolabel.ob.push_back(tag)
        try {
          __pyx_v_self->tolabel->ob.push_back(__pyx_v_tag);
        } catch(...) {
          __Pyx_CppExn2PyErr();
          __PYX_ERR(0, 323, __pyx_L1_error)
        }
+324: 					self.fanout.push_back(1)
        try {
          __pyx_v_self->fanout.push_back(1);
        } catch(...) {
          __Pyx_CppExn2PyErr();
          __PYX_ERR(0, 324, __pyx_L1_error)
        }
 325: 					# disabled because we add ids for labels on the fly:
 326: 					# logging.warning('POS tag %r for word %r not used in any '
 327: 					# 		'phrasal rule', tag, word.decode('utf8'))
 328: 					# continue
 329: 				else:
+330: 					if self.fanout[dereference(it).second] != 1:
      /*else*/ {
        __pyx_t_2 = (((__pyx_v_self->fanout[(*__pyx_v_it).second]) != 1) != 0);
        if (__pyx_t_2) {
/* … */
        }
      }
      __pyx_L10:;
+331: 						raise ValueError('POS tag %r has fan-out %d, '
          __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 331, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_7);
          __Pyx_GIVEREF(__pyx_t_3);
          PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_3);
          __pyx_t_3 = 0;
          __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_7, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 331, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_3);
          __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
          __Pyx_Raise(__pyx_t_3, 0, 0, 0);
          __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
          __PYX_ERR(0, 331, __pyx_L1_error)
+332: 								'may only be 1.' % (
          __pyx_t_3 = PyUnicode_Format(__pyx_kp_u_POS_tag_r_has_fan_out_d_may_only, __pyx_t_7); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 332, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_3);
          __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+333: 								self.fanout[dereference(it).second], tag))
          __pyx_t_4 = __Pyx_PyInt_From_uint8_t((__pyx_v_self->fanout[(*__pyx_v_it).second])); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 333, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_4);
          __pyx_t_3 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_tag); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 333, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_3);
          __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 333, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_7);
          __Pyx_GIVEREF(__pyx_t_4);
          PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_4);
          __Pyx_GIVEREF(__pyx_t_3);
          PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_3);
          __pyx_t_4 = 0;
          __pyx_t_3 = 0;
+334: 				w = convertweight(weight.c_str())
      __pyx_v_w = __pyx_f_8discodop_10containers_convertweight(__pyx_v_weight.c_str());
+335: 				if w <= 0:
      __pyx_t_2 = ((__pyx_v_w <= 0.0) != 0);
      if (__pyx_t_2) {
/* … */
      }
+336: 					raise ValueError('weights should be positive '
        __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 336, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_3);
        __Pyx_GIVEREF(__pyx_t_7);
        PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_7);
        __pyx_t_7 = 0;
        __pyx_t_7 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 336, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_7);
        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
        __Pyx_Raise(__pyx_t_7, 0, 0, 0);
        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
        __PYX_ERR(0, 336, __pyx_L1_error)
 337: 							'and non-zero:\n%s'
+338: 							% prev[:buf - prev].decode('utf8'))
        __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_prev, 0, (__pyx_v_buf - __pyx_v_prev), NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 338, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_3);
        __pyx_t_7 = PyUnicode_Format(__pyx_kp_u_weights_should_be_positive_and_n, __pyx_t_3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 338, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_7);
        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+339: 				lexrule.prob = fabs(log(w))
      __pyx_v_lexrule.prob = fabs(log(__pyx_v_w));
+340: 				lexrule.lhs = self.toid.ob[tag]
      __pyx_v_lexrule.lhs = (__pyx_v_self->toid->ob[__pyx_v_tag]);
+341: 				lexruleno = self.lexical.size()
      __pyx_v_lexruleno = __pyx_v_self->lexical.size();
+342: 				self.defaultmodel.push_back(w)
      try {
        __pyx_v_self->defaultmodel.push_back(__pyx_v_w);
      } catch(...) {
        __Pyx_CppExn2PyErr();
        __PYX_ERR(0, 342, __pyx_L1_error)
      }
+343: 				self.lexical.push_back(lexrule)
      try {
        __pyx_v_self->lexical.push_back(__pyx_v_lexrule);
      } catch(...) {
        __Pyx_CppExn2PyErr();
        __PYX_ERR(0, 343, __pyx_L1_error)
      }
+344: 				self.lexicalbyword[word].push_back(lexruleno)
      try {
        (__pyx_v_self->lexicalbyword[__pyx_v_word]).push_back(__pyx_v_lexruleno);
      } catch(...) {
        __Pyx_CppExn2PyErr();
        __PYX_ERR(0, 344, __pyx_L1_error)
      }
+345: 				self.lexicalbylhs[lexrule.lhs][word] = lexruleno
      ((__pyx_v_self->lexicalbylhs[__pyx_v_lexrule.lhs])[__pyx_v_word]) = __pyx_v_lexruleno;
    }
+346: 			if self.lexical.size() == 0:
    __pyx_t_2 = ((__pyx_v_self->lexical.size() == 0) != 0);
    if (__pyx_t_2) {
/* … */
    }
    __pyx_L3_continue:;
  }
  __pyx_L4_break:;
+347: 				raise ValueError('no lexical rules found.')
      __pyx_t_7 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 347, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      __Pyx_Raise(__pyx_t_7, 0, 0, 0);
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      __PYX_ERR(0, 347, __pyx_L1_error)
/* … */
  __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_u_no_lexical_rules_found); if (unlikely(!__pyx_tuple__5)) __PYX_ERR(0, 347, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__5);
  __Pyx_GIVEREF(__pyx_tuple__5);
 348: 
+349: 	def _allocate(self):
/* Python wrapper */
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_9_allocate(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
static char __pyx_doc_8discodop_10containers_7Grammar_8_allocate[] = "Grammar._allocate(self)\nAllocate memory to store rules.";
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_9_allocate(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_allocate (wrapper)", 0);
  __pyx_r = __pyx_pf_8discodop_10containers_7Grammar_8_allocate(((struct __pyx_obj_8discodop_10containers_Grammar *)__pyx_v_self));

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_8discodop_10containers_7Grammar_8_allocate(struct __pyx_obj_8discodop_10containers_Grammar *__pyx_v_self) {
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_allocate", 0);
/* … */
  /* function exit code */
  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_AddTraceback("discodop.containers.Grammar._allocate", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 350: 		"""Allocate memory to store rules."""
 351: 		# store all non-lexical rules in a contiguous array
 352: 		# the other arrays will contain pointers to relevant parts thereof
 353: 		# (indexed on lhs, rhs1, and rhs2 of rules)
+354: 		self.bylhs = <ProbRule **>malloc(sizeof(ProbRule *)
  __pyx_v_self->bylhs = ((ProbRule **)malloc((((sizeof(ProbRule *)) * __pyx_v_self->nonterminals) * 4)));
 355: 				* self.nonterminals * 4)
+356: 		if self.bylhs is NULL:
  __pyx_t_1 = ((__pyx_v_self->bylhs == NULL) != 0);
  if (__pyx_t_1) {
/* … */
  }
+357: 			raise MemoryError('allocation error')
    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 357, __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_ERR(0, 357, __pyx_L1_error)
/* … */
  __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_u_allocation_error); if (unlikely(!__pyx_tuple__6)) __PYX_ERR(0, 357, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__6);
  __Pyx_GIVEREF(__pyx_tuple__6);
+358: 		self.bylhs[0] = NULL
  (__pyx_v_self->bylhs[0]) = NULL;
+359: 		self.unary = &(self.bylhs[1 * self.nonterminals])
  __pyx_v_self->unary = (&(__pyx_v_self->bylhs[(1 * __pyx_v_self->nonterminals)]));
+360: 		self.lbinary = &(self.bylhs[2 * self.nonterminals])
  __pyx_v_self->lbinary = (&(__pyx_v_self->bylhs[(2 * __pyx_v_self->nonterminals)]));
+361: 		self.rbinary = &(self.bylhs[3 * self.nonterminals])
  __pyx_v_self->rbinary = (&(__pyx_v_self->bylhs[(3 * __pyx_v_self->nonterminals)]));
 362: 		# allocate the actual contiguous array that will contain the rules
 363: 		# (plus sentinels)
 364: 		# self.bylhs[0] = <ProbRule *>malloc(sizeof(ProbRule) *
 365: 		# 	(self.numrules + (2 * self.numbinary) + self.numunary + 4))
 366: 		# if self.bylhs[0] is NULL:
 367: 		# 	raise MemoryError('allocation error')
+368: 		self.buf.resize(self.numrules + (2 * self.numbinary) + self.numunary + 4)
  try {
    __pyx_v_self->buf.resize((((__pyx_v_self->numrules + (2 * __pyx_v_self->numbinary)) + __pyx_v_self->numunary) + 4));
  } catch(...) {
    __Pyx_CppExn2PyErr();
    __PYX_ERR(0, 368, __pyx_L1_error)
  }
+369: 		self.bylhs[0] = &(self.buf[0])
  (__pyx_v_self->bylhs[0]) = (&(__pyx_v_self->buf[0]));
+370: 		self.unary[0] = &(self.bylhs[0][self.numrules + 1])
  (__pyx_v_self->unary[0]) = (&((__pyx_v_self->bylhs[0])[(__pyx_v_self->numrules + 1)]));
+371: 		self.lbinary[0] = &(self.unary[0][self.numunary + 1])
  (__pyx_v_self->lbinary[0]) = (&((__pyx_v_self->unary[0])[(__pyx_v_self->numunary + 1)]));
+372: 		self.rbinary[0] = &(self.lbinary[0][self.numbinary + 1])
  (__pyx_v_self->rbinary[0]) = (&((__pyx_v_self->lbinary[0])[(__pyx_v_self->numbinary + 1)]));
+373: 		self.mask = <uint64_t *>malloc(
  __pyx_v_self->mask = ((uint64_t *)malloc((BITNSLOTS(__pyx_v_self->numrules) * (sizeof(uint64_t)))));
 374: 				BITNSLOTS(self.numrules) * sizeof(uint64_t))
+375: 		if self.mask is NULL:
  __pyx_t_1 = ((__pyx_v_self->mask == NULL) != 0);
  if (__pyx_t_1) {
/* … */
  }
+376: 			raise MemoryError('allocation error')
    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 376, __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_ERR(0, 376, __pyx_L1_error)
/* … */
  __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_u_allocation_error); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(0, 376, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__7);
  __Pyx_GIVEREF(__pyx_tuple__7);
+377: 		self.setmask(None)
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_setmask); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 377, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 377, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
/* … */
  __pyx_tuple__8 = PyTuple_Pack(1, Py_None); if (unlikely(!__pyx_tuple__8)) __PYX_ERR(0, 377, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__8);
  __Pyx_GIVEREF(__pyx_tuple__8);
+378: 		self.revrulemap = <uint32_t *>malloc(self.numrules * sizeof(uint32_t))
  __pyx_v_self->revrulemap = ((uint32_t *)malloc((__pyx_v_self->numrules * (sizeof(uint32_t)))));
+379: 		if self.revrulemap is NULL:
  __pyx_t_1 = ((__pyx_v_self->revrulemap == NULL) != 0);
  if (__pyx_t_1) {
/* … */
  }
+380: 			raise MemoryError('allocation error')
    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 380, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __PYX_ERR(0, 380, __pyx_L1_error)
/* … */
  __pyx_tuple__9 = PyTuple_Pack(1, __pyx_kp_u_allocation_error); if (unlikely(!__pyx_tuple__9)) __PYX_ERR(0, 380, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__9);
  __Pyx_GIVEREF(__pyx_tuple__9);
 381: 
+382: 	def _normalize(self):
/* Python wrapper */
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_11_normalize(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
static char __pyx_doc_8discodop_10containers_7Grammar_10_normalize[] = "Grammar._normalize(self)\nOptionally normalize frequencies to relative frequencies.\n\t\tShould be run during initialization.";
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_11_normalize(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_normalize (wrapper)", 0);
  __pyx_r = __pyx_pf_8discodop_10containers_7Grammar_10_normalize(((struct __pyx_obj_8discodop_10containers_Grammar *)__pyx_v_self));

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_8discodop_10containers_7Grammar_10_normalize(struct __pyx_obj_8discodop_10containers_Grammar *__pyx_v_self) {
  double __pyx_v_mass;
  uint32_t __pyx_v_n;
  uint32_t __pyx_v_lhs;
  spp::sparse_hash_map<Label,spp::sparse_hash_map<std::string,uint32_t> > ::iterator __pyx_v_it;
  std::pair<std::string,uint32_t>  __pyx_v_x;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_normalize", 0);
/* … */
  /* function exit code */
  __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_11);
  __Pyx_XDECREF(__pyx_t_12);
  __Pyx_XDECREF(__pyx_t_14);
  __Pyx_AddTraceback("discodop.containers.Grammar._normalize", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 383: 		"""Optionally normalize frequencies to relative frequencies.
 384: 		Should be run during initialization."""
+385: 		cdef double mass = 0
  __pyx_v_mass = 0.0;
+386: 		cdef uint32_t n = 0, lhs
  __pyx_v_n = 0;
+387: 		logging.warning('normalizing weights.')
  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_logging); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 387, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_warning); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 387, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 387, __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;
/* … */
  __pyx_tuple__10 = PyTuple_Pack(1, __pyx_kp_u_normalizing_weights); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(0, 387, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__10);
  __Pyx_GIVEREF(__pyx_tuple__10);
+388: 		for lhs in range(self.nonterminals):
  __pyx_t_3 = __pyx_v_self->nonterminals;
  for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
    __pyx_v_lhs = __pyx_t_4;
+389: 			mass = 0
    __pyx_v_mass = 0.0;
+390: 			n = 0
    __pyx_v_n = 0;
+391: 			while self.bylhs[lhs][n].lhs == lhs:
    while (1) {
      __pyx_t_5 = ((((__pyx_v_self->bylhs[__pyx_v_lhs])[__pyx_v_n]).lhs == __pyx_v_lhs) != 0);
      if (!__pyx_t_5) break;
+392: 				mass += self.defaultmodel[self.bylhs[lhs][n].no]
      __pyx_v_mass = (__pyx_v_mass + (__pyx_v_self->defaultmodel[((__pyx_v_self->bylhs[__pyx_v_lhs])[__pyx_v_n]).no]));
+393: 				n += 1
      __pyx_v_n = (__pyx_v_n + 1);
    }
+394: 			it = self.lexicalbylhs.find(lhs)
    __pyx_v_it = __pyx_v_self->lexicalbylhs.find(__pyx_v_lhs);
+395: 			if it != self.lexicalbylhs.end():
    __pyx_t_5 = ((__pyx_v_it != __pyx_v_self->lexicalbylhs.end()) != 0);
    if (__pyx_t_5) {
/* … */
    }
+396: 				for x in dereference(it).second:
      __pyx_t_7 = &(*__pyx_v_it).second;
      __pyx_t_6 = __pyx_t_7->begin();
      for (;;) {
        if (!(__pyx_t_6 != __pyx_t_7->end())) break;
        __pyx_t_8 = *__pyx_t_6;
        ++__pyx_t_6;
        __pyx_v_x = __pyx_t_8;
/* … */
      }
+397: 					mass += self.defaultmodel[self.numrules + x.second]
        __pyx_v_mass = (__pyx_v_mass + (__pyx_v_self->defaultmodel[(__pyx_v_self->numrules + __pyx_v_x.second)]));
+398: 			n = 0
    __pyx_v_n = 0;
+399: 			while self.bylhs[lhs][n].lhs == lhs:
    while (1) {
      __pyx_t_5 = ((((__pyx_v_self->bylhs[__pyx_v_lhs])[__pyx_v_n]).lhs == __pyx_v_lhs) != 0);
      if (!__pyx_t_5) break;
+400: 				self.defaultmodel[self.bylhs[lhs][n].no] /= mass
      __pyx_t_9 = ((__pyx_v_self->bylhs[__pyx_v_lhs])[__pyx_v_n]).no;
      (__pyx_v_self->defaultmodel[__pyx_t_9]) = ((__pyx_v_self->defaultmodel[__pyx_t_9]) / __pyx_v_mass);
+401: 				n += 1
      __pyx_v_n = (__pyx_v_n + 1);
    }
+402: 			it = self.lexicalbylhs.find(lhs)
    __pyx_v_it = __pyx_v_self->lexicalbylhs.find(__pyx_v_lhs);
+403: 			if it != self.lexicalbylhs.end():
    __pyx_t_5 = ((__pyx_v_it != __pyx_v_self->lexicalbylhs.end()) != 0);
    if (__pyx_t_5) {
/* … */
    }
  }
+404: 				for x in dereference(it).second:
      __pyx_t_7 = &(*__pyx_v_it).second;
      __pyx_t_6 = __pyx_t_7->begin();
      for (;;) {
        if (!(__pyx_t_6 != __pyx_t_7->end())) break;
        __pyx_t_8 = *__pyx_t_6;
        ++__pyx_t_6;
        __pyx_v_x = __pyx_t_8;
/* … */
      }
+405: 					self.defaultmodel[self.numrules + x.second] /= mass
        __pyx_t_10 = (__pyx_v_self->numrules + __pyx_v_x.second);
        (__pyx_v_self->defaultmodel[__pyx_t_10]) = ((__pyx_v_self->defaultmodel[__pyx_t_10]) / __pyx_v_mass);
+406: 		self.currentmodel = None
  __Pyx_INCREF(Py_None);
  __Pyx_GIVEREF(Py_None);
  __Pyx_GOTREF(__pyx_v_self->currentmodel);
  __Pyx_DECREF(__pyx_v_self->currentmodel);
  __pyx_v_self->currentmodel = ((PyObject*)Py_None);
+407: 		self.switch('default', self.logprob)
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_switch); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 407, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_11 = __Pyx_PyBool_FromLong(__pyx_v_self->logprob); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 407, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_11);
  __pyx_t_12 = NULL;
  __pyx_t_13 = 0;
  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
    __pyx_t_12 = PyMethod_GET_SELF(__pyx_t_2);
    if (likely(__pyx_t_12)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
      __Pyx_INCREF(__pyx_t_12);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_2, function);
      __pyx_t_13 = 1;
    }
  }
  #if CYTHON_FAST_PYCALL
  if (PyFunction_Check(__pyx_t_2)) {
    PyObject *__pyx_temp[3] = {__pyx_t_12, __pyx_n_u_default, __pyx_t_11};
    __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_13, 2+__pyx_t_13); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 407, __pyx_L1_error)
    __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0;
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
  } else
  #endif
  #if CYTHON_FAST_PYCCALL
  if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
    PyObject *__pyx_temp[3] = {__pyx_t_12, __pyx_n_u_default, __pyx_t_11};
    __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_13, 2+__pyx_t_13); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 407, __pyx_L1_error)
    __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0;
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
  } else
  #endif
  {
    __pyx_t_14 = PyTuple_New(2+__pyx_t_13); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 407, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_14);
    if (__pyx_t_12) {
      __Pyx_GIVEREF(__pyx_t_12); PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_t_12); __pyx_t_12 = NULL;
    }
    __Pyx_INCREF(__pyx_n_u_default);
    __Pyx_GIVEREF(__pyx_n_u_default);
    PyTuple_SET_ITEM(__pyx_t_14, 0+__pyx_t_13, __pyx_n_u_default);
    __Pyx_GIVEREF(__pyx_t_11);
    PyTuple_SET_ITEM(__pyx_t_14, 1+__pyx_t_13, __pyx_t_11);
    __pyx_t_11 = 0;
    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_14, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 407, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
  }
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 408: 
+409: 	cdef _indexrules(Grammar self, ProbRule **dest, int idx, int filterlen):
static PyObject *__pyx_f_8discodop_10containers_7Grammar__indexrules(struct __pyx_obj_8discodop_10containers_Grammar *__pyx_v_self, ProbRule **__pyx_v_dest, int __pyx_v_idx, int __pyx_v_filterlen) {
  uint32_t __pyx_v_prev;
  uint32_t __pyx_v_idxlabel;
  uint32_t __pyx_v_n;
  uint32_t __pyx_v_m;
  ProbRule *__pyx_v_cur;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_indexrules", 0);
/* … */
  /* function exit code */
  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_AddTraceback("discodop.containers.Grammar._indexrules", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = 0;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 410: 		"""Auxiliary function to create Grammar objects. Copies certain
 411: 		grammar rules and sorts them on the given index.
 412: 		Resulting array is ordered by lhs, rhs1, or rhs2 depending on the value
 413: 		of `idx` (0, 1, or 2); filterlen can be 0, 2, or 3 to get all, only
 414: 		unary, or only binary rules, respectively.
 415: 		A separate array has a pointer for each non-terminal into this array;
 416: 		e.g.: dest[NP][0] == the first rule with an NP in the idx position."""
+417: 		cdef uint32_t prev = self.nonterminals, idxlabel = 0, n, m = 0
  __pyx_t_1 = __pyx_v_self->nonterminals;
  __pyx_v_prev = __pyx_t_1;
  __pyx_v_idxlabel = 0;
  __pyx_v_m = 0;
 418: 		cdef ProbRule *cur
 419: 		# need to set dest even when there are no rules for that idx
+420: 		for n in range(1, self.nonterminals):
  __pyx_t_1 = __pyx_v_self->nonterminals;
  for (__pyx_t_2 = 1; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
    __pyx_v_n = __pyx_t_2;
+421: 			dest[n] = dest[0]
    (__pyx_v_dest[__pyx_v_n]) = (__pyx_v_dest[0]);
  }
+422: 		if dest is self.bylhs:
  __pyx_t_3 = ((__pyx_v_dest == __pyx_v_self->bylhs) != 0);
  if (__pyx_t_3) {
/* … */
    goto __pyx_L5;
  }
+423: 			m = self.numrules
    __pyx_t_1 = __pyx_v_self->numrules;
    __pyx_v_m = __pyx_t_1;
 424: 		else:
+425: 			for n in range(self.numrules):
  /*else*/ {
    __pyx_t_1 = __pyx_v_self->numrules;
    for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
      __pyx_v_n = __pyx_t_2;
+426: 				if ((filterlen == 2 and self.bylhs[0][n].rhs2 == 0)
      __pyx_t_4 = ((__pyx_v_filterlen == 2) != 0);
      if (!__pyx_t_4) {
        goto __pyx_L10_next_or;
      } else {
      }
      __pyx_t_4 = ((((__pyx_v_self->bylhs[0])[__pyx_v_n]).rhs2 == 0) != 0);
      if (!__pyx_t_4) {
      } else {
        __pyx_t_3 = __pyx_t_4;
        goto __pyx_L9_bool_binop_done;
      }
      __pyx_L10_next_or:;
/* … */
      if (__pyx_t_3) {
/* … */
      }
    }
  }
  __pyx_L5:;
+427: 						or (filterlen == 3 and self.bylhs[0][n].rhs1
      __pyx_t_4 = ((__pyx_v_filterlen == 3) != 0);
      if (__pyx_t_4) {
      } else {
        __pyx_t_3 = __pyx_t_4;
        goto __pyx_L9_bool_binop_done;
      }
/* … */
      __pyx_t_4 = (((__pyx_v_self->bylhs[0])[__pyx_v_n]).rhs1 != 0);
      if (__pyx_t_4) {
      } else {
        __pyx_t_3 = __pyx_t_4;
        goto __pyx_L9_bool_binop_done;
      }
+428: 						and self.bylhs[0][n].rhs2)):
      __pyx_t_4 = (((__pyx_v_self->bylhs[0])[__pyx_v_n]).rhs2 != 0);
      __pyx_t_3 = __pyx_t_4;
      __pyx_L9_bool_binop_done:;
 429: 					# copy this rule
+430: 					dest[0][m] = self.bylhs[0][n]
        ((__pyx_v_dest[0])[__pyx_v_m]) = ((__pyx_v_self->bylhs[0])[__pyx_v_n]);
+431: 					assert dest[0][m].no < self.numrules
        #ifndef CYTHON_WITHOUT_ASSERTIONS
        if (unlikely(!Py_OptimizeFlag)) {
          if (unlikely(!((((__pyx_v_dest[0])[__pyx_v_m]).no < __pyx_v_self->numrules) != 0))) {
            PyErr_SetNone(PyExc_AssertionError);
            __PYX_ERR(0, 431, __pyx_L1_error)
          }
        }
        #endif
+432: 					m += 1
        __pyx_v_m = (__pyx_v_m + 1);
+433: 		if filterlen == 2:
  switch (__pyx_v_filterlen) {
    case 2:
/* … */
    break;
+434: 			assert m == self.numunary, (m, self.numunary)
    #ifndef CYTHON_WITHOUT_ASSERTIONS
    if (unlikely(!Py_OptimizeFlag)) {
      if (unlikely(!((__pyx_v_m == __pyx_v_self->numunary) != 0))) {
        __pyx_t_5 = __Pyx_PyInt_From_uint32_t(__pyx_v_m); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 434, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_5);
        __pyx_t_6 = __Pyx_PyInt_FromSize_t(__pyx_v_self->numunary); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 434, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_6);
        __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 434, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_7);
        __Pyx_GIVEREF(__pyx_t_5);
        PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5);
        __Pyx_GIVEREF(__pyx_t_6);
        PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_6);
        __pyx_t_5 = 0;
        __pyx_t_6 = 0;
        __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 434, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_6);
        __Pyx_GIVEREF(__pyx_t_7);
        PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_7);
        __pyx_t_7 = 0;
        PyErr_SetObject(PyExc_AssertionError, __pyx_t_6);
        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
        __PYX_ERR(0, 434, __pyx_L1_error)
      }
    }
    #endif
+435: 		elif filterlen == 3:
    case 3:
/* … */
    break;
    default: break;
  }
+436: 			assert m == self.numbinary, (m, self.numbinary)
    #ifndef CYTHON_WITHOUT_ASSERTIONS
    if (unlikely(!Py_OptimizeFlag)) {
      if (unlikely(!((__pyx_v_m == __pyx_v_self->numbinary) != 0))) {
        __pyx_t_6 = __Pyx_PyInt_From_uint32_t(__pyx_v_m); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 436, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_6);
        __pyx_t_7 = __Pyx_PyInt_FromSize_t(__pyx_v_self->numbinary); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 436, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_7);
        __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 436, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_5);
        __Pyx_GIVEREF(__pyx_t_6);
        PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_6);
        __Pyx_GIVEREF(__pyx_t_7);
        PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_7);
        __pyx_t_6 = 0;
        __pyx_t_7 = 0;
        __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 436, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_7);
        __Pyx_GIVEREF(__pyx_t_5);
        PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5);
        __pyx_t_5 = 0;
        PyErr_SetObject(PyExc_AssertionError, __pyx_t_7);
        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
        __PYX_ERR(0, 436, __pyx_L1_error)
      }
    }
    #endif
 437: 		# sort rules by idx (NB: qsort is not stable, use appropriate cmp func)
+438: 		if idx == 0:
  switch (__pyx_v_idx) {
    case 0:
/* … */
    break;
+439: 			qsort(dest[0], m, sizeof(ProbRule), &cmp0)
    qsort((__pyx_v_dest[0]), __pyx_v_m, (sizeof(ProbRule)), (&__pyx_f_8discodop_10containers_cmp0));
+440: 		elif idx == 1:
    case 1:
/* … */
    break;
+441: 			qsort(dest[0], m, sizeof(ProbRule), &cmp1)
    qsort((__pyx_v_dest[0]), __pyx_v_m, (sizeof(ProbRule)), (&__pyx_f_8discodop_10containers_cmp1));
+442: 		elif idx == 2:
    case 2:
/* … */
    break;
    default: break;
  }
+443: 			qsort(dest[0], m, sizeof(ProbRule), &cmp2)
    qsort((__pyx_v_dest[0]), __pyx_v_m, (sizeof(ProbRule)), (&__pyx_f_8discodop_10containers_cmp2));
 444: 		# make index: dest[NP] points to first rule with NP in index position
+445: 		for n in range(m):
  __pyx_t_2 = __pyx_v_m;
  for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_2; __pyx_t_8+=1) {
    __pyx_v_n = __pyx_t_8;
+446: 			cur = &(dest[0][n])
    __pyx_v_cur = (&((__pyx_v_dest[0])[__pyx_v_n]));
+447: 			if idx == 0:
    switch (__pyx_v_idx) {
      case 0:
/* … */
      break;
+448: 				idxlabel = cur.lhs
      __pyx_t_9 = __pyx_v_cur->lhs;
      __pyx_v_idxlabel = __pyx_t_9;
+449: 			elif idx == 1:
      case 1:
/* … */
      break;
+450: 				idxlabel = cur.rhs1
      __pyx_t_9 = __pyx_v_cur->rhs1;
      __pyx_v_idxlabel = __pyx_t_9;
+451: 			elif idx == 2:
      case 2:
/* … */
      break;
      default: break;
    }
+452: 				idxlabel = cur.rhs2
      __pyx_t_9 = __pyx_v_cur->rhs2;
      __pyx_v_idxlabel = __pyx_t_9;
+453: 			if idxlabel != prev:
    __pyx_t_3 = ((__pyx_v_idxlabel != __pyx_v_prev) != 0);
    if (__pyx_t_3) {
/* … */
    }
+454: 				dest[idxlabel] = cur
      (__pyx_v_dest[__pyx_v_idxlabel]) = __pyx_v_cur;
+455: 			prev = idxlabel
    __pyx_v_prev = __pyx_v_idxlabel;
+456: 			assert cur.no < self.numrules
    #ifndef CYTHON_WITHOUT_ASSERTIONS
    if (unlikely(!Py_OptimizeFlag)) {
      if (unlikely(!((__pyx_v_cur->no < __pyx_v_self->numrules) != 0))) {
        PyErr_SetNone(PyExc_AssertionError);
        __PYX_ERR(0, 456, __pyx_L1_error)
      }
    }
    #endif
  }
 457: 		# sentinel rule
+458: 		dest[0][m].lhs = dest[0][m].rhs1 = dest[0][m].rhs2 = self.nonterminals
  __pyx_t_1 = __pyx_v_self->nonterminals;
  ((__pyx_v_dest[0])[__pyx_v_m]).lhs = __pyx_t_1;
  ((__pyx_v_dest[0])[__pyx_v_m]).rhs1 = __pyx_t_1;
  ((__pyx_v_dest[0])[__pyx_v_m]).rhs2 = __pyx_t_1;
 459: 
+460: 	def switch(self, str name, bint logprob=True):
/* Python wrapper */
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_13switch(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_8discodop_10containers_7Grammar_12switch[] = "Grammar.switch(self, unicode name, bool logprob=True)";
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_13switch(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_name = 0;
  int __pyx_v_logprob;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("switch (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_name,&__pyx_n_s_logprob,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);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = PyDict_Size(__pyx_kwds);
      switch (pos_args) {
        case  0:
        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_name)) != 0)) kw_args--;
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (kw_args > 0) {
          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_logprob);
          if (value) { values[1] = value; kw_args--; }
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "switch") < 0)) __PYX_ERR(0, 460, __pyx_L3_error)
      }
    } else {
      switch (PyTuple_GET_SIZE(__pyx_args)) {
        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        break;
        default: goto __pyx_L5_argtuple_error;
      }
    }
    __pyx_v_name = ((PyObject*)values[0]);
    if (values[1]) {
      __pyx_v_logprob = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_logprob == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 460, __pyx_L3_error)
    } else {
      __pyx_v_logprob = ((int)1);
    }
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("switch", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 460, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("discodop.containers.Grammar.switch", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_name), (&PyUnicode_Type), 1, "name", 1))) __PYX_ERR(0, 460, __pyx_L1_error)
  __pyx_r = __pyx_pf_8discodop_10containers_7Grammar_12switch(((struct __pyx_obj_8discodop_10containers_Grammar *)__pyx_v_self), __pyx_v_name, __pyx_v_logprob);

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_8discodop_10containers_7Grammar_12switch(struct __pyx_obj_8discodop_10containers_Grammar *__pyx_v_self, PyObject *__pyx_v_name, int __pyx_v_logprob) {
  int __pyx_v_n;
  Prob *__pyx_v_tmp;
  __Pyx_memviewslice __pyx_v_ob = { 0, 0, { 0 }, { 0 }, { 0 } };
  size_t __pyx_v_numweights;
  PyObject *__pyx_v_model = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("switch", 0);
/* … */
  /* function exit code */
  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __PYX_XDEC_MEMVIEW(&__pyx_t_6, 1);
  __Pyx_XDECREF(__pyx_t_11);
  __Pyx_XDECREF(__pyx_t_12);
  __Pyx_XDECREF(__pyx_t_14);
  __Pyx_XDECREF(__pyx_t_15);
  __PYX_XDEC_MEMVIEW(&__pyx_t_16, 1);
  __Pyx_AddTraceback("discodop.containers.Grammar.switch", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __PYX_XDEC_MEMVIEW(&__pyx_v_ob, 1);
  __Pyx_XDECREF(__pyx_v_model);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 461: 		cdef int n
 462: 		cdef Prob *tmp
 463: 		cdef Prob [:] ob
+464: 		cdef size_t numweights = self.numrules + self.lexical.size()
  __pyx_v_numweights = (__pyx_v_self->numrules + __pyx_v_self->lexical.size());
+465: 		if self.currentmodel == name and self.logprob == logprob:
  __pyx_t_2 = (__Pyx_PyUnicode_Equals(__pyx_v_self->currentmodel, __pyx_v_name, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 465, __pyx_L1_error)
  __pyx_t_3 = (__pyx_t_2 != 0);
  if (__pyx_t_3) {
  } else {
    __pyx_t_1 = __pyx_t_3;
    goto __pyx_L4_bool_binop_done;
  }
  __pyx_t_3 = ((__pyx_v_self->logprob == __pyx_v_logprob) != 0);
  __pyx_t_1 = __pyx_t_3;
  __pyx_L4_bool_binop_done:;
  if (__pyx_t_1) {
/* … */
  }
+466: 			return
    __Pyx_XDECREF(__pyx_r);
    __pyx_r = Py_None; __Pyx_INCREF(Py_None);
    goto __pyx_L0;
+467: 		if name == 'default':
  __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_default, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 467, __pyx_L1_error)
  __pyx_t_3 = (__pyx_t_1 != 0);
  if (__pyx_t_3) {
/* … */
    goto __pyx_L6;
  }
+468: 			if logprob:
    __pyx_t_3 = (__pyx_v_logprob != 0);
    if (__pyx_t_3) {
/* … */
      goto __pyx_L7;
    }
 469: 				# cannot take typed memoryview of vector<Prob>
+470: 				ob = clone(dblarray, numweights, False)
      __pyx_t_4 = ((PyObject *)__pyx_v_8discodop_10containers_dblarray);
      __Pyx_INCREF(__pyx_t_4);
      __pyx_t_5 = ((PyObject *)__pyx_f_7cpython_5array_clone(((arrayobject *)__pyx_t_4), __pyx_v_numweights, 0)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 470, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      __pyx_t_6 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn_Prob(__pyx_t_5);
      if (unlikely(!__pyx_t_6.memview)) __PYX_ERR(0, 470, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      __pyx_v_ob = __pyx_t_6;
      __pyx_t_6.memview = NULL;
      __pyx_t_6.data = NULL;
+471: 				for n in range(numweights):
      __pyx_t_7 = __pyx_v_numweights;
      for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
        __pyx_v_n = __pyx_t_8;
+472: 					ob[n] = fabs(log(self.defaultmodel[n]))
        __pyx_t_9 = __pyx_v_n;
        *((Prob *) ( /* dim=0 */ (__pyx_v_ob.data + __pyx_t_9 * __pyx_v_ob.strides[0]) )) = fabs(log((__pyx_v_self->defaultmodel[__pyx_v_n])));
      }
+473: 				tmp = &(ob[0])
      __pyx_t_10 = 0;
      __pyx_v_tmp = (&(*((Prob *) ( /* dim=0 */ (__pyx_v_ob.data + __pyx_t_10 * __pyx_v_ob.strides[0]) ))));
 474: 			else:
+475: 				tmp = &(self.defaultmodel[0])
    /*else*/ {
      __pyx_v_tmp = (&(__pyx_v_self->defaultmodel[0]));
    }
    __pyx_L7:;
 476: 		else:
+477: 			if self.models is None and self.altweightsfile:
  /*else*/ {
    __pyx_t_1 = (__pyx_v_self->models == Py_None);
    __pyx_t_2 = (__pyx_t_1 != 0);
    if (__pyx_t_2) {
    } else {
      __pyx_t_3 = __pyx_t_2;
      goto __pyx_L11_bool_binop_done;
    }
    __pyx_t_2 = (__pyx_v_self->altweightsfile != Py_None) && (__Pyx_PyUnicode_IS_TRUE(__pyx_v_self->altweightsfile) != 0);
    __pyx_t_3 = __pyx_t_2;
    __pyx_L11_bool_binop_done:;
    if (__pyx_t_3) {
/* … */
    }
+478: 				self.models = np.load(self.altweightsfile)  # FIXME: keep open?
      __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 478, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_load); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 478, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_11);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      __pyx_t_4 = NULL;
      if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_11))) {
        __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_11);
        if (likely(__pyx_t_4)) {
          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_11);
          __Pyx_INCREF(__pyx_t_4);
          __Pyx_INCREF(function);
          __Pyx_DECREF_SET(__pyx_t_11, function);
        }
      }
      if (!__pyx_t_4) {
        __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_11, __pyx_v_self->altweightsfile); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 478, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_5);
      } else {
        #if CYTHON_FAST_PYCALL
        if (PyFunction_Check(__pyx_t_11)) {
          PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_v_self->altweightsfile};
          __pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_11, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 478, __pyx_L1_error)
          __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
          __Pyx_GOTREF(__pyx_t_5);
        } else
        #endif
        #if CYTHON_FAST_PYCCALL
        if (__Pyx_PyFastCFunction_Check(__pyx_t_11)) {
          PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_v_self->altweightsfile};
          __pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_11, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 478, __pyx_L1_error)
          __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
          __Pyx_GOTREF(__pyx_t_5);
        } else
        #endif
        {
          __pyx_t_12 = PyTuple_New(1+1); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 478, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_12);
          __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_t_4); __pyx_t_4 = NULL;
          __Pyx_INCREF(__pyx_v_self->altweightsfile);
          __Pyx_GIVEREF(__pyx_v_self->altweightsfile);
          PyTuple_SET_ITEM(__pyx_t_12, 0+1, __pyx_v_self->altweightsfile);
          __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_11, __pyx_t_12, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 478, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_5);
          __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
        }
      }
      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
      __Pyx_GIVEREF(__pyx_t_5);
      __Pyx_GOTREF(__pyx_v_self->models);
      __Pyx_DECREF(__pyx_v_self->models);
      __pyx_v_self->models = __pyx_t_5;
      __pyx_t_5 = 0;
+479: 			model = self.models[name]
    __pyx_t_5 = PyObject_GetItem(__pyx_v_self->models, __pyx_v_name); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 479, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __pyx_v_model = __pyx_t_5;
    __pyx_t_5 = 0;
+480: 			if len(model) != <signed>numweights:
    __pyx_t_13 = PyObject_Length(__pyx_v_model); if (unlikely(__pyx_t_13 == -1)) __PYX_ERR(0, 480, __pyx_L1_error)
    __pyx_t_3 = ((__pyx_t_13 != ((int)__pyx_v_numweights)) != 0);
    if (__pyx_t_3) {
/* … */
    }
+481: 				raise ValueError('length mismatch: %d grammar rules, '
      __pyx_t_12 = PyTuple_New(1); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 481, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_12);
      __Pyx_GIVEREF(__pyx_t_11);
      PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_t_11);
      __pyx_t_11 = 0;
      __pyx_t_11 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_12, NULL); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 481, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_11);
      __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
      __Pyx_Raise(__pyx_t_11, 0, 0, 0);
      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
      __PYX_ERR(0, 481, __pyx_L1_error)
+482: 						'%d weights given.' % (
      __pyx_t_11 = PyUnicode_Format(__pyx_kp_u_length_mismatch_d_grammar_rules, __pyx_t_12); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 482, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_11);
      __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+483: 						self.numrules + self.lexical.size(), len(model)))
      __pyx_t_5 = __Pyx_PyInt_FromSize_t((__pyx_v_self->numrules + __pyx_v_self->lexical.size())); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 483, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __pyx_t_13 = PyObject_Length(__pyx_v_model); if (unlikely(__pyx_t_13 == -1)) __PYX_ERR(0, 483, __pyx_L1_error)
      __pyx_t_11 = PyInt_FromSsize_t(__pyx_t_13); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 483, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_11);
      __pyx_t_12 = PyTuple_New(2); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 483, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_12);
      __Pyx_GIVEREF(__pyx_t_5);
      PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_t_5);
      __Pyx_GIVEREF(__pyx_t_11);
      PyTuple_SET_ITEM(__pyx_t_12, 1, __pyx_t_11);
      __pyx_t_5 = 0;
      __pyx_t_11 = 0;
+484: 			ob = np.abs(np.log(model)) if logprob else model
    if ((__pyx_v_logprob != 0)) {
      __pyx_t_12 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 484, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_12);
      __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_12, __pyx_n_s_abs); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 484, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
      __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 484, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __pyx_t_14 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_log); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 484, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_14);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      __pyx_t_4 = NULL;
      if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_14))) {
        __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_14);
        if (likely(__pyx_t_4)) {
          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_14);
          __Pyx_INCREF(__pyx_t_4);
          __Pyx_INCREF(function);
          __Pyx_DECREF_SET(__pyx_t_14, function);
        }
      }
      if (!__pyx_t_4) {
        __pyx_t_12 = __Pyx_PyObject_CallOneArg(__pyx_t_14, __pyx_v_model); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 484, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_12);
      } else {
        #if CYTHON_FAST_PYCALL
        if (PyFunction_Check(__pyx_t_14)) {
          PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_v_model};
          __pyx_t_12 = __Pyx_PyFunction_FastCall(__pyx_t_14, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 484, __pyx_L1_error)
          __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
          __Pyx_GOTREF(__pyx_t_12);
        } else
        #endif
        #if CYTHON_FAST_PYCCALL
        if (__Pyx_PyFastCFunction_Check(__pyx_t_14)) {
          PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_v_model};
          __pyx_t_12 = __Pyx_PyCFunction_FastCall(__pyx_t_14, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 484, __pyx_L1_error)
          __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
          __Pyx_GOTREF(__pyx_t_12);
        } else
        #endif
        {
          __pyx_t_15 = PyTuple_New(1+1); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 484, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_15);
          __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_t_4); __pyx_t_4 = NULL;
          __Pyx_INCREF(__pyx_v_model);
          __Pyx_GIVEREF(__pyx_v_model);
          PyTuple_SET_ITEM(__pyx_t_15, 0+1, __pyx_v_model);
          __pyx_t_12 = __Pyx_PyObject_Call(__pyx_t_14, __pyx_t_15, NULL); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 484, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_12);
          __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
        }
      }
      __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
      __pyx_t_14 = NULL;
      if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
        __pyx_t_14 = PyMethod_GET_SELF(__pyx_t_5);
        if (likely(__pyx_t_14)) {
          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
          __Pyx_INCREF(__pyx_t_14);
          __Pyx_INCREF(function);
          __Pyx_DECREF_SET(__pyx_t_5, function);
        }
      }
      if (!__pyx_t_14) {
        __pyx_t_11 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_12); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 484, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
        __Pyx_GOTREF(__pyx_t_11);
      } else {
        #if CYTHON_FAST_PYCALL
        if (PyFunction_Check(__pyx_t_5)) {
          PyObject *__pyx_temp[2] = {__pyx_t_14, __pyx_t_12};
          __pyx_t_11 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 484, __pyx_L1_error)
          __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0;
          __Pyx_GOTREF(__pyx_t_11);
          __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
        } else
        #endif
        #if CYTHON_FAST_PYCCALL
        if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
          PyObject *__pyx_temp[2] = {__pyx_t_14, __pyx_t_12};
          __pyx_t_11 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 484, __pyx_L1_error)
          __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0;
          __Pyx_GOTREF(__pyx_t_11);
          __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
        } else
        #endif
        {
          __pyx_t_15 = PyTuple_New(1+1); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 484, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_15);
          __Pyx_GIVEREF(__pyx_t_14); PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_t_14); __pyx_t_14 = NULL;
          __Pyx_GIVEREF(__pyx_t_12);
          PyTuple_SET_ITEM(__pyx_t_15, 0+1, __pyx_t_12);
          __pyx_t_12 = 0;
          __pyx_t_11 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_15, NULL); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 484, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_11);
          __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
        }
      }
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      __pyx_t_16 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn_Prob(__pyx_t_11);
      if (unlikely(!__pyx_t_16.memview)) __PYX_ERR(0, 484, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
      __pyx_t_6 = __pyx_t_16;
      __pyx_t_16.memview = NULL;
      __pyx_t_16.data = NULL;
    } else {
      __pyx_t_16 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn_Prob(__pyx_v_model);
      if (unlikely(!__pyx_t_16.memview)) __PYX_ERR(0, 484, __pyx_L1_error)
      __pyx_t_6 = __pyx_t_16;
      __pyx_t_16.memview = NULL;
      __pyx_t_16.data = NULL;
    }
    __pyx_v_ob = __pyx_t_6;
    __pyx_t_6.memview = NULL;
    __pyx_t_6.data = NULL;
+485: 			tmp = &(ob[0])
    __pyx_t_17 = 0;
    __pyx_v_tmp = (&(*((Prob *) ( /* dim=0 */ (__pyx_v_ob.data + __pyx_t_17 * __pyx_v_ob.strides[0]) ))));
  }
  __pyx_L6:;
+486: 		for n in range(self.numrules):
  __pyx_t_7 = __pyx_v_self->numrules;
  for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
    __pyx_v_n = __pyx_t_8;
+487: 			self.bylhs[0][n].prob = tmp[self.bylhs[0][n].no]
    ((__pyx_v_self->bylhs[0])[__pyx_v_n]).prob = (__pyx_v_tmp[((__pyx_v_self->bylhs[0])[__pyx_v_n]).no]);
  }
+488: 		for n in range(self.numbinary):
  __pyx_t_7 = __pyx_v_self->numbinary;
  for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
    __pyx_v_n = __pyx_t_8;
+489: 			self.lbinary[0][n].prob = tmp[self.lbinary[0][n].no]
    ((__pyx_v_self->lbinary[0])[__pyx_v_n]).prob = (__pyx_v_tmp[((__pyx_v_self->lbinary[0])[__pyx_v_n]).no]);
+490: 			self.rbinary[0][n].prob = tmp[self.rbinary[0][n].no]
    ((__pyx_v_self->rbinary[0])[__pyx_v_n]).prob = (__pyx_v_tmp[((__pyx_v_self->rbinary[0])[__pyx_v_n]).no]);
  }
+491: 		for n in range(self.numunary):
  __pyx_t_7 = __pyx_v_self->numunary;
  for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
    __pyx_v_n = __pyx_t_8;
+492: 			self.unary[0][n].prob = tmp[self.unary[0][n].no]
    ((__pyx_v_self->unary[0])[__pyx_v_n]).prob = (__pyx_v_tmp[((__pyx_v_self->unary[0])[__pyx_v_n]).no]);
  }
+493: 		for n in range(self.lexical.size()):
  __pyx_t_18 = __pyx_v_self->lexical.size();
  for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_18; __pyx_t_8+=1) {
    __pyx_v_n = __pyx_t_8;
+494: 			self.lexical[n].prob = tmp[self.numrules + n]
    (__pyx_v_self->lexical[__pyx_v_n]).prob = (__pyx_v_tmp[(__pyx_v_self->numrules + __pyx_v_n)]);
  }
+495: 		self.logprob = logprob
  __pyx_v_self->logprob = __pyx_v_logprob;
+496: 		self.currentmodel = name
  __Pyx_INCREF(__pyx_v_name);
  __Pyx_GIVEREF(__pyx_v_name);
  __Pyx_GOTREF(__pyx_v_self->currentmodel);
  __Pyx_DECREF(__pyx_v_self->currentmodel);
  __pyx_v_self->currentmodel = __pyx_v_name;
 497: 
+498: 	def setmask(self, seq):
/* Python wrapper */
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_15setmask(PyObject *__pyx_v_self, PyObject *__pyx_v_seq); /*proto*/
static char __pyx_doc_8discodop_10containers_7Grammar_14setmask[] = "Grammar.setmask(self, seq)\nGiven a sequence of rule numbers, store a mask so that any phrasal\n\t\trules not in the sequence are deactivated. If sequence is None, the\n\t\tmask is cleared.";
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_15setmask(PyObject *__pyx_v_self, PyObject *__pyx_v_seq) {
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("setmask (wrapper)", 0);
  __pyx_r = __pyx_pf_8discodop_10containers_7Grammar_14setmask(((struct __pyx_obj_8discodop_10containers_Grammar *)__pyx_v_self), ((PyObject *)__pyx_v_seq));

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_8discodop_10containers_7Grammar_14setmask(struct __pyx_obj_8discodop_10containers_Grammar *__pyx_v_self, PyObject *__pyx_v_seq) {
  int __pyx_v_n;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("setmask", 0);
/* … */
  /* function exit code */
  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_AddTraceback("discodop.containers.Grammar.setmask", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 499: 		"""Given a sequence of rule numbers, store a mask so that any phrasal
 500: 		rules not in the sequence are deactivated. If sequence is None, the
 501: 		mask is cleared."""
 502: 		cdef int n
 503: 		# zero-bit = not blocked or out of range; 1-bit = blocked.
+504: 		if seq is None:
  __pyx_t_1 = (__pyx_v_seq == Py_None);
  __pyx_t_2 = (__pyx_t_1 != 0);
  if (__pyx_t_2) {
/* … */
  }
+505: 			memset(<void *>self.mask, 0,
    memset(((void *)__pyx_v_self->mask), 0, (BITNSLOTS(__pyx_v_self->numrules) * (sizeof(uint64_t))));
 506: 					BITNSLOTS(self.numrules) * sizeof(uint64_t))
+507: 			return
    __Pyx_XDECREF(__pyx_r);
    __pyx_r = Py_None; __Pyx_INCREF(Py_None);
    goto __pyx_L0;
+508: 		memset(<void *>self.mask, 255,
  memset(((void *)__pyx_v_self->mask), 0xFF, (BITNSLOTS(__pyx_v_self->numrules) * (sizeof(uint64_t))));
 509: 				BITNSLOTS(self.numrules) * sizeof(uint64_t))
+510: 		for n in seq:
  if (likely(PyList_CheckExact(__pyx_v_seq)) || PyTuple_CheckExact(__pyx_v_seq)) {
    __pyx_t_3 = __pyx_v_seq; __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_seq); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 510, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __pyx_t_5 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 510, __pyx_L1_error)
  }
  for (;;) {
    if (likely(!__pyx_t_5)) {
      if (likely(PyList_CheckExact(__pyx_t_3))) {
        if (__pyx_t_4 >= PyList_GET_SIZE(__pyx_t_3)) break;
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_6 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_6); __pyx_t_4++; if (unlikely(0 < 0)) __PYX_ERR(0, 510, __pyx_L1_error)
        #else
        __pyx_t_6 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 510, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_6);
        #endif
      } else {
        if (__pyx_t_4 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_6 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_6); __pyx_t_4++; if (unlikely(0 < 0)) __PYX_ERR(0, 510, __pyx_L1_error)
        #else
        __pyx_t_6 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 510, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_6);
        #endif
      }
    } else {
      __pyx_t_6 = __pyx_t_5(__pyx_t_3);
      if (unlikely(!__pyx_t_6)) {
        PyObject* exc_type = PyErr_Occurred();
        if (exc_type) {
          if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
          else __PYX_ERR(0, 510, __pyx_L1_error)
        }
        break;
      }
      __Pyx_GOTREF(__pyx_t_6);
    }
    __pyx_t_7 = __Pyx_PyInt_As_int(__pyx_t_6); if (unlikely((__pyx_t_7 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 510, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    __pyx_v_n = __pyx_t_7;
/* … */
  }
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+511: 			CLEARBIT(self.mask, n)
    CLEARBIT(__pyx_v_self->mask, __pyx_v_n);
 512: 		# clear out-of-range bits: 000011111 <-- 1-bits up to numrules.
+513: 		self.mask[BITSLOT(self.numrules)] = BITMASK(self.numrules) - 1UL
  (__pyx_v_self->mask[BITSLOT(__pyx_v_self->numrules)]) = (BITMASK(__pyx_v_self->numrules) - 1UL);
 514: 
+515: 	def testgrammar(self, epsilon=1e-16):
/* Python wrapper */
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_17testgrammar(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_8discodop_10containers_7Grammar_16testgrammar[] = "Grammar.testgrammar(self, epsilon=1e-16)\nTest whether all left-hand sides sum to 1 +/-epsilon for the\n\t\tcurrently selected weights.";
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_17testgrammar(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_epsilon = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("testgrammar (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_epsilon,0};
    PyObject* values[1] = {0};
    values[0] = ((PyObject *)__pyx_float_1eneg_16);
    if (unlikely(__pyx_kwds)) {
      Py_ssize_t kw_args;
      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
      switch (pos_args) {
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = PyDict_Size(__pyx_kwds);
      switch (pos_args) {
        case  0:
        if (kw_args > 0) {
          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_epsilon);
          if (value) { values[0] = value; kw_args--; }
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "testgrammar") < 0)) __PYX_ERR(0, 515, __pyx_L3_error)
      }
    } else {
      switch (PyTuple_GET_SIZE(__pyx_args)) {
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
    }
    __pyx_v_epsilon = values[0];
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("testgrammar", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 515, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("discodop.containers.Grammar.testgrammar", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_8discodop_10containers_7Grammar_16testgrammar(((struct __pyx_obj_8discodop_10containers_Grammar *)__pyx_v_self), __pyx_v_epsilon);

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_8discodop_10containers_7Grammar_16testgrammar(struct __pyx_obj_8discodop_10containers_Grammar *__pyx_v_self, PyObject *__pyx_v_epsilon) {
  ProbRule *__pyx_v_rule;
  LexicalRule __pyx_v_lexrule;
  uint32_t __pyx_v_n;
  uint32_t __pyx_v_maxlabel;
  PyObject *__pyx_v_weights = 0;
  __Pyx_memviewslice __pyx_v_tmp = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_maxdiff = NULL;
  PyObject *__pyx_v_lhs = NULL;
  PyObject *__pyx_v_lhsweights = NULL;
  PyObject *__pyx_v_mass = NULL;
  PyObject *__pyx_v_msg = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("testgrammar", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_4);
  __PYX_XDEC_MEMVIEW(&__pyx_t_7, 1);
  __Pyx_XDECREF(__pyx_t_13);
  __Pyx_XDECREF(__pyx_t_15);
  __Pyx_XDECREF(__pyx_t_16);
  __Pyx_XDECREF(__pyx_t_17);
  __Pyx_AddTraceback("discodop.containers.Grammar.testgrammar", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_weights);
  __PYX_XDEC_MEMVIEW(&__pyx_v_tmp, 1);
  __Pyx_XDECREF(__pyx_v_maxdiff);
  __Pyx_XDECREF(__pyx_v_lhs);
  __Pyx_XDECREF(__pyx_v_lhsweights);
  __Pyx_XDECREF(__pyx_v_mass);
  __Pyx_XDECREF(__pyx_v_msg);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 516: 		"""Test whether all left-hand sides sum to 1 +/-epsilon for the
 517: 		currently selected weights."""
 518: 		cdef ProbRule *rule
 519: 		cdef LexicalRule lexrule
+520: 		cdef uint32_t n, maxlabel = 0
  __pyx_v_maxlabel = 0;
+521: 		cdef list weights = [[] for _ in range(self.nonterminals)]
  { /* enter inner scope */
    CYTHON_UNUSED size_t __pyx_7genexpr__pyx_v__;
    __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 521, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_2 = __pyx_v_self->nonterminals;
    for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
      __pyx_7genexpr__pyx_v__ = __pyx_t_3;
      __pyx_t_4 = PyList_New(0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 521, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_4))) __PYX_ERR(0, 521, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    }
  } /* exit inner scope */
  __pyx_v_weights = ((PyObject*)__pyx_t_1);
  __pyx_t_1 = 0;
 522: 		cdef Prob [:] tmp
+523: 		if self.currentmodel == 'default':
  __pyx_t_5 = (__Pyx_PyUnicode_Equals(__pyx_v_self->currentmodel, __pyx_n_u_default, Py_EQ)); if (unlikely(__pyx_t_5 < 0)) __PYX_ERR(0, 523, __pyx_L1_error)
  __pyx_t_6 = (__pyx_t_5 != 0);
  if (__pyx_t_6) {
/* … */
    goto __pyx_L5;
  }
+524: 			tmp = array('d', self.defaultmodel)
    __pyx_t_1 = __pyx_convert_vector_to_py_Prob(__pyx_v_self->defaultmodel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 524, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 524, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_INCREF(__pyx_n_u_d);
    __Pyx_GIVEREF(__pyx_n_u_d);
    PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_n_u_d);
    __Pyx_GIVEREF(__pyx_t_1);
    PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_1);
    __pyx_t_1 = 0;
    __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_7cpython_5array_array), __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 524, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn_Prob(__pyx_t_1);
    if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 524, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_v_tmp = __pyx_t_7;
    __pyx_t_7.memview = NULL;
    __pyx_t_7.data = NULL;
 525: 		else:
+526: 			tmp = self.models[self.currentmodel]
  /*else*/ {
    __pyx_t_1 = PyObject_GetItem(__pyx_v_self->models, __pyx_v_self->currentmodel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 526, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn_Prob(__pyx_t_1);
    if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 526, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_v_tmp = __pyx_t_7;
    __pyx_t_7.memview = NULL;
    __pyx_t_7.data = NULL;
  }
  __pyx_L5:;
 527: 		# We could be strict about separating POS tags and phrasal categories,
 528: 		# but Negra contains at least one tag (--) used for both.
+529: 		for n in range(self.numrules):
  __pyx_t_2 = __pyx_v_self->numrules;
  for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_2; __pyx_t_8+=1) {
    __pyx_v_n = __pyx_t_8;
+530: 			rule = &(self.bylhs[0][n])
    __pyx_v_rule = (&((__pyx_v_self->bylhs[0])[__pyx_v_n]));
+531: 			weights[rule.lhs].append(tmp[rule.no])
    __pyx_t_3 = __pyx_v_rule->no;
    __pyx_t_1 = PyFloat_FromDouble((*((Prob *) ( /* dim=0 */ (__pyx_v_tmp.data + __pyx_t_3 * __pyx_v_tmp.strides[0]) )))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 531, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_9 = __Pyx_PyObject_Append(PyList_GET_ITEM(__pyx_v_weights, __pyx_v_rule->lhs), __pyx_t_1); if (unlikely(__pyx_t_9 == -1)) __PYX_ERR(0, 531, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  }
+532: 		n = self.numrules
  __pyx_t_2 = __pyx_v_self->numrules;
  __pyx_v_n = __pyx_t_2;
+533: 		for lexrule in self.lexical:
  __pyx_t_11 = &__pyx_v_self->lexical;
  __pyx_t_10 = __pyx_t_11->begin();
  for (;;) {
    if (!(__pyx_t_10 != __pyx_t_11->end())) break;
    __pyx_t_12 = *__pyx_t_10;
    ++__pyx_t_10;
    __pyx_v_lexrule = __pyx_t_12;
/* … */
  }
+534: 			weights[lexrule.lhs].append(tmp[n])
    __pyx_t_2 = __pyx_v_n;
    __pyx_t_1 = PyFloat_FromDouble((*((Prob *) ( /* dim=0 */ (__pyx_v_tmp.data + __pyx_t_2 * __pyx_v_tmp.strides[0]) )))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 534, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_9 = __Pyx_PyObject_Append(PyList_GET_ITEM(__pyx_v_weights, __pyx_v_lexrule.lhs), __pyx_t_1); if (unlikely(__pyx_t_9 == -1)) __PYX_ERR(0, 534, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+535: 			n += 1
    __pyx_v_n = (__pyx_v_n + 1);
+536: 		maxdiff = epsilon
  __Pyx_INCREF(__pyx_v_epsilon);
  __pyx_v_maxdiff = __pyx_v_epsilon;
+537: 		for lhs, lhsweights in enumerate(weights[1:], 1):
  __Pyx_INCREF(__pyx_int_1);
  __pyx_t_1 = __pyx_int_1;
  __pyx_t_4 = __Pyx_PyList_GetSlice(__pyx_v_weights, 1, PY_SSIZE_T_MAX); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 537, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_13 = __pyx_t_4; __Pyx_INCREF(__pyx_t_13); __pyx_t_14 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  for (;;) {
    if (__pyx_t_14 >= PyList_GET_SIZE(__pyx_t_13)) break;
    #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
    __pyx_t_4 = PyList_GET_ITEM(__pyx_t_13, __pyx_t_14); __Pyx_INCREF(__pyx_t_4); __pyx_t_14++; if (unlikely(0 < 0)) __PYX_ERR(0, 537, __pyx_L1_error)
    #else
    __pyx_t_4 = PySequence_ITEM(__pyx_t_13, __pyx_t_14); __pyx_t_14++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 537, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    #endif
    __Pyx_XDECREF_SET(__pyx_v_lhsweights, __pyx_t_4);
    __pyx_t_4 = 0;
    __Pyx_INCREF(__pyx_t_1);
    __Pyx_XDECREF_SET(__pyx_v_lhs, __pyx_t_1);
    __pyx_t_4 = __Pyx_PyInt_AddObjC(__pyx_t_1, __pyx_int_1, 1, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 537, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_DECREF(__pyx_t_1);
    __pyx_t_1 = __pyx_t_4;
    __pyx_t_4 = 0;
/* … */
  }
  __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+538: 			mass = fsum(lhsweights)
    __pyx_t_15 = __Pyx_GetModuleGlobalName(__pyx_n_s_fsum); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 538, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_15);
    __pyx_t_16 = NULL;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_15))) {
      __pyx_t_16 = PyMethod_GET_SELF(__pyx_t_15);
      if (likely(__pyx_t_16)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_15);
        __Pyx_INCREF(__pyx_t_16);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_15, function);
      }
    }
    if (!__pyx_t_16) {
      __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_15, __pyx_v_lhsweights); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 538, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
    } else {
      #if CYTHON_FAST_PYCALL
      if (PyFunction_Check(__pyx_t_15)) {
        PyObject *__pyx_temp[2] = {__pyx_t_16, __pyx_v_lhsweights};
        __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_15, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 538, __pyx_L1_error)
        __Pyx_XDECREF(__pyx_t_16); __pyx_t_16 = 0;
        __Pyx_GOTREF(__pyx_t_4);
      } else
      #endif
      #if CYTHON_FAST_PYCCALL
      if (__Pyx_PyFastCFunction_Check(__pyx_t_15)) {
        PyObject *__pyx_temp[2] = {__pyx_t_16, __pyx_v_lhsweights};
        __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_15, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 538, __pyx_L1_error)
        __Pyx_XDECREF(__pyx_t_16); __pyx_t_16 = 0;
        __Pyx_GOTREF(__pyx_t_4);
      } else
      #endif
      {
        __pyx_t_17 = PyTuple_New(1+1); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 538, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_17);
        __Pyx_GIVEREF(__pyx_t_16); PyTuple_SET_ITEM(__pyx_t_17, 0, __pyx_t_16); __pyx_t_16 = NULL;
        __Pyx_INCREF(__pyx_v_lhsweights);
        __Pyx_GIVEREF(__pyx_v_lhsweights);
        PyTuple_SET_ITEM(__pyx_t_17, 0+1, __pyx_v_lhsweights);
        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_15, __pyx_t_17, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 538, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
        __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0;
      }
    }
    __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
    __Pyx_XDECREF_SET(__pyx_v_mass, __pyx_t_4);
    __pyx_t_4 = 0;
+539: 			if abs(mass - 1.0) > maxdiff:
    __pyx_t_4 = __Pyx_PyFloat_SubtractObjC(__pyx_v_mass, __pyx_float_1_0, 1.0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 539, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __pyx_t_15 = PyNumber_Absolute(__pyx_t_4); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 539, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_15);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __pyx_t_4 = PyObject_RichCompare(__pyx_t_15, __pyx_v_maxdiff, Py_GT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 539, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
    __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(0, 539, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    if (__pyx_t_6) {
/* … */
    }
+540: 				maxdiff = abs(mass - 1.0)
      __pyx_t_4 = __Pyx_PyFloat_SubtractObjC(__pyx_v_mass, __pyx_float_1_0, 1.0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 540, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __pyx_t_15 = PyNumber_Absolute(__pyx_t_4); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 540, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_15);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      __Pyx_DECREF_SET(__pyx_v_maxdiff, __pyx_t_15);
      __pyx_t_15 = 0;
+541: 				maxlabel = lhs
      __pyx_t_8 = __Pyx_PyInt_As_uint32_t(__pyx_v_lhs); if (unlikely((__pyx_t_8 == ((uint32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 541, __pyx_L1_error)
      __pyx_v_maxlabel = __pyx_t_8;
+542: 		if maxdiff > epsilon:
  __pyx_t_1 = PyObject_RichCompare(__pyx_v_maxdiff, __pyx_v_epsilon, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 542, __pyx_L1_error)
  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(0, 542, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (__pyx_t_6) {
/* … */
  }
 543: 			msg = ('Weights do not sum to 1 +/- %g.\n'
 544: 					'Largest difference with rules for LHS \'%s\': '
+545: 					'sum = %g; diff = %g' % (
    __pyx_t_13 = PyUnicode_Format(__pyx_kp_u_Weights_do_not_sum_to_1_g_Larges, __pyx_t_15); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 545, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_13);
    __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
    __pyx_v_msg = ((PyObject*)__pyx_t_13);
    __pyx_t_13 = 0;
+546: 					epsilon, self.tolabel[maxlabel],
    __pyx_t_1 = __Pyx_GetItemInt(((PyObject *)__pyx_v_self->tolabel), __pyx_v_maxlabel, uint32_t, 0, __Pyx_PyInt_From_uint32_t, 0, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 546, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
/* … */
    __pyx_t_15 = PyTuple_New(4); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 546, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_15);
    __Pyx_INCREF(__pyx_v_epsilon);
    __Pyx_GIVEREF(__pyx_v_epsilon);
    PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_v_epsilon);
    __Pyx_GIVEREF(__pyx_t_1);
    PyTuple_SET_ITEM(__pyx_t_15, 1, __pyx_t_1);
    __Pyx_GIVEREF(__pyx_t_13);
    PyTuple_SET_ITEM(__pyx_t_15, 2, __pyx_t_13);
    __Pyx_INCREF(__pyx_v_maxdiff);
    __Pyx_GIVEREF(__pyx_v_maxdiff);
    PyTuple_SET_ITEM(__pyx_t_15, 3, __pyx_v_maxdiff);
    __pyx_t_1 = 0;
    __pyx_t_13 = 0;
+547: 					fsum(weights[maxlabel]), maxdiff))
    __pyx_t_15 = __Pyx_GetModuleGlobalName(__pyx_n_s_fsum); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 547, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_15);
    __pyx_t_4 = NULL;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_15))) {
      __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_15);
      if (likely(__pyx_t_4)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_15);
        __Pyx_INCREF(__pyx_t_4);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_15, function);
      }
    }
    if (!__pyx_t_4) {
      __pyx_t_13 = __Pyx_PyObject_CallOneArg(__pyx_t_15, PyList_GET_ITEM(__pyx_v_weights, __pyx_v_maxlabel)); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 547, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_13);
    } else {
      #if CYTHON_FAST_PYCALL
      if (PyFunction_Check(__pyx_t_15)) {
        PyObject *__pyx_temp[2] = {__pyx_t_4, PyList_GET_ITEM(__pyx_v_weights, __pyx_v_maxlabel)};
        __pyx_t_13 = __Pyx_PyFunction_FastCall(__pyx_t_15, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 547, __pyx_L1_error)
        __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
        __Pyx_GOTREF(__pyx_t_13);
      } else
      #endif
      #if CYTHON_FAST_PYCCALL
      if (__Pyx_PyFastCFunction_Check(__pyx_t_15)) {
        PyObject *__pyx_temp[2] = {__pyx_t_4, PyList_GET_ITEM(__pyx_v_weights, __pyx_v_maxlabel)};
        __pyx_t_13 = __Pyx_PyCFunction_FastCall(__pyx_t_15, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 547, __pyx_L1_error)
        __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
        __Pyx_GOTREF(__pyx_t_13);
      } else
      #endif
      {
        __pyx_t_17 = PyTuple_New(1+1); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 547, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_17);
        __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_17, 0, __pyx_t_4); __pyx_t_4 = NULL;
        __Pyx_INCREF(PyList_GET_ITEM(__pyx_v_weights, __pyx_v_maxlabel));
        __Pyx_GIVEREF(PyList_GET_ITEM(__pyx_v_weights, __pyx_v_maxlabel));
        PyTuple_SET_ITEM(__pyx_t_17, 0+1, PyList_GET_ITEM(__pyx_v_weights, __pyx_v_maxlabel));
        __pyx_t_13 = __Pyx_PyObject_Call(__pyx_t_15, __pyx_t_17, NULL); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 547, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_13);
        __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0;
      }
    }
    __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
+548: 			return False, msg
    __Pyx_XDECREF(__pyx_r);
    __pyx_t_13 = PyTuple_New(2); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 548, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_13);
    __Pyx_INCREF(Py_False);
    __Pyx_GIVEREF(Py_False);
    PyTuple_SET_ITEM(__pyx_t_13, 0, Py_False);
    __Pyx_INCREF(__pyx_v_msg);
    __Pyx_GIVEREF(__pyx_v_msg);
    PyTuple_SET_ITEM(__pyx_t_13, 1, __pyx_v_msg);
    __pyx_r = __pyx_t_13;
    __pyx_t_13 = 0;
    goto __pyx_L0;
+549: 		return True, 'All left hand sides sum to 1 +/- epsilon=%s' % epsilon
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_13 = PyUnicode_Format(__pyx_kp_u_All_left_hand_sides_sum_to_1_eps, __pyx_v_epsilon); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 549, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_13);
  __pyx_t_15 = PyTuple_New(2); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 549, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_15);
  __Pyx_INCREF(Py_True);
  __Pyx_GIVEREF(Py_True);
  PyTuple_SET_ITEM(__pyx_t_15, 0, Py_True);
  __Pyx_GIVEREF(__pyx_t_13);
  PyTuple_SET_ITEM(__pyx_t_15, 1, __pyx_t_13);
  __pyx_t_13 = 0;
  __pyx_r = __pyx_t_15;
  __pyx_t_15 = 0;
  goto __pyx_L0;
 550: 
+551: 	def getmapping(Grammar self, Grammar coarse, striplabelre=None,
/* Python wrapper */
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_19getmapping(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_8discodop_10containers_7Grammar_18getmapping[] = "Grammar.getmapping(self, Grammar coarse, striplabelre=None, neverblockre=None, bool splitprune=False, bool markorigin=False, dict mapping=None)\nConstruct mapping of this grammar's non-terminal labels to another.\n\n\t\t:param coarse: the grammar to which this grammar's labels will be\n\t\t\tmapped. May be ``None`` to establish a separate mapping to own\n\t\t\tlabels.\n\t\t:param striplabelre: if not None, a compiled regex used to form\n\t\t\tthe coarse label for a given fine label. This regex is applied\n\t\t\twith a substitution to the empty string.\n\t\t:param neverblockre: labels that match this regex will never be pruned.\n\t\t\tAlso used to identify auxiliary labels of Double-DOP grammars.\n\n\t\t\t- use ``|<`` to ignore nodes introduced by binarization;\n\t\t\t\tuseful if coarse and fine stages employ different kinds of\n\t\t\t\tmarkovization; e.g., ``NP`` and ``VP`` may be blocked,\n\t\t\t\tbut not ``NP|<DT-NN>``.\n\t\t\t- ``_[0-9]+`` to ignore discontinuous nodes ``X_n`` where ``X`` is\n\t\t\t\ta label and *n* is a fanout.\n\n\t\t:param mapping: a dictionary with strings of fine labels mapped to\n\t\t\tcoarse labels. striplabelre, if given, is applied first.\n\n\t\tThe regexes should be compiled objects, i.e., ``re.compile(regex)``,\n\t\tor ``None`` to leave labels unchanged.\n\t\t";
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_19getmapping(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  struct __pyx_obj_8discodop_10containers_Grammar *__pyx_v_coarse = 0;
  PyObject *__pyx_v_striplabelre = 0;
  PyObject *__pyx_v_neverblockre = 0;
  int __pyx_v_splitprune;
  int __pyx_v_markorigin;
  PyObject *__pyx_v_mapping = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("getmapping (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_coarse,&__pyx_n_s_striplabelre,&__pyx_n_s_neverblockre,&__pyx_n_s_splitprune,&__pyx_n_s_markorigin,&__pyx_n_s_mapping,0};
    PyObject* values[6] = {0,0,0,0,0,0};
    values[1] = ((PyObject *)Py_None);
/* … */
  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_8discodop_10containers_7Grammar_18getmapping(struct __pyx_obj_8discodop_10containers_Grammar *__pyx_v_self, struct __pyx_obj_8discodop_10containers_Grammar *__pyx_v_coarse, PyObject *__pyx_v_striplabelre, PyObject *__pyx_v_neverblockre, int __pyx_v_splitprune, int __pyx_v_markorigin, PyObject *__pyx_v_mapping) {
  int __pyx_v_selfmap;
  int __pyx_v_n;
  int __pyx_v_m;
  int __pyx_v_components;
  PyObject *__pyx_v_seen = 0;
  uint32_t *__pyx_v_result;
  PyObject *__pyx_v_strlabel = NULL;
  PyObject *__pyx_v_msg = NULL;
  PyObject *__pyx_v_l = NULL;
  PyObject *__pyx_v_diff = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("getmapping", 0);
  __Pyx_INCREF((PyObject *)__pyx_v_coarse);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_XDECREF(__pyx_t_9);
  __Pyx_XDECREF(__pyx_t_10);
  __Pyx_AddTraceback("discodop.containers.Grammar.getmapping", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_seen);
  __Pyx_XDECREF(__pyx_v_strlabel);
  __Pyx_XDECREF(__pyx_v_msg);
  __Pyx_XDECREF(__pyx_v_l);
  __Pyx_XDECREF(__pyx_v_diff);
  __Pyx_XDECREF((PyObject *)__pyx_v_coarse);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
+552: 			neverblockre=None, bint splitprune=False, bint markorigin=False,
    values[2] = ((PyObject *)Py_None);
/* … */
      __pyx_v_splitprune = ((int)0);
    }
    if (values[4]) {
      __pyx_v_markorigin = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_markorigin == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 552, __pyx_L3_error)
    } else {
      __pyx_v_markorigin = ((int)0);
    }
    __pyx_v_mapping = ((PyObject*)values[5]);
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("getmapping", 0, 1, 6, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 551, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("discodop.containers.Grammar.getmapping", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_coarse), __pyx_ptype_8discodop_10containers_Grammar, 1, "coarse", 0))) __PYX_ERR(0, 551, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_mapping), (&PyDict_Type), 1, "mapping", 1))) __PYX_ERR(0, 553, __pyx_L1_error)
  __pyx_r = __pyx_pf_8discodop_10containers_7Grammar_18getmapping(((struct __pyx_obj_8discodop_10containers_Grammar *)__pyx_v_self), __pyx_v_coarse, __pyx_v_striplabelre, __pyx_v_neverblockre, __pyx_v_splitprune, __pyx_v_markorigin, __pyx_v_mapping);
+553: 			dict mapping=None):
    values[5] = ((PyObject*)Py_None);
    if (unlikely(__pyx_kwds)) {
      Py_ssize_t kw_args;
      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
      switch (pos_args) {
        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
        CYTHON_FALLTHROUGH;
        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
        CYTHON_FALLTHROUGH;
        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
        CYTHON_FALLTHROUGH;
        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = PyDict_Size(__pyx_kwds);
      switch (pos_args) {
        case  0:
        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_coarse)) != 0)) kw_args--;
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (kw_args > 0) {
          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_striplabelre);
          if (value) { values[1] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (kw_args > 0) {
          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_neverblockre);
          if (value) { values[2] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  3:
        if (kw_args > 0) {
          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_splitprune);
          if (value) { values[3] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  4:
        if (kw_args > 0) {
          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_markorigin);
          if (value) { values[4] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  5:
        if (kw_args > 0) {
          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_mapping);
          if (value) { values[5] = value; kw_args--; }
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "getmapping") < 0)) __PYX_ERR(0, 551, __pyx_L3_error)
      }
    } else {
      switch (PyTuple_GET_SIZE(__pyx_args)) {
        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
        CYTHON_FALLTHROUGH;
        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
        CYTHON_FALLTHROUGH;
        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
        CYTHON_FALLTHROUGH;
        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        break;
        default: goto __pyx_L5_argtuple_error;
      }
    }
    __pyx_v_coarse = ((struct __pyx_obj_8discodop_10containers_Grammar *)values[0]);
    __pyx_v_striplabelre = values[1];
    __pyx_v_neverblockre = values[2];
    if (values[3]) {
      __pyx_v_splitprune = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_splitprune == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 552, __pyx_L3_error)
    } else {
 554: 		"""Construct mapping of this grammar's non-terminal labels to another.
 555: 
 556: 		:param coarse: the grammar to which this grammar's labels will be
 557: 			mapped. May be ``None`` to establish a separate mapping to own
 558: 			labels.
 559: 		:param striplabelre: if not None, a compiled regex used to form
 560: 			the coarse label for a given fine label. This regex is applied
 561: 			with a substitution to the empty string.
 562: 		:param neverblockre: labels that match this regex will never be pruned.
 563: 			Also used to identify auxiliary labels of Double-DOP grammars.
 564: 
 565: 			- use ``|<`` to ignore nodes introduced by binarization;
 566: 				useful if coarse and fine stages employ different kinds of
 567: 				markovization; e.g., ``NP`` and ``VP`` may be blocked,
 568: 				but not ``NP|<DT-NN>``.
 569: 			- ``_[0-9]+`` to ignore discontinuous nodes ``X_n`` where ``X`` is
 570: 				a label and *n* is a fanout.
 571: 
 572: 		:param mapping: a dictionary with strings of fine labels mapped to
 573: 			coarse labels. striplabelre, if given, is applied first.
 574: 
 575: 		The regexes should be compiled objects, i.e., ``re.compile(regex)``,
 576: 		or ``None`` to leave labels unchanged.
 577: 		"""
+578: 		cdef bint selfmap = coarse is None
  __pyx_t_1 = (((PyObject *)__pyx_v_coarse) == Py_None);
  __pyx_v_selfmap = __pyx_t_1;
+579: 		cdef int n, m, components = 0
  __pyx_v_components = 0;
+580: 		cdef set seen = {0}
  __pyx_t_2 = PySet_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 580, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PySet_Add(__pyx_t_2, __pyx_int_0) < 0) __PYX_ERR(0, 580, __pyx_L1_error)
  __pyx_v_seen = ((PyObject*)__pyx_t_2);
  __pyx_t_2 = 0;
+581: 		cdef uint32_t *result = <uint32_t *>malloc(
  __pyx_v_result = ((uint32_t *)malloc(((sizeof(uint32_t)) * __pyx_v_self->nonterminals)));
 582: 				sizeof(uint32_t) * self.nonterminals)
+583: 		if result is NULL:
  __pyx_t_1 = ((__pyx_v_result == NULL) != 0);
  if (__pyx_t_1) {
/* … */
  }
+584: 			raise MemoryError
    PyErr_NoMemory(); __PYX_ERR(0, 584, __pyx_L1_error)
+585: 		if selfmap:
  __pyx_t_1 = (__pyx_v_selfmap != 0);
  if (__pyx_t_1) {
/* … */
    goto __pyx_L4;
  }
+586: 			coarse = self
    __Pyx_INCREF(((PyObject *)__pyx_v_self));
    __Pyx_DECREF_SET(__pyx_v_coarse, __pyx_v_self);
+587: 			if self.selfmapping is not NULL:
    __pyx_t_1 = ((__pyx_v_self->selfmapping != NULL) != 0);
    if (__pyx_t_1) {
/* … */
    }
+588: 				free(self.selfmapping)
      free(__pyx_v_self->selfmapping);
+589: 			self.selfmapping = result
    __pyx_v_self->selfmapping = __pyx_v_result;
 590: 		else:
+591: 			if self.mapping is not NULL:
  /*else*/ {
    __pyx_t_1 = ((__pyx_v_self->mapping != NULL) != 0);
    if (__pyx_t_1) {
/* … */
    }
+592: 				free(self.mapping)
      free(__pyx_v_self->mapping);
+593: 			self.mapping = result
    __pyx_v_self->mapping = __pyx_v_result;
 594: 			# construct mapping from coarse label to fine labels
+595: 			self.revmap.resize(coarse.nonterminals)
    try {
      __pyx_v_self->revmap.resize(__pyx_v_coarse->nonterminals);
    } catch(...) {
      __Pyx_CppExn2PyErr();
      __PYX_ERR(0, 595, __pyx_L1_error)
    }
  }
  __pyx_L4:;
+596: 		if splitprune and markorigin:
  __pyx_t_3 = (__pyx_v_splitprune != 0);
  if (__pyx_t_3) {
  } else {
    __pyx_t_1 = __pyx_t_3;
    goto __pyx_L8_bool_binop_done;
  }
  __pyx_t_3 = (__pyx_v_markorigin != 0);
  __pyx_t_1 = __pyx_t_3;
  __pyx_L8_bool_binop_done:;
  if (__pyx_t_1) {
/* … */
  }
+597: 			if self.splitmapping is not NULL:
    __pyx_t_1 = ((__pyx_v_self->splitmapping != NULL) != 0);
    if (__pyx_t_1) {
/* … */
    }
+598: 				if self.splitmapping[0] is not NULL:
      __pyx_t_1 = (((__pyx_v_self->splitmapping[0]) != NULL) != 0);
      if (__pyx_t_1) {
/* … */
      }
+599: 					free(self.splitmapping[0])
        free((__pyx_v_self->splitmapping[0]));
+600: 				free(self.splitmapping)
      free(__pyx_v_self->splitmapping);
+601: 			self.splitmapping = <uint32_t **>malloc(sizeof(uint32_t *)
    __pyx_v_self->splitmapping = ((uint32_t **)malloc(((sizeof(uint32_t *)) * __pyx_v_self->nonterminals)));
 602: 					* self.nonterminals)
+603: 			for n in range(self.nonterminals):
    /* "discodop/_grammar.pxi":603
 * 			self.splitmapping = <uint32_t **>malloc(sizeof(uint32_t *)
 * 					* self.nonterminals)
 * 			for n in range(self.nonterminals):             # <<<<<<<<<<<<<<
 * 				self.splitmapping[n] = NULL
 * 			self.splitmapping[0] = <uint32_t *>malloc(sizeof(uint32_t) *
 */
    __pyx_t_4 = __pyx_v_self->nonterminals;
    for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
      __pyx_v_n = __pyx_t_5;
+604: 				self.splitmapping[n] = NULL
      (__pyx_v_self->splitmapping[__pyx_v_n]) = NULL;
    }
+605: 			self.splitmapping[0] = <uint32_t *>malloc(sizeof(uint32_t) *
    __pyx_t_2 = __Pyx_PyInt_FromSize_t((sizeof(uint32_t))); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 605, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
/* … */
    __pyx_t_7 = PyNumber_Multiply(__pyx_t_2, __pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 605, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_7);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    __pyx_t_4 = __Pyx_PyInt_As_size_t(__pyx_t_7); if (unlikely((__pyx_t_4 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 605, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    (__pyx_v_self->splitmapping[0]) = ((uint32_t *)malloc(__pyx_t_4));
+606: 				sum([self.fanout[n] for n in range(self.nonterminals)
    { /* enter inner scope */
      int __pyx_8genexpr1__pyx_v_n;
      __pyx_t_6 = PyList_New(0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 606, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      __pyx_t_4 = __pyx_v_self->nonterminals;
      for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
        __pyx_8genexpr1__pyx_v_n = __pyx_t_5;
/* … */
          __pyx_t_7 = __Pyx_PyInt_From_uint8_t((__pyx_v_self->fanout[__pyx_8genexpr1__pyx_v_n])); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 606, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_7);
          if (unlikely(__Pyx_ListComp_Append(__pyx_t_6, (PyObject*)__pyx_t_7))) __PYX_ERR(0, 606, __pyx_L1_error)
          __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
/* … */
    __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 606, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_7);
    __Pyx_GIVEREF(__pyx_t_6);
    PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6);
    __pyx_t_6 = 0;
    __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_sum, __pyx_t_7, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 606, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+607: 					if self.fanout[n] > 1]))
        __pyx_t_1 = (((__pyx_v_self->fanout[__pyx_8genexpr1__pyx_v_n]) > 1) != 0);
        if (__pyx_t_1) {
/* … */
        }
      }
    } /* exit inner scope */
+608: 		for n in range(self.nonterminals):
  __pyx_t_4 = __pyx_v_self->nonterminals;
  for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
    __pyx_v_n = __pyx_t_5;
+609: 			if not neverblockre or neverblockre.search(self.tolabel[n]) is None:
    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_neverblockre); if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 609, __pyx_L1_error)
    __pyx_t_8 = ((!__pyx_t_3) != 0);
    if (!__pyx_t_8) {
    } else {
      __pyx_t_1 = __pyx_t_8;
      goto __pyx_L20_bool_binop_done;
    }
    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_neverblockre, __pyx_n_s_search); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 609, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __pyx_t_2 = __Pyx_GetItemInt(((PyObject *)__pyx_v_self->tolabel), __pyx_v_n, int, 1, __Pyx_PyInt_From_int, 0, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 609, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_9 = NULL;
    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
      __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_6);
      if (likely(__pyx_t_9)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
        __Pyx_INCREF(__pyx_t_9);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_6, function);
      }
    }
    if (!__pyx_t_9) {
      __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_t_2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 609, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      __Pyx_GOTREF(__pyx_t_7);
    } else {
      #if CYTHON_FAST_PYCALL
      if (PyFunction_Check(__pyx_t_6)) {
        PyObject *__pyx_temp[2] = {__pyx_t_9, __pyx_t_2};
        __pyx_t_7 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 609, __pyx_L1_error)
        __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
        __Pyx_GOTREF(__pyx_t_7);
        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      } else
      #endif
      #if CYTHON_FAST_PYCCALL
      if (__Pyx_PyFastCFunction_Check(__pyx_t_6)) {
        PyObject *__pyx_temp[2] = {__pyx_t_9, __pyx_t_2};
        __pyx_t_7 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 609, __pyx_L1_error)
        __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
        __Pyx_GOTREF(__pyx_t_7);
        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      } else
      #endif
      {
        __pyx_t_10 = PyTuple_New(1+1); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 609, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_10);
        __Pyx_GIVEREF(__pyx_t_9); PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_9); __pyx_t_9 = NULL;
        __Pyx_GIVEREF(__pyx_t_2);
        PyTuple_SET_ITEM(__pyx_t_10, 0+1, __pyx_t_2);
        __pyx_t_2 = 0;
        __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_10, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 609, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_7);
        __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
      }
    }
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    __pyx_t_8 = (__pyx_t_7 == Py_None);
    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    __pyx_t_3 = (__pyx_t_8 != 0);
    __pyx_t_1 = __pyx_t_3;
    __pyx_L20_bool_binop_done:;
    if (__pyx_t_1) {
/* … */
      goto __pyx_L19;
    }
+610: 				strlabel = self.tolabel[n]
      __pyx_t_7 = __Pyx_GetItemInt(((PyObject *)__pyx_v_self->tolabel), __pyx_v_n, int, 1, __Pyx_PyInt_From_int, 0, 0, 0); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 610, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      __Pyx_XDECREF_SET(__pyx_v_strlabel, __pyx_t_7);
      __pyx_t_7 = 0;
+611: 				if striplabelre is not None:
      __pyx_t_1 = (__pyx_v_striplabelre != Py_None);
      __pyx_t_3 = (__pyx_t_1 != 0);
      if (__pyx_t_3) {
/* … */
      }
+612: 					strlabel = striplabelre.sub('', strlabel, 1)
        __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_striplabelre, __pyx_n_s_sub); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 612, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_6);
        __pyx_t_10 = NULL;
        __pyx_t_11 = 0;
        if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
          __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_6);
          if (likely(__pyx_t_10)) {
            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
            __Pyx_INCREF(__pyx_t_10);
            __Pyx_INCREF(function);
            __Pyx_DECREF_SET(__pyx_t_6, function);
            __pyx_t_11 = 1;
          }
        }
        #if CYTHON_FAST_PYCALL
        if (PyFunction_Check(__pyx_t_6)) {
          PyObject *__pyx_temp[4] = {__pyx_t_10, __pyx_kp_u__11, __pyx_v_strlabel, __pyx_int_1};
          __pyx_t_7 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-__pyx_t_11, 3+__pyx_t_11); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 612, __pyx_L1_error)
          __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
          __Pyx_GOTREF(__pyx_t_7);
        } else
        #endif
        #if CYTHON_FAST_PYCCALL
        if (__Pyx_PyFastCFunction_Check(__pyx_t_6)) {
          PyObject *__pyx_temp[4] = {__pyx_t_10, __pyx_kp_u__11, __pyx_v_strlabel, __pyx_int_1};
          __pyx_t_7 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-__pyx_t_11, 3+__pyx_t_11); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 612, __pyx_L1_error)
          __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
          __Pyx_GOTREF(__pyx_t_7);
        } else
        #endif
        {
          __pyx_t_2 = PyTuple_New(3+__pyx_t_11); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 612, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_2);
          if (__pyx_t_10) {
            __Pyx_GIVEREF(__pyx_t_10); PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_10); __pyx_t_10 = NULL;
          }
          __Pyx_INCREF(__pyx_kp_u__11);
          __Pyx_GIVEREF(__pyx_kp_u__11);
          PyTuple_SET_ITEM(__pyx_t_2, 0+__pyx_t_11, __pyx_kp_u__11);
          __Pyx_INCREF(__pyx_v_strlabel);
          __Pyx_GIVEREF(__pyx_v_strlabel);
          PyTuple_SET_ITEM(__pyx_t_2, 1+__pyx_t_11, __pyx_v_strlabel);
          __Pyx_INCREF(__pyx_int_1);
          __Pyx_GIVEREF(__pyx_int_1);
          PyTuple_SET_ITEM(__pyx_t_2, 2+__pyx_t_11, __pyx_int_1);
          __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_2, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 612, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_7);
          __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
        }
        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
        __Pyx_DECREF_SET(__pyx_v_strlabel, __pyx_t_7);
        __pyx_t_7 = 0;
+613: 				if mapping is not None:
      __pyx_t_3 = (__pyx_v_mapping != ((PyObject*)Py_None));
      __pyx_t_1 = (__pyx_t_3 != 0);
      if (__pyx_t_1) {
/* … */
      }
+614: 					strlabel = mapping[strlabel]
        if (unlikely(__pyx_v_mapping == Py_None)) {
          PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
          __PYX_ERR(0, 614, __pyx_L1_error)
        }
        __pyx_t_7 = __Pyx_PyDict_GetItem(__pyx_v_mapping, __pyx_v_strlabel); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 614, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_7);
        __Pyx_DECREF_SET(__pyx_v_strlabel, __pyx_t_7);
        __pyx_t_7 = 0;
+615: 				if self.fanout[n] > 1 and splitprune:
      __pyx_t_3 = (((__pyx_v_self->fanout[__pyx_v_n]) > 1) != 0);
      if (__pyx_t_3) {
      } else {
        __pyx_t_1 = __pyx_t_3;
        goto __pyx_L25_bool_binop_done;
      }
      __pyx_t_3 = (__pyx_v_splitprune != 0);
      __pyx_t_1 = __pyx_t_3;
      __pyx_L25_bool_binop_done:;
      if (__pyx_t_1) {
/* … */
      }
+616: 					strlabel += '*'
        __pyx_t_7 = PyNumber_InPlaceAdd(__pyx_v_strlabel, __pyx_kp_u__12); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 616, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_7);
        __Pyx_DECREF_SET(__pyx_v_strlabel, __pyx_t_7);
        __pyx_t_7 = 0;
+617: 				if self.fanout[n] > 1 and splitprune and markorigin:
      __pyx_t_3 = (((__pyx_v_self->fanout[__pyx_v_n]) > 1) != 0);
      if (__pyx_t_3) {
      } else {
        __pyx_t_1 = __pyx_t_3;
        goto __pyx_L28_bool_binop_done;
      }
      __pyx_t_3 = (__pyx_v_splitprune != 0);
      if (__pyx_t_3) {
      } else {
        __pyx_t_1 = __pyx_t_3;
        goto __pyx_L28_bool_binop_done;
      }
      __pyx_t_3 = (__pyx_v_markorigin != 0);
      __pyx_t_1 = __pyx_t_3;
      __pyx_L28_bool_binop_done:;
      if (__pyx_t_1) {
/* … */
        goto __pyx_L27;
      }
+618: 					result[n] = self.nonterminals  # sentinel value
        __pyx_t_12 = __pyx_v_self->nonterminals;
        (__pyx_v_result[__pyx_v_n]) = __pyx_t_12;
+619: 					self.splitmapping[n] = &(self.splitmapping[0][components])
        (__pyx_v_self->splitmapping[__pyx_v_n]) = (&((__pyx_v_self->splitmapping[0])[__pyx_v_components]));
+620: 					components += self.fanout[n]
        __pyx_v_components = (__pyx_v_components + (__pyx_v_self->fanout[__pyx_v_n]));
+621: 					for m in range(self.fanout[n]):
        __pyx_t_13 = (__pyx_v_self->fanout[__pyx_v_n]);
        for (__pyx_t_11 = 0; __pyx_t_11 < __pyx_t_13; __pyx_t_11+=1) {
          __pyx_v_m = __pyx_t_11;
+622: 						self.splitmapping[n][m] = coarse.toid[
          __pyx_t_7 = PyObject_GetItem(((PyObject *)__pyx_v_coarse->toid), __pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 622, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_7);
          __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
          __pyx_t_14 = __Pyx_PyInt_As_uint32_t(__pyx_t_7); if (unlikely((__pyx_t_14 == ((Label)-1)) && PyErr_Occurred())) __PYX_ERR(0, 622, __pyx_L1_error)
          __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
          ((__pyx_v_self->splitmapping[__pyx_v_n])[__pyx_v_m]) = __pyx_t_14;
+623: 								strlabel + str(m)]
          __pyx_t_7 = __Pyx_PyInt_From_int(__pyx_v_m); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 623, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_7);
          __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 623, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_6);
          __Pyx_GIVEREF(__pyx_t_7);
          PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_7);
          __pyx_t_7 = 0;
          __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)(&PyUnicode_Type)), __pyx_t_6, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 623, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_7);
          __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
          __pyx_t_6 = PyNumber_Add(__pyx_v_strlabel, __pyx_t_7); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 623, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_6);
          __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+624: 						seen.add(self.splitmapping[n][m])
          __pyx_t_7 = __Pyx_PyInt_From_uint32_t(((__pyx_v_self->splitmapping[__pyx_v_n])[__pyx_v_m])); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 624, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_7);
          __pyx_t_15 = PySet_Add(__pyx_v_seen, __pyx_t_7); if (unlikely(__pyx_t_15 == -1)) __PYX_ERR(0, 624, __pyx_L1_error)
          __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+625: 						if not selfmap:
          __pyx_t_1 = ((!(__pyx_v_selfmap != 0)) != 0);
          if (__pyx_t_1) {
/* … */
          }
        }
+626: 							self.revmap[self.splitmapping[n][m]].push_back(n)
            try {
              (__pyx_v_self->revmap[((__pyx_v_self->splitmapping[__pyx_v_n])[__pyx_v_m])]).push_back(__pyx_v_n);
            } catch(...) {
              __Pyx_CppExn2PyErr();
              __PYX_ERR(0, 626, __pyx_L1_error)
            }
 627: 				else:
+628: 					try:
      /*else*/ {
        {
          /*try:*/ {
/* … */
          }
          __Pyx_XDECREF(__pyx_t_16); __pyx_t_16 = 0;
          __Pyx_XDECREF(__pyx_t_17); __pyx_t_17 = 0;
          __Pyx_XDECREF(__pyx_t_18); __pyx_t_18 = 0;
          goto __pyx_L41_try_end;
          __pyx_L34_error:;
          __Pyx_PyThreadState_assign
          __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
          __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
          __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
          __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
          __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
/* … */
          __Pyx_PyThreadState_assign
          __Pyx_XGIVEREF(__pyx_t_16);
          __Pyx_XGIVEREF(__pyx_t_17);
          __Pyx_XGIVEREF(__pyx_t_18);
          __Pyx_ExceptionReset(__pyx_t_16, __pyx_t_17, __pyx_t_18);
          goto __pyx_L1_error;
          __pyx_L41_try_end:;
        }
      }
      __pyx_L27:;
+629: 						result[n] = coarse.toid[strlabel]
            __pyx_t_7 = PyObject_GetItem(((PyObject *)__pyx_v_coarse->toid), __pyx_v_strlabel); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 629, __pyx_L34_error)
            __Pyx_GOTREF(__pyx_t_7);
            __pyx_t_19 = __Pyx_PyInt_As_uint32_t(__pyx_t_7); if (unlikely((__pyx_t_19 == ((uint32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 629, __pyx_L34_error)
            __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
            (__pyx_v_result[__pyx_v_n]) = __pyx_t_19;
+630: 						if not selfmap:
            __pyx_t_1 = ((!(__pyx_v_selfmap != 0)) != 0);
            if (__pyx_t_1) {
/* … */
            }
+631: 							self.revmap[result[n]].push_back(n)
              try {
                (__pyx_v_self->revmap[(__pyx_v_result[__pyx_v_n])]).push_back(__pyx_v_n);
              } catch(...) {
                __Pyx_CppExn2PyErr();
                __PYX_ERR(0, 631, __pyx_L34_error)
              }
+632: 					except KeyError:
          __pyx_t_11 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError);
          if (__pyx_t_11) {
            __Pyx_AddTraceback("discodop.containers.Grammar.getmapping", __pyx_clineno, __pyx_lineno, __pyx_filename);
            if (__Pyx_GetException(&__pyx_t_7, &__pyx_t_6, &__pyx_t_2) < 0) __PYX_ERR(0, 632, __pyx_L36_except_error)
            __Pyx_GOTREF(__pyx_t_7);
            __Pyx_GOTREF(__pyx_t_6);
            __Pyx_GOTREF(__pyx_t_2);
+633: 						raise KeyError('incorrect mapping; '
            __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 633, __pyx_L36_except_error)
            __Pyx_GOTREF(__pyx_t_9);
            __Pyx_GIVEREF(__pyx_t_10);
            PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_10);
            __pyx_t_10 = 0;
            __pyx_t_10 = __Pyx_PyObject_Call(__pyx_builtin_KeyError, __pyx_t_9, NULL); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 633, __pyx_L36_except_error)
            __Pyx_GOTREF(__pyx_t_10);
            __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
            __Pyx_Raise(__pyx_t_10, 0, 0, 0);
            __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
            __PYX_ERR(0, 633, __pyx_L36_except_error)
          }
          goto __pyx_L36_except_error;
          __pyx_L36_except_error:;
+634: 								'coarse label %s not found, mapped from %s' % (
            __pyx_t_10 = PyUnicode_Format(__pyx_kp_u_incorrect_mapping_coarse_label_s, __pyx_t_9); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 634, __pyx_L36_except_error)
            __Pyx_GOTREF(__pyx_t_10);
            __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+635: 								strlabel, self.tolabel[n]))
            __pyx_t_10 = __Pyx_GetItemInt(((PyObject *)__pyx_v_self->tolabel), __pyx_v_n, int, 1, __Pyx_PyInt_From_int, 0, 0, 0); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 635, __pyx_L36_except_error)
            __Pyx_GOTREF(__pyx_t_10);
            __pyx_t_9 = PyTuple_New(2); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 635, __pyx_L36_except_error)
            __Pyx_GOTREF(__pyx_t_9);
            __Pyx_INCREF(__pyx_v_strlabel);
            __Pyx_GIVEREF(__pyx_v_strlabel);
            PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_v_strlabel);
            __Pyx_GIVEREF(__pyx_t_10);
            PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_t_10);
            __pyx_t_10 = 0;
 636: 			else:
+637: 				result[n] = 0
    /*else*/ {
      (__pyx_v_result[__pyx_v_n]) = 0;
    }
    __pyx_L19:;
  }
+638: 		if seen == set(range(coarse.nonterminals)):
  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_v_coarse->nonterminals); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 638, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 638, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __Pyx_GIVEREF(__pyx_t_2);
  PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_2);
  __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_range, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 638, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  __pyx_t_6 = PySet_New(__pyx_t_2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 638, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = PyObject_RichCompare(__pyx_v_seen, __pyx_t_6, Py_EQ); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 638, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 638, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  if (__pyx_t_1) {
/* … */
    goto __pyx_L45;
  }
+639: 			msg = 'label sets are equal'
    __Pyx_INCREF(__pyx_kp_u_label_sets_are_equal);
    __pyx_v_msg = __pyx_kp_u_label_sets_are_equal;
 640: 		else:
 641: 			# NB: ALL fine symbols are mapped to some coarse symbol;
 642: 			# we only check if all coarse symbols have received a mapping.
+643: 			l = sorted([coarse.tolabel[a] for a in
  /*else*/ {
    { /* enter inner scope */
      PyObject *__pyx_8genexpr2__pyx_v_a = NULL;
      __pyx_t_6 = PyList_New(0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 643, __pyx_L48_error)
      __Pyx_GOTREF(__pyx_t_6);
/* … */
        __pyx_t_7 = PyObject_GetItem(((PyObject *)__pyx_v_coarse->tolabel), __pyx_8genexpr2__pyx_v_a); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 643, __pyx_L48_error)
        __Pyx_GOTREF(__pyx_t_7);
        if (unlikely(__Pyx_ListComp_Append(__pyx_t_6, (PyObject*)__pyx_t_7))) __PYX_ERR(0, 643, __pyx_L48_error)
        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      }
      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
      __Pyx_XDECREF(__pyx_8genexpr2__pyx_v_a);
      goto __pyx_L51_exit_scope;
      __pyx_L48_error:;
      __Pyx_XDECREF(__pyx_8genexpr2__pyx_v_a);
      goto __pyx_L1_error;
      __pyx_L51_exit_scope:;
    } /* exit inner scope */
    __pyx_t_2 = ((PyObject*)__pyx_t_6);
    __pyx_t_6 = 0;
    __pyx_t_15 = PyList_Sort(__pyx_t_2); if (unlikely(__pyx_t_15 == -1)) __PYX_ERR(0, 643, __pyx_L1_error)
    __pyx_v_l = ((PyObject*)__pyx_t_2);
    __pyx_t_2 = 0;
+644: 					set(range(coarse.nonterminals)) - seen])
      __pyx_t_7 = __Pyx_PyInt_FromSize_t(__pyx_v_coarse->nonterminals); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 644, __pyx_L48_error)
      __Pyx_GOTREF(__pyx_t_7);
      __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 644, __pyx_L48_error)
      __Pyx_GOTREF(__pyx_t_10);
      __Pyx_GIVEREF(__pyx_t_7);
      PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_7);
      __pyx_t_7 = 0;
      __pyx_t_7 = __Pyx_PyObject_Call(__pyx_builtin_range, __pyx_t_10, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 644, __pyx_L48_error)
      __Pyx_GOTREF(__pyx_t_7);
      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
      __pyx_t_10 = PySet_New(__pyx_t_7); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 644, __pyx_L48_error)
      __Pyx_GOTREF(__pyx_t_10);
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      __pyx_t_7 = PyNumber_Subtract(__pyx_t_10, __pyx_v_seen); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 644, __pyx_L48_error)
      __Pyx_GOTREF(__pyx_t_7);
      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
      if (likely(PyList_CheckExact(__pyx_t_7)) || PyTuple_CheckExact(__pyx_t_7)) {
        __pyx_t_10 = __pyx_t_7; __Pyx_INCREF(__pyx_t_10); __pyx_t_20 = 0;
        __pyx_t_21 = NULL;
      } else {
        __pyx_t_20 = -1; __pyx_t_10 = PyObject_GetIter(__pyx_t_7); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 644, __pyx_L48_error)
        __Pyx_GOTREF(__pyx_t_10);
        __pyx_t_21 = Py_TYPE(__pyx_t_10)->tp_iternext; if (unlikely(!__pyx_t_21)) __PYX_ERR(0, 644, __pyx_L48_error)
      }
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      for (;;) {
        if (likely(!__pyx_t_21)) {
          if (likely(PyList_CheckExact(__pyx_t_10))) {
            if (__pyx_t_20 >= PyList_GET_SIZE(__pyx_t_10)) break;
            #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
            __pyx_t_7 = PyList_GET_ITEM(__pyx_t_10, __pyx_t_20); __Pyx_INCREF(__pyx_t_7); __pyx_t_20++; if (unlikely(0 < 0)) __PYX_ERR(0, 644, __pyx_L48_error)
            #else
            __pyx_t_7 = PySequence_ITEM(__pyx_t_10, __pyx_t_20); __pyx_t_20++; if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 644, __pyx_L48_error)
            __Pyx_GOTREF(__pyx_t_7);
            #endif
          } else {
            if (__pyx_t_20 >= PyTuple_GET_SIZE(__pyx_t_10)) break;
            #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
            __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_10, __pyx_t_20); __Pyx_INCREF(__pyx_t_7); __pyx_t_20++; if (unlikely(0 < 0)) __PYX_ERR(0, 644, __pyx_L48_error)
            #else
            __pyx_t_7 = PySequence_ITEM(__pyx_t_10, __pyx_t_20); __pyx_t_20++; if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 644, __pyx_L48_error)
            __Pyx_GOTREF(__pyx_t_7);
            #endif
          }
        } else {
          __pyx_t_7 = __pyx_t_21(__pyx_t_10);
          if (unlikely(!__pyx_t_7)) {
            PyObject* exc_type = PyErr_Occurred();
            if (exc_type) {
              if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
              else __PYX_ERR(0, 644, __pyx_L48_error)
            }
            break;
          }
          __Pyx_GOTREF(__pyx_t_7);
        }
        __Pyx_XDECREF_SET(__pyx_8genexpr2__pyx_v_a, __pyx_t_7);
        __pyx_t_7 = 0;
+645: 			diff = ', '.join(l[:10]) + (', ...' if len(l) > 10 else '')
    if (unlikely(__pyx_v_l == Py_None)) {
      PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
      __PYX_ERR(0, 645, __pyx_L1_error)
    }
    __pyx_t_2 = __Pyx_PyList_GetSlice(__pyx_v_l, 0, 10); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 645, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_6 = PyUnicode_Join(__pyx_kp_u__13, __pyx_t_2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 645, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    if (unlikely(__pyx_v_l == Py_None)) {
      PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()");
      __PYX_ERR(0, 645, __pyx_L1_error)
    }
    __pyx_t_20 = PyList_GET_SIZE(__pyx_v_l); if (unlikely(__pyx_t_20 == -1)) __PYX_ERR(0, 645, __pyx_L1_error)
    if (((__pyx_t_20 > 10) != 0)) {
      __Pyx_INCREF(__pyx_kp_u__14);
      __pyx_t_2 = __pyx_kp_u__14;
    } else {
      __Pyx_INCREF(__pyx_kp_u__11);
      __pyx_t_2 = __pyx_kp_u__11;
    }
    __pyx_t_10 = __Pyx_PyUnicode_ConcatSafe(__pyx_t_6, __pyx_t_2); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 645, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_10);
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __pyx_v_diff = ((PyObject*)__pyx_t_10);
    __pyx_t_10 = 0;
+646: 			if coarse.nonterminals > self.nonterminals:
    __pyx_t_1 = ((__pyx_v_coarse->nonterminals > __pyx_v_self->nonterminals) != 0);
    if (__pyx_t_1) {
/* … */
      goto __pyx_L52;
    }
 647: 				msg = ('grammar is not a superset of coarse grammar:\n'
+648: 						'coarse labels without mapping: { %s }' % diff)
      __pyx_t_10 = PyUnicode_Format(__pyx_kp_u_grammar_is_not_a_superset_of_coa, __pyx_v_diff); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 648, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_10);
      __pyx_v_msg = ((PyObject*)__pyx_t_10);
      __pyx_t_10 = 0;
+649: 			elif coarse.nonterminals < self.nonterminals:
    __pyx_t_1 = ((__pyx_v_coarse->nonterminals < __pyx_v_self->nonterminals) != 0);
    if (__pyx_t_1) {
/* … */
      goto __pyx_L52;
    }
+650: 				msg = 'grammar is a proper superset of coarse grammar.'
      __Pyx_INCREF(__pyx_kp_u_grammar_is_a_proper_superset_of);
      __pyx_v_msg = __pyx_kp_u_grammar_is_a_proper_superset_of;
 651: 			else:
 652: 				msg = ('equal number of nodes, but not equivalent:\n'
+653: 						'coarse labels without mapping: { %s }' % diff)
    /*else*/ {
      __pyx_t_10 = PyUnicode_Format(__pyx_kp_u_equal_number_of_nodes_but_not_eq, __pyx_v_diff); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 653, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_10);
      __pyx_v_msg = ((PyObject*)__pyx_t_10);
      __pyx_t_10 = 0;
    }
    __pyx_L52:;
  }
  __pyx_L45:;
+654: 		return msg
  __Pyx_XDECREF(__pyx_r);
  __Pyx_INCREF(__pyx_v_msg);
  __pyx_r = __pyx_v_msg;
  goto __pyx_L0;
 655: 
+656: 	def getrulemapping(Grammar self, Grammar coarse, striplabelre):
/* Python wrapper */
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_21getrulemapping(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_8discodop_10containers_7Grammar_20getrulemapping[] = "Grammar.getrulemapping(self, Grammar coarse, striplabelre)\nProduce a mapping of coarse rules to sets of fine rules.\n\n\t\tA coarse rule for a given fine rule is found by applying the label\n\t\tmapping to rules. The rule mapping uses the rule numbers (``rule.no``)\n\t\tderived from the original order of the rules when the Grammar object\n\t\twas created; e.g., ``self.rulemapping[12] == [34, 56, 78, ...]``\n\t\twhere 12 refers to a rule in the given coarse grammar, and the other\n\t\tIDs to rules in this grammar.";
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_21getrulemapping(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  struct __pyx_obj_8discodop_10containers_Grammar *__pyx_v_coarse = 0;
  PyObject *__pyx_v_striplabelre = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("getrulemapping (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_coarse,&__pyx_n_s_striplabelre,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);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = PyDict_Size(__pyx_kwds);
      switch (pos_args) {
        case  0:
        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_coarse)) != 0)) kw_args--;
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_striplabelre)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("getrulemapping", 1, 2, 2, 1); __PYX_ERR(0, 656, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "getrulemapping") < 0)) __PYX_ERR(0, 656, __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_coarse = ((struct __pyx_obj_8discodop_10containers_Grammar *)values[0]);
    __pyx_v_striplabelre = values[1];
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("getrulemapping", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 656, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("discodop.containers.Grammar.getrulemapping", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_coarse), __pyx_ptype_8discodop_10containers_Grammar, 1, "coarse", 0))) __PYX_ERR(0, 656, __pyx_L1_error)
  __pyx_r = __pyx_pf_8discodop_10containers_7Grammar_20getrulemapping(((struct __pyx_obj_8discodop_10containers_Grammar *)__pyx_v_self), __pyx_v_coarse, __pyx_v_striplabelre);

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_8discodop_10containers_7Grammar_20getrulemapping(struct __pyx_obj_8discodop_10containers_Grammar *__pyx_v_self, struct __pyx_obj_8discodop_10containers_Grammar *__pyx_v_coarse, PyObject *__pyx_v_striplabelre) {
  int __pyx_v_n;
  int __pyx_v_m;
  ProbRule *__pyx_v_rule;
  Rule __pyx_v_key;
  PyObject *__pyx_v_rulemapping = 0;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("getrulemapping", 0);
/* … */
  /* function exit code */
  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_XDECREF(__pyx_t_9);
  __Pyx_AddTraceback("discodop.containers.Grammar.getrulemapping", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_rulemapping);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 657: 		"""Produce a mapping of coarse rules to sets of fine rules.
 658: 
 659: 		A coarse rule for a given fine rule is found by applying the label
 660: 		mapping to rules. The rule mapping uses the rule numbers (``rule.no``)
 661: 		derived from the original order of the rules when the Grammar object
 662: 		was created; e.g., ``self.rulemapping[12] == [34, 56, 78, ...]``
 663: 		where 12 refers to a rule in the given coarse grammar, and the other
 664: 		IDs to rules in this grammar."""
 665: 		cdef int n, m
 666: 		cdef ProbRule *rule
 667: 		cdef Rule key
+668: 		cdef list rulemapping = [array('L') for _ in range(coarse.numrules)]
  { /* enter inner scope */
    CYTHON_UNUSED size_t __pyx_8genexpr3__pyx_v__;
    __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 668, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_2 = __pyx_v_coarse->numrules;
    for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
      __pyx_8genexpr3__pyx_v__ = __pyx_t_3;
      __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_7cpython_5array_array), __pyx_tuple__15, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 668, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_4))) __PYX_ERR(0, 668, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    }
  } /* exit inner scope */
  __pyx_v_rulemapping = ((PyObject*)__pyx_t_1);
  __pyx_t_1 = 0;
/* … */
  __pyx_tuple__15 = PyTuple_Pack(1, __pyx_n_u_L); if (unlikely(!__pyx_tuple__15)) __PYX_ERR(0, 668, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__15);
  __Pyx_GIVEREF(__pyx_tuple__15);
+669: 		for n in range(self.numrules):
  __pyx_t_2 = __pyx_v_self->numrules;
  for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_2; __pyx_t_5+=1) {
    __pyx_v_n = __pyx_t_5;
+670: 			rule = &(self.bylhs[0][n])
    __pyx_v_rule = (&((__pyx_v_self->bylhs[0])[__pyx_v_n]));
 671: 			# this could work, but only if mapping[..] is never 0.
 672: 			# key.lhs = self.mapping[rule.lhs]
 673: 			# key.rhs1 = self.mapping[rule.rhs1]
 674: 			# key.rhs2 = self.mapping[rule.rhs2]
+675: 			key.lhs = coarse.toid[striplabelre.sub(
    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_striplabelre, __pyx_n_s_sub); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 675, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
/* … */
    __pyx_t_4 = PyObject_GetItem(((PyObject *)__pyx_v_coarse->toid), __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 675, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_t_10 = __Pyx_PyInt_As_uint32_t(__pyx_t_4); if (unlikely((__pyx_t_10 == ((Label)-1)) && PyErr_Occurred())) __PYX_ERR(0, 675, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __pyx_v_key.lhs = __pyx_t_10;
+676: 					'', self.tolabel[rule.lhs], 1)]
    __pyx_t_6 = __Pyx_GetItemInt(((PyObject *)__pyx_v_self->tolabel), __pyx_v_rule->lhs, Label, 0, __Pyx_PyInt_From_uint32_t, 0, 0, 0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 676, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __pyx_t_7 = NULL;
    __pyx_t_8 = 0;
    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) {
      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_4);
      if (likely(__pyx_t_7)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
        __Pyx_INCREF(__pyx_t_7);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_4, function);
        __pyx_t_8 = 1;
      }
    }
    #if CYTHON_FAST_PYCALL
    if (PyFunction_Check(__pyx_t_4)) {
      PyObject *__pyx_temp[4] = {__pyx_t_7, __pyx_kp_u__11, __pyx_t_6, __pyx_int_1};
      __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_8, 3+__pyx_t_8); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 675, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    } else
    #endif
    #if CYTHON_FAST_PYCCALL
    if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
      PyObject *__pyx_temp[4] = {__pyx_t_7, __pyx_kp_u__11, __pyx_t_6, __pyx_int_1};
      __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_8, 3+__pyx_t_8); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 675, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    } else
    #endif
    {
      __pyx_t_9 = PyTuple_New(3+__pyx_t_8); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 675, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_9);
      if (__pyx_t_7) {
        __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __pyx_t_7 = NULL;
      }
      __Pyx_INCREF(__pyx_kp_u__11);
      __Pyx_GIVEREF(__pyx_kp_u__11);
      PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_8, __pyx_kp_u__11);
      __Pyx_GIVEREF(__pyx_t_6);
      PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_8, __pyx_t_6);
      __Pyx_INCREF(__pyx_int_1);
      __Pyx_GIVEREF(__pyx_int_1);
      PyTuple_SET_ITEM(__pyx_t_9, 2+__pyx_t_8, __pyx_int_1);
      __pyx_t_6 = 0;
      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_9, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 675, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
    }
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+677: 			key.rhs1 = coarse.toid[striplabelre.sub(
    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_striplabelre, __pyx_n_s_sub); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 677, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
/* … */
    __pyx_t_1 = PyObject_GetItem(((PyObject *)__pyx_v_coarse->toid), __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 677, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __pyx_t_10 = __Pyx_PyInt_As_uint32_t(__pyx_t_1); if (unlikely((__pyx_t_10 == ((Label)-1)) && PyErr_Occurred())) __PYX_ERR(0, 677, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_v_key.rhs1 = __pyx_t_10;
+678: 					'', self.tolabel[rule.rhs1], 1)]
    __pyx_t_9 = __Pyx_GetItemInt(((PyObject *)__pyx_v_self->tolabel), __pyx_v_rule->rhs1, Label, 0, __Pyx_PyInt_From_uint32_t, 0, 0, 0); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 678, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_9);
    __pyx_t_6 = NULL;
    __pyx_t_8 = 0;
    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_1))) {
      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_1);
      if (likely(__pyx_t_6)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
        __Pyx_INCREF(__pyx_t_6);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_1, function);
        __pyx_t_8 = 1;
      }
    }
    #if CYTHON_FAST_PYCALL
    if (PyFunction_Check(__pyx_t_1)) {
      PyObject *__pyx_temp[4] = {__pyx_t_6, __pyx_kp_u__11, __pyx_t_9, __pyx_int_1};
      __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_1, __pyx_temp+1-__pyx_t_8, 3+__pyx_t_8); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 677, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
    } else
    #endif
    #if CYTHON_FAST_PYCCALL
    if (__Pyx_PyFastCFunction_Check(__pyx_t_1)) {
      PyObject *__pyx_temp[4] = {__pyx_t_6, __pyx_kp_u__11, __pyx_t_9, __pyx_int_1};
      __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_1, __pyx_temp+1-__pyx_t_8, 3+__pyx_t_8); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 677, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
    } else
    #endif
    {
      __pyx_t_7 = PyTuple_New(3+__pyx_t_8); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 677, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      if (__pyx_t_6) {
        __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __pyx_t_6 = NULL;
      }
      __Pyx_INCREF(__pyx_kp_u__11);
      __Pyx_GIVEREF(__pyx_kp_u__11);
      PyTuple_SET_ITEM(__pyx_t_7, 0+__pyx_t_8, __pyx_kp_u__11);
      __Pyx_GIVEREF(__pyx_t_9);
      PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_8, __pyx_t_9);
      __Pyx_INCREF(__pyx_int_1);
      __Pyx_GIVEREF(__pyx_int_1);
      PyTuple_SET_ITEM(__pyx_t_7, 2+__pyx_t_8, __pyx_int_1);
      __pyx_t_9 = 0;
      __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_7, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 677, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    }
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+679: 			key.rhs2 = coarse.toid[striplabelre.sub(
    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_striplabelre, __pyx_n_s_sub); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 679, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
/* … */
    __pyx_t_4 = PyObject_GetItem(((PyObject *)__pyx_v_coarse->toid), __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 679, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_t_10 = __Pyx_PyInt_As_uint32_t(__pyx_t_4); if (unlikely((__pyx_t_10 == ((Label)-1)) && PyErr_Occurred())) __PYX_ERR(0, 679, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __pyx_v_key.rhs2 = __pyx_t_10;
+680: 					'', self.tolabel[rule.rhs2], 1)]
    __pyx_t_7 = __Pyx_GetItemInt(((PyObject *)__pyx_v_self->tolabel), __pyx_v_rule->rhs2, Label, 0, __Pyx_PyInt_From_uint32_t, 0, 0, 0); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 680, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_7);
    __pyx_t_9 = NULL;
    __pyx_t_8 = 0;
    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) {
      __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_4);
      if (likely(__pyx_t_9)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
        __Pyx_INCREF(__pyx_t_9);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_4, function);
        __pyx_t_8 = 1;
      }
    }
    #if CYTHON_FAST_PYCALL
    if (PyFunction_Check(__pyx_t_4)) {
      PyObject *__pyx_temp[4] = {__pyx_t_9, __pyx_kp_u__11, __pyx_t_7, __pyx_int_1};
      __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_8, 3+__pyx_t_8); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 679, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    } else
    #endif
    #if CYTHON_FAST_PYCCALL
    if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
      PyObject *__pyx_temp[4] = {__pyx_t_9, __pyx_kp_u__11, __pyx_t_7, __pyx_int_1};
      __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_8, 3+__pyx_t_8); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 679, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    } else
    #endif
    {
      __pyx_t_6 = PyTuple_New(3+__pyx_t_8); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 679, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      if (__pyx_t_9) {
        __Pyx_GIVEREF(__pyx_t_9); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_9); __pyx_t_9 = NULL;
      }
      __Pyx_INCREF(__pyx_kp_u__11);
      __Pyx_GIVEREF(__pyx_kp_u__11);
      PyTuple_SET_ITEM(__pyx_t_6, 0+__pyx_t_8, __pyx_kp_u__11);
      __Pyx_GIVEREF(__pyx_t_7);
      PyTuple_SET_ITEM(__pyx_t_6, 1+__pyx_t_8, __pyx_t_7);
      __Pyx_INCREF(__pyx_int_1);
      __Pyx_GIVEREF(__pyx_int_1);
      PyTuple_SET_ITEM(__pyx_t_6, 2+__pyx_t_8, __pyx_int_1);
      __pyx_t_7 = 0;
      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 679, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    }
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+681: 			key.args, key.lengths = rule.args, rule.lengths
    __pyx_t_11 = __pyx_v_rule->args;
    __pyx_t_12 = __pyx_v_rule->lengths;
    __pyx_v_key.args = __pyx_t_11;
    __pyx_v_key.lengths = __pyx_t_12;
+682: 			m = coarse.rulenos[key]
    __pyx_v_m = (__pyx_v_coarse->rulenos[__pyx_v_key]);
+683: 			rulemapping[m].append(rule.no)
    __pyx_t_4 = __Pyx_PyInt_From_uint32_t(__pyx_v_rule->no); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 683, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __pyx_t_13 = __Pyx_PyObject_Append(PyList_GET_ITEM(__pyx_v_rulemapping, __pyx_v_m), __pyx_t_4); if (unlikely(__pyx_t_13 == -1)) __PYX_ERR(0, 683, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  }
+684: 		if self is coarse:
  __pyx_t_14 = (__pyx_v_self == __pyx_v_coarse);
  __pyx_t_15 = (__pyx_t_14 != 0);
  if (__pyx_t_15) {
/* … */
    goto __pyx_L7;
  }
+685: 			self.selfrulemapping = rulemapping
    __Pyx_INCREF(__pyx_v_rulemapping);
    __Pyx_GIVEREF(__pyx_v_rulemapping);
    __Pyx_GOTREF(__pyx_v_self->selfrulemapping);
    __Pyx_DECREF(__pyx_v_self->selfrulemapping);
    __pyx_v_self->selfrulemapping = __pyx_v_rulemapping;
 686: 		else:
+687: 			self.rulemapping = rulemapping
  /*else*/ {
    __Pyx_INCREF(__pyx_v_rulemapping);
    __Pyx_GIVEREF(__pyx_v_rulemapping);
    __Pyx_GOTREF(__pyx_v_self->rulemapping);
    __Pyx_DECREF(__pyx_v_self->rulemapping);
    __pyx_v_self->rulemapping = __pyx_v_rulemapping;
  }
  __pyx_L7:;
 688: 
+689: 	cpdef noderuleno(self, node):
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_23noderuleno(PyObject *__pyx_v_self, PyObject *__pyx_v_node); /*proto*/
static PyObject *__pyx_f_8discodop_10containers_7Grammar_noderuleno(struct __pyx_obj_8discodop_10containers_Grammar *__pyx_v_self, PyObject *__pyx_v_node, CYTHON_UNUSED int __pyx_skip_dispatch) {
  Rule __pyx_v_key;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("noderuleno", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_AddTraceback("discodop.containers.Grammar.noderuleno", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = 0;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

/* Python wrapper */
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_23noderuleno(PyObject *__pyx_v_self, PyObject *__pyx_v_node); /*proto*/
static char __pyx_doc_8discodop_10containers_7Grammar_22noderuleno[] = "Grammar.noderuleno(self, node)\nGet rule no given a node of a continuous tree.";
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_23noderuleno(PyObject *__pyx_v_self, PyObject *__pyx_v_node) {
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("noderuleno (wrapper)", 0);
  __pyx_r = __pyx_pf_8discodop_10containers_7Grammar_22noderuleno(((struct __pyx_obj_8discodop_10containers_Grammar *)__pyx_v_self), ((PyObject *)__pyx_v_node));

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_8discodop_10containers_7Grammar_22noderuleno(struct __pyx_obj_8discodop_10containers_Grammar *__pyx_v_self, PyObject *__pyx_v_node) {
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("noderuleno", 0);
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_1 = __pyx_f_8discodop_10containers_7Grammar_noderuleno(__pyx_v_self, __pyx_v_node, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 689, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_r = __pyx_t_1;
  __pyx_t_1 = 0;
  goto __pyx_L0;

  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_AddTraceback("discodop.containers.Grammar.noderuleno", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 690: 		"""Get rule no given a node of a continuous tree."""
 691: 		cdef Rule key
+692: 		key.lhs = self.toid.ob[node.label.encode('utf8')]
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_node, __pyx_n_s_label); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 692, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_encode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 692, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__16, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 692, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 692, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_key.lhs = (__pyx_v_self->toid->ob[__pyx_t_3]);
/* … */
  __pyx_tuple__16 = PyTuple_Pack(1, __pyx_n_u_utf8); if (unlikely(!__pyx_tuple__16)) __PYX_ERR(0, 692, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__16);
  __Pyx_GIVEREF(__pyx_tuple__16);
+693: 		key.rhs1 = self.toid.ob[node[0].label.encode('utf8')]
  __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_node, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 693, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_label); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 693, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_encode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 693, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__17, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 693, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 693, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_v_key.rhs1 = (__pyx_v_self->toid->ob[__pyx_t_3]);
/* … */
  __pyx_tuple__17 = PyTuple_Pack(1, __pyx_n_u_utf8); if (unlikely(!__pyx_tuple__17)) __PYX_ERR(0, 693, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__17);
  __Pyx_GIVEREF(__pyx_tuple__17);
+694: 		if len(node) > 1:
  __pyx_t_4 = PyObject_Length(__pyx_v_node); if (unlikely(__pyx_t_4 == -1)) __PYX_ERR(0, 694, __pyx_L1_error)
  __pyx_t_5 = ((__pyx_t_4 > 1) != 0);
  if (__pyx_t_5) {
/* … */
    goto __pyx_L3;
  }
+695: 			key.rhs2 = self.toid.ob[node[1].label.encode('utf8')]
    __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_node, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 695, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_label); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 695, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_encode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 695, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__18, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 695, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 695, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_v_key.rhs2 = (__pyx_v_self->toid->ob[__pyx_t_3]);
/* … */
  __pyx_tuple__18 = PyTuple_Pack(1, __pyx_n_u_utf8); if (unlikely(!__pyx_tuple__18)) __PYX_ERR(0, 695, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__18);
  __Pyx_GIVEREF(__pyx_tuple__18);
+696: 			key.args, key.lengths = 0b10, 0b10
    __pyx_t_6 = 2;
    __pyx_t_7 = 2;
    __pyx_v_key.args = __pyx_t_6;
    __pyx_v_key.lengths = __pyx_t_7;
 697: 		else:
+698: 			key.rhs2 = 0
  /*else*/ {
    __pyx_v_key.rhs2 = 0;
+699: 			key.args, key.lengths = 0b0, 0b1
    __pyx_t_7 = 0;
    __pyx_t_6 = 1;
    __pyx_v_key.args = __pyx_t_7;
    __pyx_v_key.lengths = __pyx_t_6;
  }
  __pyx_L3:;
+700: 		return self.rulenos[key]
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_1 = __Pyx_PyInt_From_uint32_t((__pyx_v_self->rulenos[__pyx_v_key])); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 700, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_r = __pyx_t_1;
  __pyx_t_1 = 0;
  goto __pyx_L0;
 701: 
+702: 	cpdef getruleno(self, tuple r, tuple yf):
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_25getruleno(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyObject *__pyx_f_8discodop_10containers_7Grammar_getruleno(struct __pyx_obj_8discodop_10containers_Grammar *__pyx_v_self, PyObject *__pyx_v_r, PyObject *__pyx_v_yf, CYTHON_UNUSED int __pyx_skip_dispatch) {
  Rule __pyx_v_key;
  PyObject *__pyx_v_lhs = 0;
  PyObject *__pyx_v_rhs1 = 0;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("getruleno", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_AddTraceback("discodop.containers.Grammar.getruleno", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = 0;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_lhs);
  __Pyx_XDECREF(__pyx_v_rhs1);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

/* Python wrapper */
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_25getruleno(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_8discodop_10containers_7Grammar_24getruleno[] = "Grammar.getruleno(self, tuple r, tuple yf)\nGet rule no given a (discontinuous) production.";
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_25getruleno(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_r = 0;
  PyObject *__pyx_v_yf = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("getruleno (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_r,&__pyx_n_s_yf,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);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = PyDict_Size(__pyx_kwds);
      switch (pos_args) {
        case  0:
        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_r)) != 0)) kw_args--;
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_yf)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("getruleno", 1, 2, 2, 1); __PYX_ERR(0, 702, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "getruleno") < 0)) __PYX_ERR(0, 702, __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_r = ((PyObject*)values[0]);
    __pyx_v_yf = ((PyObject*)values[1]);
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("getruleno", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 702, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("discodop.containers.Grammar.getruleno", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_r), (&PyTuple_Type), 1, "r", 1))) __PYX_ERR(0, 702, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_yf), (&PyTuple_Type), 1, "yf", 1))) __PYX_ERR(0, 702, __pyx_L1_error)
  __pyx_r = __pyx_pf_8discodop_10containers_7Grammar_24getruleno(((struct __pyx_obj_8discodop_10containers_Grammar *)__pyx_v_self), __pyx_v_r, __pyx_v_yf);

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_8discodop_10containers_7Grammar_24getruleno(struct __pyx_obj_8discodop_10containers_Grammar *__pyx_v_self, PyObject *__pyx_v_r, PyObject *__pyx_v_yf) {
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("getruleno", 0);
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_1 = __pyx_f_8discodop_10containers_7Grammar_getruleno(__pyx_v_self, __pyx_v_r, __pyx_v_yf, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 702, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_r = __pyx_t_1;
  __pyx_t_1 = 0;
  goto __pyx_L0;

  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_AddTraceback("discodop.containers.Grammar.getruleno", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 703: 		"""Get rule no given a (discontinuous) production."""
 704: 		cdef Rule key
+705: 		cdef bytes lhs = r[0].encode('utf8')
  if (unlikely(__pyx_v_r == Py_None)) {
    PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
    __PYX_ERR(0, 705, __pyx_L1_error)
  }
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(PyTuple_GET_ITEM(__pyx_v_r, 0), __pyx_n_s_encode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 705, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__19, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 705, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (!(likely(PyBytes_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_2)->tp_name), 0))) __PYX_ERR(0, 705, __pyx_L1_error)
  __pyx_v_lhs = ((PyObject*)__pyx_t_2);
  __pyx_t_2 = 0;
/* … */
  __pyx_tuple__19 = PyTuple_Pack(1, __pyx_n_u_utf8); if (unlikely(!__pyx_tuple__19)) __PYX_ERR(0, 705, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__19);
  __Pyx_GIVEREF(__pyx_tuple__19);
+706: 		cdef bytes rhs1 = r[1].encode('utf8')
  if (unlikely(__pyx_v_r == Py_None)) {
    PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
    __PYX_ERR(0, 706, __pyx_L1_error)
  }
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(PyTuple_GET_ITEM(__pyx_v_r, 1), __pyx_n_s_encode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 706, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__20, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 706, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  if (!(likely(PyBytes_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(0, 706, __pyx_L1_error)
  __pyx_v_rhs1 = ((PyObject*)__pyx_t_1);
  __pyx_t_1 = 0;
/* … */
  __pyx_tuple__20 = PyTuple_Pack(1, __pyx_n_u_utf8); if (unlikely(!__pyx_tuple__20)) __PYX_ERR(0, 706, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__20);
  __Pyx_GIVEREF(__pyx_tuple__20);
+707: 		key.lhs, key.rhs1 = self.toid.ob[lhs], self.toid.ob[rhs1]
  __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_v_lhs); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 707, __pyx_L1_error)
  __pyx_t_4 = (__pyx_v_self->toid->ob[__pyx_t_3]);
  __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_v_rhs1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 707, __pyx_L1_error)
  __pyx_t_5 = (__pyx_v_self->toid->ob[__pyx_t_3]);
  __pyx_v_key.lhs = __pyx_t_4;
  __pyx_v_key.rhs1 = __pyx_t_5;
+708: 		key.rhs2 = self.toid.ob[r[2].encode('utf8')] if len(r) > 2 else 0
  if (unlikely(__pyx_v_r == Py_None)) {
    PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()");
    __PYX_ERR(0, 708, __pyx_L1_error)
  }
  __pyx_t_6 = PyTuple_GET_SIZE(__pyx_v_r); if (unlikely(__pyx_t_6 == -1)) __PYX_ERR(0, 708, __pyx_L1_error)
  if (((__pyx_t_6 > 2) != 0)) {
    if (unlikely(__pyx_v_r == Py_None)) {
      PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
      __PYX_ERR(0, 708, __pyx_L1_error)
    }
    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(PyTuple_GET_ITEM(__pyx_v_r, 2), __pyx_n_s_encode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 708, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__21, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 708, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 708, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __pyx_t_5 = (__pyx_v_self->toid->ob[__pyx_t_3]);
  } else {
    __pyx_t_5 = 0;
  }
  __pyx_v_key.rhs2 = __pyx_t_5;
/* … */
  __pyx_tuple__21 = PyTuple_Pack(1, __pyx_n_u_utf8); if (unlikely(!__pyx_tuple__21)) __PYX_ERR(0, 708, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__21);
  __Pyx_GIVEREF(__pyx_tuple__21);
+709: 		getyf(yf, &key.args, &key.lengths)
  __pyx_t_2 = __pyx_f_8discodop_10containers_getyf(__pyx_v_yf, (&__pyx_v_key.args), (&__pyx_v_key.lengths)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 709, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+710: 		return self.rulenos[key]
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_2 = __Pyx_PyInt_From_uint32_t((__pyx_v_self->rulenos[__pyx_v_key])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 710, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_r = __pyx_t_2;
  __pyx_t_2 = 0;
  goto __pyx_L0;
 711: 
+712: 	cpdef rulestr(self, int n):
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_27rulestr(PyObject *__pyx_v_self, PyObject *__pyx_arg_n); /*proto*/
static PyObject *__pyx_f_8discodop_10containers_7Grammar_rulestr(struct __pyx_obj_8discodop_10containers_Grammar *__pyx_v_self, int __pyx_v_n, CYTHON_UNUSED int __pyx_skip_dispatch) {
  ProbRule __pyx_v_rule;
  PyObject *__pyx_v_left = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("rulestr", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_XDECREF(__pyx_t_8);
  __Pyx_AddTraceback("discodop.containers.Grammar.rulestr", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = 0;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_left);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

/* Python wrapper */
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_27rulestr(PyObject *__pyx_v_self, PyObject *__pyx_arg_n); /*proto*/
static char __pyx_doc_8discodop_10containers_7Grammar_26rulestr[] = "Grammar.rulestr(self, int n)\nReturn a string representation of a specific rule in this grammar.";
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_27rulestr(PyObject *__pyx_v_self, PyObject *__pyx_arg_n) {
  int __pyx_v_n;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("rulestr (wrapper)", 0);
  assert(__pyx_arg_n); {
    __pyx_v_n = __Pyx_PyInt_As_int(__pyx_arg_n); if (unlikely((__pyx_v_n == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 712, __pyx_L3_error)
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L3_error:;
  __Pyx_AddTraceback("discodop.containers.Grammar.rulestr", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_8discodop_10containers_7Grammar_26rulestr(((struct __pyx_obj_8discodop_10containers_Grammar *)__pyx_v_self), ((int)__pyx_v_n));

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_8discodop_10containers_7Grammar_26rulestr(struct __pyx_obj_8discodop_10containers_Grammar *__pyx_v_self, int __pyx_v_n) {
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("rulestr", 0);
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_1 = __pyx_f_8discodop_10containers_7Grammar_rulestr(__pyx_v_self, __pyx_v_n, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 712, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_r = __pyx_t_1;
  __pyx_t_1 = 0;
  goto __pyx_L0;

  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_AddTraceback("discodop.containers.Grammar.rulestr", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 713: 		"""Return a string representation of a specific rule in this grammar."""
 714: 		cdef ProbRule rule
+715: 		if not 0 <= n < self.numrules:
  __pyx_t_1 = (0 <= __pyx_v_n);
  if (__pyx_t_1) {
    __pyx_t_1 = (__pyx_v_n < __pyx_v_self->numrules);
  }
  __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
  if (__pyx_t_2) {
/* … */
  }
+716: 			raise ValueError('Out of range: %s' % n)
    __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_n); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 716, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __pyx_t_4 = PyUnicode_Format(__pyx_kp_u_Out_of_range_s, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 716, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 716, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_GIVEREF(__pyx_t_4);
    PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
    __pyx_t_4 = 0;
    __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 716, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __Pyx_Raise(__pyx_t_4, 0, 0, 0);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __PYX_ERR(0, 716, __pyx_L1_error)
+717: 		rule = self.bylhs[0][n]
  __pyx_v_rule = ((__pyx_v_self->bylhs[0])[__pyx_v_n]);
+718: 		left = '%.2f %s => %s%s' % (
  __pyx_t_6 = PyUnicode_Format(__pyx_kp_u_2f_s_s_s, __pyx_t_8); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 718, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
  __pyx_v_left = ((PyObject*)__pyx_t_6);
  __pyx_t_6 = 0;
+719: 			exp(-rule.prob) if self.logprob else rule.prob,
  if ((__pyx_v_self->logprob != 0)) {
    __pyx_t_3 = PyFloat_FromDouble(exp((-__pyx_v_rule.prob))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 719, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __pyx_t_4 = __pyx_t_3;
    __pyx_t_3 = 0;
  } else {
    __pyx_t_3 = PyFloat_FromDouble(__pyx_v_rule.prob); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 719, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __pyx_t_4 = __pyx_t_3;
    __pyx_t_3 = 0;
  }
/* … */
  __pyx_t_8 = PyTuple_New(4); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 719, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_8);
  __Pyx_GIVEREF(__pyx_t_4);
  PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_4);
  __Pyx_GIVEREF(__pyx_t_3);
  PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_5);
  PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_t_5);
  __Pyx_GIVEREF(__pyx_t_6);
  PyTuple_SET_ITEM(__pyx_t_8, 3, __pyx_t_6);
  __pyx_t_4 = 0;
  __pyx_t_3 = 0;
  __pyx_t_5 = 0;
  __pyx_t_6 = 0;
+720: 			self.tolabel[rule.lhs],
  __pyx_t_3 = __Pyx_GetItemInt(((PyObject *)__pyx_v_self->tolabel), __pyx_v_rule.lhs, Label, 0, __Pyx_PyInt_From_uint32_t, 0, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 720, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
+721: 			self.tolabel[rule.rhs1],
  __pyx_t_5 = __Pyx_GetItemInt(((PyObject *)__pyx_v_self->tolabel), __pyx_v_rule.rhs1, Label, 0, __Pyx_PyInt_From_uint32_t, 0, 0, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 721, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
+722: 			' %s' % self.tolabel[rule.rhs2]
    __pyx_t_7 = __Pyx_GetItemInt(((PyObject *)__pyx_v_self->tolabel), __pyx_v_rule.rhs2, Label, 0, __Pyx_PyInt_From_uint32_t, 0, 0, 0); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 722, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_7);
    __pyx_t_8 = PyUnicode_Format(__pyx_kp_u_s, __pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 722, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_8);
    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    __pyx_t_6 = __pyx_t_8;
    __pyx_t_8 = 0;
  } else {
    __Pyx_INCREF(__pyx_kp_u__11);
    __pyx_t_6 = __pyx_kp_u__11;
  }
+723: 				if rule.rhs2 else '')
  if ((__pyx_v_rule.rhs2 != 0)) {
+724: 		return '%s %s [%d]' % (left.ljust(40), self.yfstr(rule), rule.no)
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_left, __pyx_n_s_ljust); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 724, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_tuple__22, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 724, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_8);
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  __pyx_t_6 = __pyx_f_8discodop_10containers_7Grammar_yfstr(__pyx_v_self, __pyx_v_rule); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 724, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __pyx_t_5 = __Pyx_PyInt_From_uint32_t(__pyx_v_rule.no); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 724, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 724, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_8);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_8);
  __Pyx_GIVEREF(__pyx_t_6);
  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_6);
  __Pyx_GIVEREF(__pyx_t_5);
  PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_5);
  __pyx_t_8 = 0;
  __pyx_t_6 = 0;
  __pyx_t_5 = 0;
  __pyx_t_5 = PyUnicode_Format(__pyx_kp_u_s_s_d, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 724, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_r = __pyx_t_5;
  __pyx_t_5 = 0;
  goto __pyx_L0;
/* … */
  __pyx_tuple__22 = PyTuple_Pack(1, __pyx_int_40); if (unlikely(!__pyx_tuple__22)) __PYX_ERR(0, 724, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__22);
  __Pyx_GIVEREF(__pyx_tuple__22);
 725: 
+726: 	cdef yfstr(self, ProbRule rule):
static PyObject *__pyx_f_8discodop_10containers_7Grammar_yfstr(struct __pyx_obj_8discodop_10containers_Grammar *__pyx_v_self, ProbRule __pyx_v_rule) {
  int __pyx_v_n;
  int __pyx_v_m;
  PyObject *__pyx_v_result = 0;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("yfstr", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_AddTraceback("discodop.containers.Grammar.yfstr", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = 0;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_result);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
+727: 		cdef int n, m = 0
  __pyx_v_m = 0;
+728: 		cdef str result = ''
  __Pyx_INCREF(__pyx_kp_u__11);
  __pyx_v_result = __pyx_kp_u__11;
+729: 		for n in range(8 * sizeof(rule.args)):
  __pyx_t_1 = (8 * (sizeof(__pyx_v_rule.args)));
  for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
    __pyx_v_n = __pyx_t_2;
+730: 			result += '1' if (rule.args >> n) & 1 else '0'
    if ((((__pyx_v_rule.args >> __pyx_v_n) & 1) != 0)) {
      __Pyx_INCREF(__pyx_kp_u_1);
      __pyx_t_3 = __pyx_kp_u_1;
    } else {
      __Pyx_INCREF(__pyx_kp_u_0);
      __pyx_t_3 = __pyx_kp_u_0;
    }
    __pyx_t_4 = __Pyx_PyUnicode_ConcatSafe(__pyx_v_result, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 730, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __Pyx_DECREF_SET(__pyx_v_result, ((PyObject*)__pyx_t_4));
    __pyx_t_4 = 0;
+731: 			if (rule.lengths >> n) & 1:
    __pyx_t_5 = (((__pyx_v_rule.lengths >> __pyx_v_n) & 1) != 0);
    if (__pyx_t_5) {
/* … */
    }
  }
+732: 				m += 1
      __pyx_v_m = (__pyx_v_m + 1);
+733: 				if m == self.fanout[rule.lhs]:
      __pyx_t_5 = ((__pyx_v_m == (__pyx_v_self->fanout[__pyx_v_rule.lhs])) != 0);
      if (__pyx_t_5) {
/* … */
      }
+734: 					return result
        __Pyx_XDECREF(__pyx_r);
        __Pyx_INCREF(__pyx_v_result);
        __pyx_r = __pyx_v_result;
        goto __pyx_L0;
 735: 				else:
+736: 					result += ','
      /*else*/ {
        __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_v_result, __pyx_kp_u__23); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 736, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
        __Pyx_DECREF_SET(__pyx_v_result, ((PyObject*)__pyx_t_4));
        __pyx_t_4 = 0;
      }
+737: 		raise ValueError('illegal yield function expected %d components.\n'
  __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 737, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_7);
  __Pyx_GIVEREF(__pyx_t_6);
  PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6);
  __pyx_t_6 = 0;
  __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_7, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 737, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
  __Pyx_Raise(__pyx_t_6, 0, 0, 0);
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  __PYX_ERR(0, 737, __pyx_L1_error)
+738: 				'args: %s; lengths: %s' % (self.fanout[rule.lhs],
  __pyx_t_4 = __Pyx_PyInt_From_uint8_t((__pyx_v_self->fanout[__pyx_v_rule.lhs])); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 738, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
/* … */
  __pyx_t_7 = PyTuple_New(3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 738, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_7);
  __Pyx_GIVEREF(__pyx_t_4);
  PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_4);
  __Pyx_GIVEREF(__pyx_t_3);
  PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_6);
  PyTuple_SET_ITEM(__pyx_t_7, 2, __pyx_t_6);
  __pyx_t_4 = 0;
  __pyx_t_3 = 0;
  __pyx_t_6 = 0;
  __pyx_t_6 = PyUnicode_Format(__pyx_kp_u_illegal_yield_function_expected, __pyx_t_7); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 738, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+739: 				bin(rule.args), bin(rule.lengths)))
  __pyx_t_3 = __Pyx_PyInt_From_uint32_t(__pyx_v_rule.args); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 739, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 739, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __Pyx_GIVEREF(__pyx_t_3);
  PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_3);
  __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_bin, __pyx_t_6, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 739, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  __pyx_t_6 = __Pyx_PyInt_From_uint32_t(__pyx_v_rule.lengths); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 739, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 739, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_7);
  __Pyx_GIVEREF(__pyx_t_6);
  PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6);
  __pyx_t_6 = 0;
  __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_bin, __pyx_t_7, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 739, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
 740: 
+741: 	def getwords(self):
/* Python wrapper */
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_29getwords(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
static char __pyx_doc_8discodop_10containers_7Grammar_28getwords[] = "Grammar.getwords(self)\nReturn words in lexicon as list.";
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_29getwords(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("getwords (wrapper)", 0);
  __pyx_r = __pyx_pf_8discodop_10containers_7Grammar_28getwords(((struct __pyx_obj_8discodop_10containers_Grammar *)__pyx_v_self));

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_8discodop_10containers_7Grammar_28getwords(struct __pyx_obj_8discodop_10containers_Grammar *__pyx_v_self) {
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("getwords", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_AddTraceback("discodop.containers.Grammar.getwords", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 742: 		"""Return words in lexicon as list."""
+743: 		return [x.first.decode('utf8') for x in self.lexicalbyword]
  __Pyx_XDECREF(__pyx_r);
  { /* enter inner scope */
    std::pair<std::string,std::vector<uint32_t> >  __pyx_8genexpr4__pyx_v_x;
    __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 743, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_3 = &__pyx_v_self->lexicalbyword;
    __pyx_t_2 = __pyx_t_3->begin();
    for (;;) {
      if (!(__pyx_t_2 != __pyx_t_3->end())) break;
      __pyx_t_4 = *__pyx_t_2;
      ++__pyx_t_2;
      __pyx_8genexpr4__pyx_v_x = __pyx_t_4;
      __pyx_t_5 = __Pyx_decode_cpp_string(__pyx_8genexpr4__pyx_v_x.first, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 743, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_5))) __PYX_ERR(0, 743, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    }
  } /* exit inner scope */
  __pyx_r = __pyx_t_1;
  __pyx_t_1 = 0;
  goto __pyx_L0;
 744: 
+745: 	def getlexprobs(self, str word):
/* Python wrapper */
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_31getlexprobs(PyObject *__pyx_v_self, PyObject *__pyx_v_word); /*proto*/
static char __pyx_doc_8discodop_10containers_7Grammar_30getlexprobs[] = "Grammar.getlexprobs(self, unicode word)\nReturn a list of probabilities for a word.";
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_31getlexprobs(PyObject *__pyx_v_self, PyObject *__pyx_v_word) {
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("getlexprobs (wrapper)", 0);
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_word), (&PyUnicode_Type), 1, "word", 1))) __PYX_ERR(0, 745, __pyx_L1_error)
  __pyx_r = __pyx_pf_8discodop_10containers_7Grammar_30getlexprobs(((struct __pyx_obj_8discodop_10containers_Grammar *)__pyx_v_self), ((PyObject*)__pyx_v_word));

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_8discodop_10containers_7Grammar_30getlexprobs(struct __pyx_obj_8discodop_10containers_Grammar *__pyx_v_self, PyObject *__pyx_v_word) {
  spp::sparse_hash_map<std::string,std::vector<uint32_t> > ::iterator __pyx_v_it;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("getlexprobs", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_AddTraceback("discodop.containers.Grammar.getlexprobs", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 746: 		"""Return a list of probabilities for a word."""
+747: 		it = self.lexicalbyword.find(word.encode('utf8'))
  if (unlikely(__pyx_v_word == Py_None)) {
    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "encode");
    __PYX_ERR(0, 747, __pyx_L1_error)
  }
  __pyx_t_1 = PyUnicode_AsUTF8String(__pyx_v_word); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 747, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __pyx_convert_string_from_py_std__in_string(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 747, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_it = __pyx_v_self->lexicalbyword.find(__pyx_t_2);
+748: 		if it == self.lexicalbyword.end():
  __pyx_t_3 = ((__pyx_v_it == __pyx_v_self->lexicalbyword.end()) != 0);
  if (__pyx_t_3) {
/* … */
  }
+749: 			return []
    __Pyx_XDECREF(__pyx_r);
    __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 749, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_r = __pyx_t_1;
    __pyx_t_1 = 0;
    goto __pyx_L0;
+750: 		return [self.lexical[n].prob for n in dereference(it).second]
  __Pyx_XDECREF(__pyx_r);
  { /* enter inner scope */
    uint32_t __pyx_8genexpr5__pyx_v_n;
    __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 750, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_5 = &(*__pyx_v_it).second;
    __pyx_t_4 = __pyx_t_5->begin();
    for (;;) {
      if (!(__pyx_t_4 != __pyx_t_5->end())) break;
      __pyx_t_6 = *__pyx_t_4;
      ++__pyx_t_4;
      __pyx_8genexpr5__pyx_v_n = __pyx_t_6;
      __pyx_t_7 = PyFloat_FromDouble((__pyx_v_self->lexical[__pyx_8genexpr5__pyx_v_n]).prob); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 750, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_7))) __PYX_ERR(0, 750, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    }
  } /* exit inner scope */
  __pyx_r = __pyx_t_1;
  __pyx_t_1 = 0;
  goto __pyx_L0;
 751: 
+752: 	def __str__(self):
/* Python wrapper */
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_33__str__(PyObject *__pyx_v_self); /*proto*/
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_33__str__(PyObject *__pyx_v_self) {
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("__str__ (wrapper)", 0);
  __pyx_r = __pyx_pf_8discodop_10containers_7Grammar_32__str__(((struct __pyx_obj_8discodop_10containers_Grammar *)__pyx_v_self));

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
static PyObject *__pyx_pf_8discodop_10containers_7Grammar_32__str__(struct __pyx_obj_8discodop_10containers_Grammar *__pyx_v_self) {
  struct __pyx_obj_8discodop_10containers___pyx_scope_struct____str__ *__pyx_cur_scope;
  PyObject *__pyx_v_rules = NULL;
  PyObject *__pyx_v_lexical = NULL;
  PyObject *__pyx_v_labels = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("__str__", 0);
  __pyx_cur_scope = (struct __pyx_obj_8discodop_10containers___pyx_scope_struct____str__ *)__pyx_tp_new_8discodop_10containers___pyx_scope_struct____str__(__pyx_ptype_8discodop_10containers___pyx_scope_struct____str__, __pyx_empty_tuple, NULL);
  if (unlikely(!__pyx_cur_scope)) {
    __pyx_cur_scope = ((struct __pyx_obj_8discodop_10containers___pyx_scope_struct____str__ *)Py_None);
    __Pyx_INCREF(Py_None);
    __PYX_ERR(0, 752, __pyx_L1_error)
  } else {
    __Pyx_GOTREF(__pyx_cur_scope);
  }
  __pyx_cur_scope->__pyx_v_self = __pyx_v_self;
  __Pyx_INCREF((PyObject *)__pyx_cur_scope->__pyx_v_self);
  __Pyx_GIVEREF((PyObject *)__pyx_cur_scope->__pyx_v_self);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_9);
  __Pyx_XDECREF(__pyx_t_16);
  __Pyx_XDECREF(__pyx_t_21);
  __Pyx_XDECREF(__pyx_t_22);
  __Pyx_AddTraceback("discodop.containers.Grammar.__str__", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_rules);
  __Pyx_XDECREF(__pyx_v_lexical);
  __Pyx_XDECREF(__pyx_v_labels);
  __Pyx_DECREF(((PyObject *)__pyx_cur_scope));
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
struct __pyx_obj_8discodop_10containers___pyx_scope_struct____str__ {
  PyObject_HEAD
  struct __pyx_obj_8discodop_10containers_Grammar *__pyx_v_self;
};

+753: 		rules = '\n'.join(filter(None,
  { /* enter inner scope */
    size_t __pyx_8genexpr6__pyx_v_n;
/* … */
  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 753, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_INCREF(Py_None);
  __Pyx_GIVEREF(Py_None);
  PyTuple_SET_ITEM(__pyx_t_4, 0, Py_None);
  __Pyx_GIVEREF(__pyx_t_1);
  PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_1);
  __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_filter, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 753, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = PyUnicode_Join(__pyx_kp_u__24, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 753, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_rules = ((PyObject*)__pyx_t_4);
  __pyx_t_4 = 0;
+754: 			[self.rulestr(n) for n in range(self.numrules)]))
    __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 754, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_2 = __pyx_cur_scope->__pyx_v_self->numrules;
    for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
      __pyx_8genexpr6__pyx_v_n = __pyx_t_3;
      __pyx_t_4 = __pyx_f_8discodop_10containers_7Grammar_rulestr(__pyx_cur_scope->__pyx_v_self, __pyx_8genexpr6__pyx_v_n, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 754, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_4))) __PYX_ERR(0, 754, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    }
  } /* exit inner scope */
+755: 		lexical = '\n'.join(['%.2f %s => %s' % (
  { /* enter inner scope */
    PyObject *__pyx_8genexpr7__pyx_v_word = NULL;
    PyObject *__pyx_8genexpr7__pyx_v_n = NULL;
    __pyx_t_4 = PyList_New(0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 755, __pyx_L7_error)
    __Pyx_GOTREF(__pyx_t_4);
/* … */
        __pyx_t_22 = PyUnicode_Format(__pyx_kp_u_2f_s_s, __pyx_t_21); if (unlikely(!__pyx_t_22)) __PYX_ERR(0, 755, __pyx_L7_error)
        __Pyx_GOTREF(__pyx_t_22);
        __Pyx_DECREF(__pyx_t_21); __pyx_t_21 = 0;
        if (unlikely(__Pyx_ListComp_Append(__pyx_t_4, (PyObject*)__pyx_t_22))) __PYX_ERR(0, 755, __pyx_L7_error)
        __Pyx_DECREF(__pyx_t_22); __pyx_t_22 = 0;
/* … */
  __pyx_t_5 = PyUnicode_Join(__pyx_kp_u__24, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 755, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_v_lexical = ((PyObject*)__pyx_t_5);
  __pyx_t_5 = 0;
+756: 				exp(-self.lexical[n].prob) if self.logprob
        if ((__pyx_cur_scope->__pyx_v_self->logprob != 0)) {
          __pyx_t_19 = __Pyx_PyInt_As_size_t(__pyx_8genexpr7__pyx_v_n); if (unlikely((__pyx_t_19 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 756, __pyx_L7_error)
          __pyx_t_9 = PyFloat_FromDouble(exp((-(__pyx_cur_scope->__pyx_v_self->lexical[__pyx_t_19]).prob))); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 756, __pyx_L7_error)
          __Pyx_GOTREF(__pyx_t_9);
          __pyx_t_16 = __pyx_t_9;
          __pyx_t_9 = 0;
        } else {
/* … */
        __pyx_t_21 = PyTuple_New(3); if (unlikely(!__pyx_t_21)) __PYX_ERR(0, 756, __pyx_L7_error)
        __Pyx_GOTREF(__pyx_t_21);
        __Pyx_GIVEREF(__pyx_t_16);
        PyTuple_SET_ITEM(__pyx_t_21, 0, __pyx_t_16);
        __Pyx_GIVEREF(__pyx_t_9);
        PyTuple_SET_ITEM(__pyx_t_21, 1, __pyx_t_9);
        __Pyx_GIVEREF(__pyx_t_22);
        PyTuple_SET_ITEM(__pyx_t_21, 2, __pyx_t_22);
        __pyx_t_16 = 0;
        __pyx_t_9 = 0;
        __pyx_t_22 = 0;
+757: 				else self.lexical[n].prob,
          __pyx_t_19 = __Pyx_PyInt_As_size_t(__pyx_8genexpr7__pyx_v_n); if (unlikely((__pyx_t_19 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 757, __pyx_L7_error)
          __pyx_t_9 = PyFloat_FromDouble((__pyx_cur_scope->__pyx_v_self->lexical[__pyx_t_19]).prob); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 757, __pyx_L7_error)
          __Pyx_GOTREF(__pyx_t_9);
          __pyx_t_16 = __pyx_t_9;
          __pyx_t_9 = 0;
        }
+758: 				self.tolabel[self.lexical[n].lhs],
        __pyx_t_19 = __Pyx_PyInt_As_size_t(__pyx_8genexpr7__pyx_v_n); if (unlikely((__pyx_t_19 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 758, __pyx_L7_error)
        __pyx_t_20 = (__pyx_cur_scope->__pyx_v_self->lexical[__pyx_t_19]).lhs;
        __pyx_t_9 = __Pyx_GetItemInt(((PyObject *)__pyx_cur_scope->__pyx_v_self->tolabel), __pyx_t_20, Label, 0, __Pyx_PyInt_From_uint32_t, 0, 0, 0); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 758, __pyx_L7_error)
        __Pyx_GOTREF(__pyx_t_9);
+759: 				word.decode('utf8'))
        __pyx_t_21 = __Pyx_PyObject_GetAttrStr(__pyx_8genexpr7__pyx_v_word, __pyx_n_s_decode); if (unlikely(!__pyx_t_21)) __PYX_ERR(0, 759, __pyx_L7_error)
        __Pyx_GOTREF(__pyx_t_21);
        __pyx_t_22 = __Pyx_PyObject_Call(__pyx_t_21, __pyx_tuple__25, NULL); if (unlikely(!__pyx_t_22)) __PYX_ERR(0, 759, __pyx_L7_error)
        __Pyx_GOTREF(__pyx_t_22);
        __Pyx_DECREF(__pyx_t_21); __pyx_t_21 = 0;
/* … */
  __pyx_tuple__25 = PyTuple_Pack(1, __pyx_n_u_utf8); if (unlikely(!__pyx_tuple__25)) __PYX_ERR(0, 759, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__25);
  __Pyx_GIVEREF(__pyx_tuple__25);
+760: 			for word in sorted([x.first for x in self.lexicalbyword])
    { /* enter inner scope */
      std::pair<std::string,std::vector<uint32_t> >  __pyx_8genexpr8__pyx_8genexpr7__pyx_v_x;
      __pyx_t_5 = PyList_New(0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 760, __pyx_L7_error)
      __Pyx_GOTREF(__pyx_t_5);
      __pyx_t_7 = &__pyx_cur_scope->__pyx_v_self->lexicalbyword;
      __pyx_t_6 = __pyx_t_7->begin();
      for (;;) {
        if (!(__pyx_t_6 != __pyx_t_7->end())) break;
        __pyx_t_8 = *__pyx_t_6;
        ++__pyx_t_6;
        __pyx_8genexpr8__pyx_8genexpr7__pyx_v_x = __pyx_t_8;
        __pyx_t_9 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_8genexpr8__pyx_8genexpr7__pyx_v_x.first); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 760, __pyx_L7_error)
        __Pyx_GOTREF(__pyx_t_9);
        if (unlikely(__Pyx_ListComp_Append(__pyx_t_5, (PyObject*)__pyx_t_9))) __PYX_ERR(0, 760, __pyx_L7_error)
        __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
      }
    } /* exit inner scope */
    __pyx_t_1 = ((PyObject*)__pyx_t_5);
    __pyx_t_5 = 0;
    __pyx_t_10 = PyList_Sort(__pyx_t_1); if (unlikely(__pyx_t_10 == -1)) __PYX_ERR(0, 760, __pyx_L7_error)
    if (unlikely(__pyx_t_1 == Py_None)) {
      PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
      __PYX_ERR(0, 760, __pyx_L7_error)
    }
    __pyx_t_5 = __pyx_t_1; __Pyx_INCREF(__pyx_t_5); __pyx_t_11 = 0;
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    for (;;) {
      if (__pyx_t_11 >= PyList_GET_SIZE(__pyx_t_5)) break;
      #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
      __pyx_t_1 = PyList_GET_ITEM(__pyx_t_5, __pyx_t_11); __Pyx_INCREF(__pyx_t_1); __pyx_t_11++; if (unlikely(0 < 0)) __PYX_ERR(0, 760, __pyx_L7_error)
      #else
      __pyx_t_1 = PySequence_ITEM(__pyx_t_5, __pyx_t_11); __pyx_t_11++; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 760, __pyx_L7_error)
      __Pyx_GOTREF(__pyx_t_1);
      #endif
      __Pyx_XDECREF_SET(__pyx_8genexpr7__pyx_v_word, __pyx_t_1);
      __pyx_t_1 = 0;
/* … */
    }
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    __Pyx_XDECREF(__pyx_8genexpr7__pyx_v_word);
    __Pyx_XDECREF(__pyx_8genexpr7__pyx_v_n);
    goto __pyx_L16_exit_scope;
    __pyx_L7_error:;
    __Pyx_XDECREF(__pyx_8genexpr7__pyx_v_word);
    __Pyx_XDECREF(__pyx_8genexpr7__pyx_v_n);
    goto __pyx_L1_error;
    __pyx_L16_exit_scope:;
  } /* exit inner scope */
+761: 			for n in sorted([y for y in self.lexicalbyword[word]],
      { /* enter inner scope */
        uint32_t __pyx_8genexpr9__pyx_8genexpr7__pyx_v_y;
        __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 761, __pyx_L7_error)
        __Pyx_GOTREF(__pyx_t_1);
        __pyx_t_12 = __pyx_convert_string_from_py_std__in_string(__pyx_8genexpr7__pyx_v_word); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 761, __pyx_L7_error)
        __pyx_t_14 = &(__pyx_cur_scope->__pyx_v_self->lexicalbyword[__pyx_t_12]);
        __pyx_t_13 = __pyx_t_14->begin();
        for (;;) {
          if (!(__pyx_t_13 != __pyx_t_14->end())) break;
          __pyx_t_15 = *__pyx_t_13;
          ++__pyx_t_13;
          __pyx_8genexpr9__pyx_8genexpr7__pyx_v_y = __pyx_t_15;
          __pyx_t_9 = __Pyx_PyInt_From_uint32_t(__pyx_8genexpr9__pyx_8genexpr7__pyx_v_y); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 761, __pyx_L7_error)
          __Pyx_GOTREF(__pyx_t_9);
          if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_9))) __PYX_ERR(0, 761, __pyx_L7_error)
          __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
        }
      } /* exit inner scope */
      __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 761, __pyx_L7_error)
      __Pyx_GOTREF(__pyx_t_9);
      __Pyx_GIVEREF(__pyx_t_1);
      PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_1);
      __pyx_t_1 = 0;
/* … */
      __pyx_t_16 = __Pyx_PyObject_Call(__pyx_builtin_sorted, __pyx_t_9, __pyx_t_1); if (unlikely(!__pyx_t_16)) __PYX_ERR(0, 761, __pyx_L7_error)
      __Pyx_GOTREF(__pyx_t_16);
      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      if (likely(PyList_CheckExact(__pyx_t_16)) || PyTuple_CheckExact(__pyx_t_16)) {
        __pyx_t_1 = __pyx_t_16; __Pyx_INCREF(__pyx_t_1); __pyx_t_17 = 0;
        __pyx_t_18 = NULL;
      } else {
        __pyx_t_17 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_t_16); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 761, __pyx_L7_error)
        __Pyx_GOTREF(__pyx_t_1);
        __pyx_t_18 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_18)) __PYX_ERR(0, 761, __pyx_L7_error)
      }
      __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
      for (;;) {
        if (likely(!__pyx_t_18)) {
          if (likely(PyList_CheckExact(__pyx_t_1))) {
            if (__pyx_t_17 >= PyList_GET_SIZE(__pyx_t_1)) break;
            #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
            __pyx_t_16 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_17); __Pyx_INCREF(__pyx_t_16); __pyx_t_17++; if (unlikely(0 < 0)) __PYX_ERR(0, 761, __pyx_L7_error)
            #else
            __pyx_t_16 = PySequence_ITEM(__pyx_t_1, __pyx_t_17); __pyx_t_17++; if (unlikely(!__pyx_t_16)) __PYX_ERR(0, 761, __pyx_L7_error)
            __Pyx_GOTREF(__pyx_t_16);
            #endif
          } else {
            if (__pyx_t_17 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
            #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
            __pyx_t_16 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_17); __Pyx_INCREF(__pyx_t_16); __pyx_t_17++; if (unlikely(0 < 0)) __PYX_ERR(0, 761, __pyx_L7_error)
            #else
            __pyx_t_16 = PySequence_ITEM(__pyx_t_1, __pyx_t_17); __pyx_t_17++; if (unlikely(!__pyx_t_16)) __PYX_ERR(0, 761, __pyx_L7_error)
            __Pyx_GOTREF(__pyx_t_16);
            #endif
          }
        } else {
          __pyx_t_16 = __pyx_t_18(__pyx_t_1);
          if (unlikely(!__pyx_t_16)) {
            PyObject* exc_type = PyErr_Occurred();
            if (exc_type) {
              if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
              else __PYX_ERR(0, 761, __pyx_L7_error)
            }
            break;
          }
          __Pyx_GOTREF(__pyx_t_16);
        }
        __Pyx_XDECREF_SET(__pyx_8genexpr7__pyx_v_n, __pyx_t_16);
        __pyx_t_16 = 0;
/* … */
      }
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+762: 			key=lambda n: self.lexical[n].lhs)])
/* Python wrapper */
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_7__str___8genexpr7_lambda(PyObject *__pyx_self, PyObject *__pyx_v_n); /*proto*/
static PyMethodDef __pyx_mdef_8discodop_10containers_7Grammar_7__str___8genexpr7_lambda = {"lambda", (PyCFunction)__pyx_pw_8discodop_10containers_7Grammar_7__str___8genexpr7_lambda, METH_O, 0};
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_7__str___8genexpr7_lambda(PyObject *__pyx_self, PyObject *__pyx_v_n) {
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("lambda (wrapper)", 0);
  __pyx_r = __pyx_lambda_funcdef_lambda(__pyx_self, ((PyObject *)__pyx_v_n));

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_lambda_funcdef_lambda(PyObject *__pyx_self, PyObject *__pyx_v_n) {
  struct __pyx_obj_8discodop_10containers___pyx_scope_struct____str__ *__pyx_cur_scope;
  struct __pyx_obj_8discodop_10containers___pyx_scope_struct____str__ *__pyx_outer_scope;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("lambda", 0);
  __pyx_outer_scope = (struct __pyx_obj_8discodop_10containers___pyx_scope_struct____str__ *) __Pyx_CyFunction_GetClosure(__pyx_self);
  __pyx_cur_scope = __pyx_outer_scope;
  __Pyx_XDECREF(__pyx_r);
  if (unlikely(!__pyx_cur_scope->__pyx_v_self)) { __Pyx_RaiseClosureNameError("self"); __PYX_ERR(0, 762, __pyx_L1_error) }
  __pyx_t_1 = __Pyx_PyInt_As_size_t(__pyx_v_n); if (unlikely((__pyx_t_1 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 762, __pyx_L1_error)
  __pyx_t_2 = __Pyx_PyInt_From_uint32_t((__pyx_cur_scope->__pyx_v_self->lexical[__pyx_t_1]).lhs); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 762, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_r = __pyx_t_2;
  __pyx_t_2 = 0;
  goto __pyx_L0;

  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_AddTraceback("discodop.containers.Grammar.__str__.lambda", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
      __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 762, __pyx_L7_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_16 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8discodop_10containers_7Grammar_7__str___8genexpr7_lambda, 0, __pyx_n_s_str___locals_lambda, ((PyObject*)__pyx_cur_scope), __pyx_n_s_discodop_containers, __pyx_d, NULL); if (unlikely(!__pyx_t_16)) __PYX_ERR(0, 762, __pyx_L7_error)
      __Pyx_GOTREF(__pyx_t_16);
      if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_key, __pyx_t_16) < 0) __PYX_ERR(0, 762, __pyx_L7_error)
      __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+763: 		labels = ', '.join(['%s=%d' % (a, self.toid[a])
  { /* enter inner scope */
    PyObject *__pyx_9genexpr10__pyx_v_a = NULL;
    __pyx_t_5 = PyList_New(0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 763, __pyx_L19_error)
    __Pyx_GOTREF(__pyx_t_5);
/* … */
      __pyx_t_4 = PyObject_GetItem(((PyObject *)__pyx_cur_scope->__pyx_v_self->toid), __pyx_9genexpr10__pyx_v_a); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 763, __pyx_L19_error)
      __Pyx_GOTREF(__pyx_t_4);
      __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 763, __pyx_L19_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_INCREF(__pyx_9genexpr10__pyx_v_a);
      __Pyx_GIVEREF(__pyx_9genexpr10__pyx_v_a);
      PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_9genexpr10__pyx_v_a);
      __Pyx_GIVEREF(__pyx_t_4);
      PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_4);
      __pyx_t_4 = 0;
      __pyx_t_4 = PyUnicode_Format(__pyx_kp_u_s_d, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 763, __pyx_L19_error)
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      if (unlikely(__Pyx_ListComp_Append(__pyx_t_5, (PyObject*)__pyx_t_4))) __PYX_ERR(0, 763, __pyx_L19_error)
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
/* … */
  __pyx_t_22 = PyUnicode_Join(__pyx_kp_u__13, __pyx_t_5); if (unlikely(!__pyx_t_22)) __PYX_ERR(0, 763, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_22);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_v_labels = ((PyObject*)__pyx_t_22);
  __pyx_t_22 = 0;
+764: 				for a in sorted(self.toid)])
    __pyx_t_1 = ((PyObject *)__pyx_cur_scope->__pyx_v_self->toid);
    __Pyx_INCREF(__pyx_t_1);
    __pyx_t_22 = PySequence_List(__pyx_t_1); if (unlikely(!__pyx_t_22)) __PYX_ERR(0, 764, __pyx_L19_error)
    __Pyx_GOTREF(__pyx_t_22);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_t_4 = ((PyObject*)__pyx_t_22);
    __pyx_t_22 = 0;
    __pyx_t_10 = PyList_Sort(__pyx_t_4); if (unlikely(__pyx_t_10 == -1)) __PYX_ERR(0, 764, __pyx_L19_error)
    if (unlikely(__pyx_t_4 == Py_None)) {
      PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
      __PYX_ERR(0, 764, __pyx_L19_error)
    }
    __pyx_t_22 = __pyx_t_4; __Pyx_INCREF(__pyx_t_22); __pyx_t_11 = 0;
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    for (;;) {
      if (__pyx_t_11 >= PyList_GET_SIZE(__pyx_t_22)) break;
      #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
      __pyx_t_4 = PyList_GET_ITEM(__pyx_t_22, __pyx_t_11); __Pyx_INCREF(__pyx_t_4); __pyx_t_11++; if (unlikely(0 < 0)) __PYX_ERR(0, 764, __pyx_L19_error)
      #else
      __pyx_t_4 = PySequence_ITEM(__pyx_t_22, __pyx_t_11); __pyx_t_11++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 764, __pyx_L19_error)
      __Pyx_GOTREF(__pyx_t_4);
      #endif
      __Pyx_XDECREF_SET(__pyx_9genexpr10__pyx_v_a, __pyx_t_4);
      __pyx_t_4 = 0;
/* … */
    }
    __Pyx_DECREF(__pyx_t_22); __pyx_t_22 = 0;
    __Pyx_XDECREF(__pyx_9genexpr10__pyx_v_a);
    goto __pyx_L22_exit_scope;
    __pyx_L19_error:;
    __Pyx_XDECREF(__pyx_9genexpr10__pyx_v_a);
    goto __pyx_L1_error;
    __pyx_L22_exit_scope:;
  } /* exit inner scope */
+765: 		return 'rules:\n%s\nlexicon:\n%s\nlabels:\n%s' % (
  __Pyx_XDECREF(__pyx_r);
/* … */
  __pyx_t_5 = PyUnicode_Format(__pyx_kp_u_rules_s_lexicon_s_labels_s, __pyx_t_22); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 765, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_22); __pyx_t_22 = 0;
  __pyx_r = __pyx_t_5;
  __pyx_t_5 = 0;
  goto __pyx_L0;
+766: 				rules, lexical, labels)
  __pyx_t_22 = PyTuple_New(3); if (unlikely(!__pyx_t_22)) __PYX_ERR(0, 766, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_22);
  __Pyx_INCREF(__pyx_v_rules);
  __Pyx_GIVEREF(__pyx_v_rules);
  PyTuple_SET_ITEM(__pyx_t_22, 0, __pyx_v_rules);
  __Pyx_INCREF(__pyx_v_lexical);
  __Pyx_GIVEREF(__pyx_v_lexical);
  PyTuple_SET_ITEM(__pyx_t_22, 1, __pyx_v_lexical);
  __Pyx_INCREF(__pyx_v_labels);
  __Pyx_GIVEREF(__pyx_v_labels);
  PyTuple_SET_ITEM(__pyx_t_22, 2, __pyx_v_labels);
 767: 
+768: 	def __repr__(self):
/* Python wrapper */
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_35__repr__(PyObject *__pyx_v_self); /*proto*/
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_35__repr__(PyObject *__pyx_v_self) {
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
  __pyx_r = __pyx_pf_8discodop_10containers_7Grammar_34__repr__(((struct __pyx_obj_8discodop_10containers_Grammar *)__pyx_v_self));

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_8discodop_10containers_7Grammar_34__repr__(struct __pyx_obj_8discodop_10containers_Grammar *__pyx_v_self) {
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("__repr__", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_AddTraceback("discodop.containers.Grammar.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
+769: 		return '%s(\n%r,\n%r\n)' % (self.__class__.__name__,
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 769, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_name_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 769, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
/* … */
  __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 769, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GIVEREF(__pyx_t_2);
  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
  __Pyx_GIVEREF(__pyx_t_1);
  PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_1);
  __Pyx_INCREF(__pyx_v_self->lexiconfile);
  __Pyx_GIVEREF(__pyx_v_self->lexiconfile);
  PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_v_self->lexiconfile);
  __pyx_t_2 = 0;
  __pyx_t_1 = 0;
  __pyx_t_1 = PyUnicode_Format(__pyx_kp_u_s_r_r, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 769, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_r = __pyx_t_1;
  __pyx_t_1 = 0;
  goto __pyx_L0;
+770: 				self.rulesfile or self.ruletuples, self.lexiconfile)
  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_self->rulesfile); if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 770, __pyx_L1_error)
  if (!__pyx_t_3) {
  } else {
    __Pyx_INCREF(__pyx_v_self->rulesfile);
    __pyx_t_1 = __pyx_v_self->rulesfile;
    goto __pyx_L3_bool_binop_done;
  }
  __Pyx_INCREF(__pyx_v_self->ruletuples);
  __pyx_t_1 = __pyx_v_self->ruletuples;
  __pyx_L3_bool_binop_done:;
 771: 
+772: 	def __reduce__(self):
/* Python wrapper */
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_37__reduce__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
static char __pyx_doc_8discodop_10containers_7Grammar_36__reduce__[] = "Grammar.__reduce__(self)\nHelper function for pickling.";
static PyObject *__pyx_pw_8discodop_10containers_7Grammar_37__reduce__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("__reduce__ (wrapper)", 0);
  __pyx_r = __pyx_pf_8discodop_10containers_7Grammar_36__reduce__(((struct __pyx_obj_8discodop_10containers_Grammar *)__pyx_v_self));

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_8discodop_10containers_7Grammar_36__reduce__(struct __pyx_obj_8discodop_10containers_Grammar *__pyx_v_self) {
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("__reduce__", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_AddTraceback("discodop.containers.Grammar.__reduce__", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 773: 		"""Helper function for pickling."""
+774: 		return (Grammar, (self.rulesfile or self.ruletuples, self.lexiconfile,
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_self->rulesfile); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 774, __pyx_L1_error)
  if (!__pyx_t_2) {
  } else {
    __Pyx_INCREF(__pyx_v_self->rulesfile);
    __pyx_t_1 = __pyx_v_self->rulesfile;
    goto __pyx_L3_bool_binop_done;
  }
  __Pyx_INCREF(__pyx_v_self->ruletuples);
  __pyx_t_1 = __pyx_v_self->ruletuples;
  __pyx_L3_bool_binop_done:;
/* … */
  __pyx_t_4 = PyTuple_New(4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 774, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GIVEREF(__pyx_t_1);
  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
  __Pyx_INCREF(__pyx_v_self->lexiconfile);
  __Pyx_GIVEREF(__pyx_v_self->lexiconfile);
  PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_v_self->lexiconfile);
  __Pyx_INCREF(__pyx_v_self->start);
  __Pyx_GIVEREF(__pyx_v_self->start);
  PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_v_self->start);
  __Pyx_GIVEREF(__pyx_t_3);
  PyTuple_SET_ITEM(__pyx_t_4, 3, __pyx_t_3);
  __pyx_t_1 = 0;
  __pyx_t_3 = 0;
  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 774, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_INCREF(((PyObject *)__pyx_ptype_8discodop_10containers_Grammar));
  __Pyx_GIVEREF(((PyObject *)__pyx_ptype_8discodop_10containers_Grammar));
  PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_ptype_8discodop_10containers_Grammar));
  __Pyx_GIVEREF(__pyx_t_4);
  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_4);
  __pyx_t_4 = 0;
  __pyx_r = __pyx_t_3;
  __pyx_t_3 = 0;
  goto __pyx_L0;
+775: 				self.start, self.altweightsfile or self.models))
  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_self->altweightsfile); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 775, __pyx_L1_error)
  if (!__pyx_t_2) {
  } else {
    __Pyx_INCREF(__pyx_v_self->altweightsfile);
    __pyx_t_3 = __pyx_v_self->altweightsfile;
    goto __pyx_L5_bool_binop_done;
  }
  __Pyx_INCREF(__pyx_v_self->models);
  __pyx_t_3 = __pyx_v_self->models;
  __pyx_L5_bool_binop_done:;
 776: 
+777: 	def __dealloc__(self):
/* Python wrapper */
static void __pyx_pw_8discodop_10containers_7Grammar_39__dealloc__(PyObject *__pyx_v_self); /*proto*/
static void __pyx_pw_8discodop_10containers_7Grammar_39__dealloc__(PyObject *__pyx_v_self) {
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
  __pyx_pf_8discodop_10containers_7Grammar_38__dealloc__(((struct __pyx_obj_8discodop_10containers_Grammar *)__pyx_v_self));

  /* function exit code */
  __Pyx_RefNannyFinishContext();
}

static void __pyx_pf_8discodop_10containers_7Grammar_38__dealloc__(struct __pyx_obj_8discodop_10containers_Grammar *__pyx_v_self) {
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("__dealloc__", 0);
/* … */
  /* function exit code */
  __pyx_L0:;
  __Pyx_RefNannyFinishContext();
}
+778: 		if self.bylhs is NULL:
  __pyx_t_1 = ((__pyx_v_self->bylhs == NULL) != 0);
  if (__pyx_t_1) {
/* … */
  }
+779: 			return
    goto __pyx_L0;
+780: 		free(self.bylhs)
  free(__pyx_v_self->bylhs);
+781: 		free(self.mask)
  free(__pyx_v_self->mask);
+782: 		free(self.revrulemap)
  free(__pyx_v_self->revrulemap);
+783: 		if self.mapping is not NULL:
  __pyx_t_1 = ((__pyx_v_self->mapping != NULL) != 0);
  if (__pyx_t_1) {
/* … */
  }
+784: 			free(self.mapping)
    free(__pyx_v_self->mapping);
+785: 		if self.splitmapping is not NULL:
  __pyx_t_1 = ((__pyx_v_self->splitmapping != NULL) != 0);
  if (__pyx_t_1) {
/* … */
  }
+786: 			free(self.splitmapping[0])
    free((__pyx_v_self->splitmapping[0]));
+787: 			free(self.splitmapping)
    free(__pyx_v_self->splitmapping);
+788: 		if self.selfmapping is not NULL:
  __pyx_t_1 = ((__pyx_v_self->selfmapping != NULL) != 0);
  if (__pyx_t_1) {
/* … */
  }
+789: 			free(self.selfmapping)
    free(__pyx_v_self->selfmapping);
+790: 		self.bylhs = self.mask = self.revrulemap = NULL
  __pyx_v_self->bylhs = NULL;
  __pyx_v_self->mask = NULL;
  __pyx_v_self->revrulemap = NULL;
+791: 		self.mapping = self.splitmapping = NULL
  __pyx_v_self->mapping = NULL;
  __pyx_v_self->splitmapping = NULL;
 792: 
 793: 
+794: cdef inline Prob convertweight(const char *weight):
static CYTHON_INLINE Prob __pyx_f_8discodop_10containers_convertweight(char const *__pyx_v_weight) {
  char *__pyx_v_endptr;
  Prob __pyx_v_w;
  Prob __pyx_r;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("convertweight", 0);
/* … */
  /* function exit code */
  __pyx_L0:;
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 795: 	"""Convert weight to float/double; weight may be a fraction '1/2',
 796: 	decimal float '0.5' or hex float '0x1.0p-1'. Returns 0 on error."""
+797: 	cdef char *endptr = NULL
  __pyx_v_endptr = NULL;
+798: 	cdef Prob w = strtod(weight, &endptr)
  __pyx_v_w = strtod(__pyx_v_weight, (&__pyx_v_endptr));
+799: 	if endptr[0] == b'/':
  __pyx_t_1 = (((__pyx_v_endptr[0]) == '/') != 0);
  if (__pyx_t_1) {
/* … */
    goto __pyx_L3;
  }
+800: 		w /= strtod(&endptr[1], NULL)
    __pyx_v_w = (__pyx_v_w / strtod((&(__pyx_v_endptr[1])), NULL));
+801: 	elif endptr[0]:
  __pyx_t_1 = ((__pyx_v_endptr[0]) != 0);
  if (__pyx_t_1) {
/* … */
  }
  __pyx_L3:;
+802: 		return 0
    __pyx_r = 0.0;
    goto __pyx_L0;
+803: 	return w
  __pyx_r = __pyx_v_w;
  goto __pyx_L0;
 804: 
 805: 
+806: cdef inline const char *readfields(const char *buf, vector[string] &result):
static CYTHON_INLINE char const *__pyx_f_8discodop_10containers_readfields(char const *__pyx_v_buf, std::vector<std::string>  &__pyx_v_result) {
  char const *__pyx_v_endofline;
  char const *__pyx_v_tmp;
  char const *__pyx_r;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("readfields", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_WriteUnraisable("discodop.containers.readfields", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
  __pyx_r = 0;
  __pyx_L0:;
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 807: 	"""Tokenize a tab-separated line in a string.
 808: 
 809: 	:returns: a pointer of the new position in buf,
 810: 		or NULL if end of string was reached.
 811: 		result is extended with the tokens encountered."""
+812: 	cdef const char *endofline = strchr(buf, b'\n')
  __pyx_v_endofline = strchr(__pyx_v_buf, '\n');
 813: 	cdef const char *tmp
+814: 	if endofline is NULL:
  __pyx_t_1 = ((__pyx_v_endofline == NULL) != 0);
  if (__pyx_t_1) {
/* … */
  }
 815: 		# NB: if last last line has no end of line, its tokens will be ignored.
+816: 		return NULL
    __pyx_r = NULL;
    goto __pyx_L0;
+817: 	tmp = strchr(buf, b'\t')
  __pyx_v_tmp = strchr(__pyx_v_buf, '\t');
+818: 	while tmp is not NULL and tmp < endofline:
  while (1) {
    __pyx_t_2 = ((__pyx_v_tmp != NULL) != 0);
    if (__pyx_t_2) {
    } else {
      __pyx_t_1 = __pyx_t_2;
      goto __pyx_L6_bool_binop_done;
    }
    __pyx_t_2 = ((__pyx_v_tmp < __pyx_v_endofline) != 0);
    __pyx_t_1 = __pyx_t_2;
    __pyx_L6_bool_binop_done:;
    if (!__pyx_t_1) break;
+819: 		result.push_back(string(buf, tmp - buf))
    try {
      __pyx_t_3 = std::string(__pyx_v_buf, (__pyx_v_tmp - __pyx_v_buf));
    } catch(...) {
      __Pyx_CppExn2PyErr();
      __PYX_ERR(0, 819, __pyx_L1_error)
    }
    try {
      __pyx_v_result.push_back(__pyx_t_3);
    } catch(...) {
      __Pyx_CppExn2PyErr();
      __PYX_ERR(0, 819, __pyx_L1_error)
    }
+820: 		buf = tmp + 1
    __pyx_v_buf = (__pyx_v_tmp + 1);
+821: 		tmp = strchr(buf, b'\t')
    __pyx_v_tmp = strchr(__pyx_v_buf, '\t');
  }
+822: 	result.push_back(string(buf, endofline - buf))
  try {
    __pyx_t_3 = std::string(__pyx_v_buf, (__pyx_v_endofline - __pyx_v_buf));
  } catch(...) {
    __Pyx_CppExn2PyErr();
    __PYX_ERR(0, 822, __pyx_L1_error)
  }
  try {
    __pyx_v_result.push_back(__pyx_t_3);
  } catch(...) {
    __Pyx_CppExn2PyErr();
    __PYX_ERR(0, 822, __pyx_L1_error)
  }
+823: 	return endofline + 1
  __pyx_r = (__pyx_v_endofline + 1);
  goto __pyx_L0;