2012-10-15 16:58:33 +04:00
|
|
|
#ifndef SEARCH_VERTEX__
|
|
|
|
#define SEARCH_VERTEX__
|
|
|
|
|
|
|
|
#include "lm/left.hh"
|
|
|
|
#include "search/types.hh"
|
|
|
|
|
|
|
|
#include <boost/unordered_set.hpp>
|
|
|
|
|
|
|
|
#include <queue>
|
|
|
|
#include <vector>
|
|
|
|
|
2012-11-15 22:04:07 +04:00
|
|
|
#include <math.h>
|
2012-10-15 16:58:33 +04:00
|
|
|
#include <stdint.h>
|
|
|
|
|
|
|
|
namespace search {
|
|
|
|
|
|
|
|
class ContextBase;
|
|
|
|
|
|
|
|
class VertexNode {
|
|
|
|
public:
|
2012-11-15 22:04:07 +04:00
|
|
|
VertexNode() : end_() {}
|
2012-10-15 16:58:33 +04:00
|
|
|
|
|
|
|
void InitRoot() {
|
|
|
|
extend_.clear();
|
|
|
|
state_.left.full = false;
|
|
|
|
state_.left.length = 0;
|
|
|
|
state_.right.length = 0;
|
|
|
|
right_full_ = false;
|
2012-11-15 22:04:07 +04:00
|
|
|
end_ = History();
|
2012-10-15 16:58:33 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
lm::ngram::ChartState &MutableState() { return state_; }
|
|
|
|
bool &MutableRightFull() { return right_full_; }
|
|
|
|
|
|
|
|
void AddExtend(VertexNode *next) {
|
|
|
|
extend_.push_back(next);
|
|
|
|
}
|
|
|
|
|
2012-11-15 22:04:07 +04:00
|
|
|
void SetEnd(History end, Score score) {
|
|
|
|
assert(!end_);
|
2012-10-18 21:54:38 +04:00
|
|
|
end_ = end;
|
2012-11-15 22:04:07 +04:00
|
|
|
bound_ = score;
|
2012-10-18 21:54:38 +04:00
|
|
|
}
|
2012-10-15 16:58:33 +04:00
|
|
|
|
2012-11-15 22:04:07 +04:00
|
|
|
void SortAndSet(ContextBase &context);
|
2012-10-15 16:58:33 +04:00
|
|
|
|
|
|
|
// Should only happen to a root node when the entire vertex is empty.
|
|
|
|
bool Empty() const {
|
2012-11-15 22:04:07 +04:00
|
|
|
return !end_ && extend_.empty();
|
2012-10-15 16:58:33 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Complete() const {
|
2012-11-15 22:04:07 +04:00
|
|
|
return end_;
|
2012-10-15 16:58:33 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
const lm::ngram::ChartState &State() const { return state_; }
|
|
|
|
bool RightFull() const { return right_full_; }
|
|
|
|
|
|
|
|
Score Bound() const {
|
|
|
|
return bound_;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned char Length() const {
|
|
|
|
return state_.left.length + state_.right.length;
|
|
|
|
}
|
|
|
|
|
2012-10-18 21:54:38 +04:00
|
|
|
// Will be invalid unless this is a leaf.
|
2012-11-15 22:04:07 +04:00
|
|
|
const History End() const { return end_; }
|
2012-10-15 16:58:33 +04:00
|
|
|
|
|
|
|
const VertexNode &operator[](size_t index) const {
|
|
|
|
return *extend_[index];
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t Size() const {
|
|
|
|
return extend_.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2012-11-15 22:04:07 +04:00
|
|
|
void RecursiveSortAndSet(ContextBase &context, VertexNode *&parent);
|
|
|
|
|
2012-10-15 16:58:33 +04:00
|
|
|
std::vector<VertexNode*> extend_;
|
|
|
|
|
|
|
|
lm::ngram::ChartState state_;
|
|
|
|
bool right_full_;
|
|
|
|
|
|
|
|
Score bound_;
|
2012-11-15 22:04:07 +04:00
|
|
|
History end_;
|
2012-10-15 16:58:33 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
class PartialVertex {
|
|
|
|
public:
|
|
|
|
PartialVertex() {}
|
|
|
|
|
|
|
|
explicit PartialVertex(const VertexNode &back) : back_(&back), index_(0) {}
|
|
|
|
|
|
|
|
bool Empty() const { return back_->Empty(); }
|
|
|
|
|
|
|
|
bool Complete() const { return back_->Complete(); }
|
|
|
|
|
|
|
|
const lm::ngram::ChartState &State() const { return back_->State(); }
|
|
|
|
bool RightFull() const { return back_->RightFull(); }
|
|
|
|
|
2012-11-15 22:04:07 +04:00
|
|
|
Score Bound() const { return Complete() ? back_->Bound() : (*back_)[index_].Bound(); }
|
2012-10-15 16:58:33 +04:00
|
|
|
|
|
|
|
unsigned char Length() const { return back_->Length(); }
|
|
|
|
|
|
|
|
bool HasAlternative() const {
|
|
|
|
return index_ + 1 < back_->Size();
|
|
|
|
}
|
|
|
|
|
2012-10-17 16:50:08 +04:00
|
|
|
// Split into continuation and alternative, rendering this the continuation.
|
|
|
|
bool Split(PartialVertex &alternative) {
|
2012-10-15 16:58:33 +04:00
|
|
|
assert(!Complete());
|
2012-10-17 16:50:08 +04:00
|
|
|
bool ret;
|
2012-10-15 16:58:33 +04:00
|
|
|
if (index_ + 1 < back_->Size()) {
|
2012-10-17 16:50:08 +04:00
|
|
|
alternative.index_ = index_ + 1;
|
|
|
|
alternative.back_ = back_;
|
|
|
|
ret = true;
|
|
|
|
} else {
|
|
|
|
ret = false;
|
2012-10-15 16:58:33 +04:00
|
|
|
}
|
2012-10-17 16:50:08 +04:00
|
|
|
back_ = &((*back_)[index_]);
|
|
|
|
index_ = 0;
|
|
|
|
return ret;
|
2012-10-15 16:58:33 +04:00
|
|
|
}
|
|
|
|
|
2012-11-15 22:04:07 +04:00
|
|
|
const History End() const {
|
2012-10-18 21:54:38 +04:00
|
|
|
return back_->End();
|
2012-10-15 16:58:33 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
const VertexNode *back_;
|
|
|
|
unsigned int index_;
|
|
|
|
};
|
|
|
|
|
2012-11-15 22:04:07 +04:00
|
|
|
template <class Output> class VertexGenerator;
|
|
|
|
|
2012-10-15 16:58:33 +04:00
|
|
|
class Vertex {
|
|
|
|
public:
|
|
|
|
Vertex() {}
|
|
|
|
|
|
|
|
PartialVertex RootPartial() const { return PartialVertex(root_); }
|
|
|
|
|
2012-11-15 22:04:07 +04:00
|
|
|
const History BestChild() const {
|
2012-10-15 16:58:33 +04:00
|
|
|
PartialVertex top(RootPartial());
|
|
|
|
if (top.Empty()) {
|
2012-11-15 22:04:07 +04:00
|
|
|
return History();
|
2012-10-15 16:58:33 +04:00
|
|
|
} else {
|
|
|
|
PartialVertex continuation;
|
|
|
|
while (!top.Complete()) {
|
|
|
|
top.Split(continuation);
|
|
|
|
}
|
2012-10-18 21:54:38 +04:00
|
|
|
return top.End();
|
2012-10-15 16:58:33 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2012-11-15 22:04:07 +04:00
|
|
|
template <class Output> friend class VertexGenerator;
|
|
|
|
template <class Output> friend class RootVertexGenerator;
|
2012-10-15 16:58:33 +04:00
|
|
|
VertexNode root_;
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace search
|
|
|
|
#endif // SEARCH_VERTEX__
|