#ifndef __PLCFRS_HPP
#define __PLCFRS_HPP

using namespace __shedskin__;
namespace __plcfrs__ {

extern str *const_0, *const_1, *const_10, *const_11, *const_12, *const_13, *const_14, *const_15, *const_16, *const_17, *const_18, *const_19, *const_2, *const_20, *const_21, *const_22, *const_23, *const_24, *const_25, *const_26, *const_27, *const_28, *const_29, *const_3, *const_30, *const_31, *const_32, *const_33, *const_34, *const_35, *const_36, *const_37, *const_38, *const_39, *const_4, *const_40, *const_41, *const_42, *const_43, *const_44, *const_45, *const_46, *const_47, *const_48, *const_49, *const_5, *const_50, *const_51, *const_52, *const_53, *const_54, *const_55, *const_56, *const_57, *const_58, *const_59, *const_6, *const_60, *const_61, *const_62, *const_63, *const_64, *const_65, *const_66, *const_67, *const_68, *const_69, *const_7, *const_70, *const_71, *const_8, *const_9;

class Grammar;
class ChartItem;
class Edge;
class Terminal;
class Rule;
class Entry;
class agenda;

typedef __ss_int (*lambda2)(tuple2<__ss_int, __ss_int> *);
typedef __ss_int (*lambda0)(list<Edge *> *);
typedef __ss_int (*lambda1)(str *);

extern __ss_int INVALID;
extern file *__ss_stderr;
extern str *__name__;
extern list<str *> *argv;


extern class_ *cl_Grammar;
class Grammar : public pyobj {
public:
    static tuple2<str *, str *> *__slots__;

    list<list<Rule *> *> *unary;
    list<list<Rule *> *> *bylhs;
    list<list<Rule *> *> *lbinary;
    dict<str *, list<Terminal *> *> *lexical;
    dict<__ss_int, str *> *tolabel;
    dict<str *, __ss_int> *toid;
    list<list<Rule *> *> *rbinary;

    Grammar() {}
    Grammar(list<list<Rule *> *> *unary, list<list<Rule *> *> *lbinary, list<list<Rule *> *> *rbinary, dict<str *, list<Terminal *> *> *lexical, list<list<Rule *> *> *bylhs, dict<str *, __ss_int> *toid, dict<__ss_int, str *> *tolabel) {
        this->__class__ = cl_Grammar;
        __init__(unary, lbinary, rbinary, lexical, bylhs, toid, tolabel);
    }
    void *__init__(list<list<Rule *> *> *unary, list<list<Rule *> *> *lbinary, list<list<Rule *> *> *rbinary, dict<str *, list<Terminal *> *> *lexical, list<list<Rule *> *> *bylhs, dict<str *, __ss_int> *toid, dict<__ss_int, str *> *tolabel);
};

extern class_ *cl_ChartItem;
class ChartItem : public pyobj {
public:
    static tuple2<str *, str *> *__slots__;

    __ss_int label;
    __ss_int vec;

    ChartItem() {}
    ChartItem(__ss_int label, __ss_int vec) {
        this->__class__ = cl_ChartItem;
        __init__(label, vec);
    }
    long __hash__();
    __ss_bool __eq__(ChartItem *other);
    void *__init__(__ss_int label, __ss_int vec);
};

extern class_ *cl_Edge;
class Edge : public pyobj {
public:
    static tuple2<str *, str *> *__slots__;

    ChartItem *right;
    double score;
    double prob;
    double inside;
    ChartItem *left;

    Edge() {}
    Edge(double score, double inside, double prob, ChartItem *left, ChartItem *right) {
        this->__class__ = cl_Edge;
        __init__(score, inside, prob, left, right);
    }
    __ss_bool __gt__(Edge *other);
    __ss_bool __lt__(Edge *other);
    __ss_bool __eq__(Edge *other);
    void *__init__(double score, double inside, double prob, ChartItem *left, ChartItem *right);
};

extern class_ *cl_Terminal;
class Terminal : public pyobj {
public:
    static tuple2<str *, str *> *__slots__;

    str *word;
    __ss_int rhs2;
    __ss_int rhs1;
    __ss_int lhs;
    double prob;

    Terminal() {}
    Terminal(__ss_int lhs, __ss_int rhs1, __ss_int rhs2, str *word, double prob) {
        this->__class__ = cl_Terminal;
        __init__(lhs, rhs1, rhs2, word, prob);
    }
    void *__init__(__ss_int lhs, __ss_int rhs1, __ss_int rhs2, str *word, double prob);
};

extern class_ *cl_Rule;
class Rule : public pyobj {
public:
    static tuple2<str *, str *> *__slots__;

    __ss_int rhs2;
    __array__::array<__ss_int> *lengths;
    __array__::array<__ss_int> *_args;
    __ss_int rhs1;
    double prob;
    __array__::array<__ss_int> *args;
    __array__::array<__ss_int> *_lengths;
    __ss_int lhs;

