/*************************************************************************/ /* Copyright (c) 2012 */ /* Linas Vepstas <linasvepstas@gmail.com> */ /* All rights reserved */ /* */ /*************************************************************************/ #ifndef _LG_VITERBI_COMPILE_H #define _LG_VITERBI_COMPILE_H #include "utilities.h" // needed for assert #include "atom.h" namespace link_grammar { namespace viterbi { // Classes that convert run-time atom types into compile-time static // types, so that the compiler can check these for correctness. // These are here purely for C++ programming convenience; the true // structure that matters is the dynamic run-time (hyper-)graphs. class Connector : public Node { public: // Last letter of the connector must be + or - // indicating the direction of the connector. Connector(const std::string& name) : Node(CONNECTOR, name) { if (name == OPTIONAL_CLAUSE) return; char dir = *name.rbegin(); assert (('+' == dir) or ('-' == dir), "Bad direction"); } bool is_optional() const { return _name == OPTIONAL_CLAUSE; } char get_direction() const { return *_name.rbegin(); } }; class LingType : public Node { public: LingType(const std::string& name) : Node(LING_TYPE, name) {} }; class Word : public Node { public: Word(const std::string& name) : Node(WORD, name) {} }; #if 0 // Atom types. Right now an enum, but maybe should be dynamic!? enum AtomType { // Link types OR, // unordered OR of all children WORD_DISJ, // word, followed by a single disjunct for that word. }; #endif /// Ordered sequence /// And could/should inherit fom Seq, since the order of the atoms in /// its outgoing set is important. class And : public Link { public: And() : Link(AND) {} And(const OutList& ol) : Link(AND, ol) {} }; /// Create a ling-grammar link. This will be of the form: /// LING: /// Ling_TYPE "MVa" /// Atom ... /// Atom ... /// where the Atoms are typically either connectors, or WORD_DISJ /// class Ling : public Link { public: Ling(const OutList& ol) : Link(LING, ol) { assert(3 == ol.size(), "LG link wrong size"); assert(ol[0]->get_type() == LING_TYPE, "LG link has bad first node"); } Ling(const std::string& str, Atom* a, Atom *b) : Link(LING) { _oset.push_back(new LingType(str)); _oset.push_back(a); _oset.push_back(b); } Ling(LingType* t, Atom* a, Atom *b) : Link(LING) { _oset.push_back(t); _oset.push_back(a); _oset.push_back(b); } LingType* get_ling_type() { return dynamic_cast<LingType*>(get_outgoing_atom(0)); } Atom* get_left() { return get_outgoing_atom(1); } Atom* get_right() { return get_outgoing_atom(2); } }; class WordCset : public Link { public: WordCset(Word* a, Atom* b) : Link(WORD_CSET, a, b) { // this should be pointing at: // WORD_CSET : // WORD : blah.v // AND : // CONNECTOR : Wd- etc... assert(a->get_type() == WORD, "CSET is expecting WORD as first arg"); bool ok = false; ok = ok or b->get_type() == CONNECTOR; ok = ok or b->get_type() == AND; ok = ok or b->get_type() == OR; assert(ok, "CSET is expecting connector set as second arg"); } Word* get_word() const { return dynamic_cast<Word*>(_oset[0]); } Atom* get_cset() const { return _oset[1]; } }; /// Ordered sequence /// Seq inherits fom Link, and is an ordered sequence of zero or more /// atoms. class Seq : public Link { public: Seq() : Link(SEQ) {} Seq(const OutList& ol) : Link(SEQ, ol) {} Seq(Atom* singleton) : Link(SEQ, OutList(1, singleton)) {} }; /// Unordered sequence /// A Set inherits fom Link, and is an unordered set of zero or more /// atoms. class Set : public Link { public: Set(const OutList& ol) : Link(SET, ol) {} Set(Atom* singleton) : Link(SET, OutList(1, singleton)) {} }; /// A pair of two sequences. The first sequence is the state, the /// second sequence is the output. That is, the link created is of the /// form /// /// STATE_PAIR : /// SEQ /// ... /// SEQ /// ... /// class StatePair : public Link { public: StatePair(Seq* stat, Seq* outp) : Link(STATE_PAIR) { _oset.push_back(stat); _oset.push_back(outp); } Seq* get_state() { return dynamic_cast<Seq*>(_oset.at(0)); } Seq* get_output() { return dynamic_cast<Seq*>(_oset.at(1)); } }; } // namespace viterbi } // namespace link-grammar #endif // _LG_VITERBI_COMPILE_H