00001 #ifndef SEARCH_VERTEX_GENERATOR__ 00002 #define SEARCH_VERTEX_GENERATOR__ 00003 00004 #include "search/edge.hh" 00005 #include "search/types.hh" 00006 #include "search/vertex.hh" 00007 00008 namespace lm { 00009 namespace ngram { 00010 struct ChartState; 00011 } // namespace ngram 00012 } // namespace lm 00013 00014 namespace search { 00015 00016 class ContextBase; 00017 00018 // Output makes the single-best or n-best list. 00019 template <class Output> class VertexGenerator { 00020 public: 00021 VertexGenerator(ContextBase &context, Vertex &gen, Output &nbest) : context_(context), gen_(gen), nbest_(nbest) {} 00022 00023 void NewHypothesis(PartialEdge partial) { 00024 nbest_.Add(existing_[hash_value(partial.CompletedState())], partial); 00025 } 00026 00027 void FinishedSearch() { 00028 gen_.root_.InitRoot(); 00029 for (typename Existing::iterator i(existing_.begin()); i != existing_.end(); ++i) { 00030 gen_.root_.AppendHypothesis(nbest_.Complete(i->second)); 00031 } 00032 existing_.clear(); 00033 gen_.root_.FinishRoot(); 00034 } 00035 00036 Vertex &Generating() { return gen_; } 00037 00038 private: 00039 ContextBase &context_; 00040 00041 Vertex &gen_; 00042 00043 typedef boost::unordered_map<uint64_t, typename Output::Combine> Existing; 00044 Existing existing_; 00045 00046 Output &nbest_; 00047 }; 00048 00049 // Special case for root vertex: everything should come together into the root 00050 // node. In theory, this should happen naturally due to state collapsing with 00051 // <s> and </s>. If that's the case, VertexGenerator is fine, though it will 00052 // make one connection. 00053 template <class Output> class RootVertexGenerator { 00054 public: 00055 RootVertexGenerator(Vertex &gen, Output &out) : gen_(gen), out_(out) {} 00056 00057 void NewHypothesis(PartialEdge partial) { 00058 out_.Add(combine_, partial); 00059 } 00060 00061 void FinishedSearch() { 00062 gen_.root_.InitRoot(); 00063 gen_.root_.AppendHypothesis(out_.Complete(combine_)); 00064 gen_.root_.FinishRoot(); 00065 } 00066 00067 private: 00068 Vertex &gen_; 00069 00070 typename Output::Combine combine_; 00071 Output &out_; 00072 }; 00073 00074 } // namespace search 00075 #endif // SEARCH_VERTEX_GENERATOR__