    Rule() {}
    Rule(__ss_int lhs, __ss_int rhs1, __ss_int rhs2, __array__::array<__ss_int> *args, __array__::array<__ss_int> *lengths, double prob) {
        this->__class__ = cl_Rule;
        __init__(lhs, rhs1, rhs2, args, lengths, prob);
    }
    void *__init__(__ss_int lhs, __ss_int rhs1, __ss_int rhs2, __array__::array<__ss_int> *args, __array__::array<__ss_int> *lengths, double prob);
};

extern class_ *cl_Entry;
class Entry : public pyobj {
public:
    static tuple2<str *, str *> *__slots__;

    __ss_int count;
    Edge *value;
    ChartItem *key;

    Entry() {}
    Entry(ChartItem *key, Edge *value, __ss_int count) {
        this->__class__ = cl_Entry;
        __init__(key, value, count);
    }
    __ss_bool __lt__(Entry *other);
    __ss_bool __eq__(Entry *other);
    void *__init__(ChartItem *key, Edge *value, __ss_int count);
};

extern class_ *cl_agenda;
class agenda : public pyobj {
public:
    __ss_int counter;
    dict<ChartItem *, Entry *> *mapping;
    list<Entry *> *heap;

    agenda() {}
    agenda(int __ss_init) {
        this->__class__ = cl_agenda;
        __init__();
    }
    Edge *__getitem__(ChartItem *key);
    __ss_bool __contains__(ChartItem *key);
    void *__setitem__(ChartItem *key, Edge *value);
    void *__init__();
    tuple2<ChartItem *, Edge *> *popitem();
    __ss_int __len__();
};

tuple2<dict<ChartItem *, list<Edge *> *> *, ChartItem *> *parse(list<str *> *sent, Grammar *grammar, list<str *> *tags, __ss_int start, __ss_bool exhaustive);
__ss_int process_edge(ChartItem *newitem, Edge *newedge, agenda *A, dict<ChartItem *, list<Edge *> *> *C, __ss_bool exhaustive);
__ss_bool concat(Rule *rule, __ss_int lvec, __ss_int rvec);
tuple2<str *, double> *mostprobablederivation(dict<ChartItem *, list<Edge *> *> *chart, ChartItem *start, dict<__ss_int, str *> *tolabel);
str *getmpd(dict<ChartItem *, list<Edge *> *> *chart, ChartItem *start, dict<__ss_int, str *> *tolabel);
str *binrepr(ChartItem *a, list<str *> *sent);
void *pprint_chart(dict<ChartItem *, list<Edge *> *> *chart, list<str *> *sent, dict<__ss_int, str *> *tolabel);
__ss_bool __ss_do(str *sent, Grammar *grammar);
tuple2<list<tuple2<tuple2<tuple2<str *, str *> *, tuple2<tuple2<__ss_int, __ss_int> *, tuple2<__ss_int, __ss_int> *> *> *, double> *> *, list<tuple2<tuple2<tuple2<str *, str *> *, str *> *, double> *> *> *read_srcg_grammar(str *rulefile, str *lexiconfile);
Grammar *splitgrammar(list<tuple2<tuple2<tuple2<str *, str *> *, tuple2<tuple2<__ss_int, __ss_int> *, tuple2<__ss_int, __ss_int> *> *> *, double> *> *grammar, list<tuple2<tuple2<tuple2<str *, str *> *, str *> *, double> *> *lexicon);
tuple2<__array__::array<__ss_int> *, __array__::array<__ss_int> *> *yfarray(tuple2<tuple2<__ss_int, __ss_int> *, tuple2<__ss_int, __ss_int> *> *yf);
tuple2<tuple2<__ss_int, __ss_int> *, tuple2<__ss_int, __ss_int> *> *arraytoyf(__array__::array<__ss_int> *args, __array__::array<__ss_int> *lengths);
__ss_int nextset(__ss_int a, __ss_int pos);
__ss_int nextunset(__ss_int a, __ss_int pos);
__ss_int bitcount(__ss_int a);
__ss_int testbit(__ss_int a, __ss_int offset);
void *batch(str *rulefile, str *lexiconfile, str *sentfile);
void *demo();

} // module namespace
namespace __shedskin__ { /* XXX */
template<> __ss_int __cmp(__plcfrs__::Edge *a, __plcfrs__::Edge *b) {
    if (!a) return -1;
    if(a->__eq__(b)) return 0;
    return (a->__lt__(b))?-1:1;
}
template<> __ss_int __cmp(__plcfrs__::ChartItem *a, __plcfrs__::ChartItem *b) {
    if (!a) return -1;
    if(a->__eq__(b)) return 0;
    return __cmp<void *>(a, b);
}
template<> __ss_int __cmp(__plcfrs__::Entry *a, __plcfrs__::Entry *b) {
    if (!a) return -1;
    if(a->__eq__(b)) return 0;
    return (a->__lt__(b))?-1:1;
}
template<> __ss_bool __gt(__plcfrs__::Entry *a, __plcfrs__::Entry *b) {
    return b->__lt__(a);
}
}
#endif
