2009-08-07 20:47:54 +04:00
|
|
|
#include "Manager.h"
|
2008-12-20 23:22:35 +03:00
|
|
|
#include "Timer.h"
|
|
|
|
#include "SearchNormal.h"
|
2013-09-25 19:57:01 +04:00
|
|
|
#include "SentenceStats.h"
|
2008-12-20 23:22:35 +03:00
|
|
|
|
2015-02-06 02:35:53 +03:00
|
|
|
#include <boost/foreach.hpp>
|
|
|
|
|
2010-04-12 14:04:35 +04:00
|
|
|
using namespace std;
|
|
|
|
|
2008-12-20 23:22:35 +03:00
|
|
|
namespace Moses
|
|
|
|
{
|
2009-01-14 16:55:54 +03:00
|
|
|
/**
|
2008-12-20 23:22:35 +03:00
|
|
|
* Organizing main function
|
|
|
|
*
|
|
|
|
* /param source input sentence
|
|
|
|
* /param transOptColl collection of translation options to be used for this sentence
|
|
|
|
*/
|
2015-08-06 02:51:02 +03:00
|
|
|
SearchNormal::
|
2015-08-08 02:00:45 +03:00
|
|
|
SearchNormal(Manager& manager, const InputType &source,
|
|
|
|
const TranslationOptionCollection &transOptColl)
|
2015-10-26 12:20:08 +03:00
|
|
|
: Search(manager, source)
|
2015-08-06 02:51:02 +03:00
|
|
|
, m_hypoStackColl(source.GetSize() + 1)
|
|
|
|
, m_transOptColl(transOptColl)
|
2008-12-20 23:22:35 +03:00
|
|
|
{
|
2011-02-24 16:14:42 +03:00
|
|
|
VERBOSE(1, "Translating: " << m_source << endl);
|
2015-08-06 02:51:02 +03:00
|
|
|
|
|
|
|
// m_beam_width = manager.options().search.beam_width;
|
|
|
|
// m_stack_size = manager.options().search.stack_size;
|
|
|
|
// m_stack_diversity = manager.options().search.stack_diversity;
|
|
|
|
// m_timeout = manager.options().search.timeout;
|
|
|
|
// m_max_distortion = manager.options().reordering.max_distortion;
|
2011-02-24 16:14:42 +03:00
|
|
|
|
|
|
|
// only if constraint decoding (having to match a specified output)
|
2013-09-26 01:07:31 +04:00
|
|
|
// long sentenceID = source.GetTranslationId();
|
2011-02-24 16:14:42 +03:00
|
|
|
|
|
|
|
// initialize the stacks: create data structure and set limits
|
|
|
|
std::vector < HypothesisStackNormal >::iterator iterStack;
|
|
|
|
for (size_t ind = 0 ; ind < m_hypoStackColl.size() ; ++ind) {
|
|
|
|
HypothesisStackNormal *sourceHypoColl = new HypothesisStackNormal(m_manager);
|
2015-08-08 02:00:45 +03:00
|
|
|
sourceHypoColl->SetMaxHypoStackSize(this->m_options.search.stack_size,
|
|
|
|
this->m_options.search.stack_diversity);
|
2015-08-06 02:51:02 +03:00
|
|
|
sourceHypoColl->SetBeamWidth(this->m_options.search.beam_width);
|
2011-02-24 16:14:42 +03:00
|
|
|
m_hypoStackColl[ind] = sourceHypoColl;
|
|
|
|
}
|
2008-12-20 23:22:35 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
SearchNormal::~SearchNormal()
|
|
|
|
{
|
2011-02-24 16:14:42 +03:00
|
|
|
RemoveAllInColl(m_hypoStackColl);
|
2008-12-20 23:22:35 +03:00
|
|
|
}
|
|
|
|
|
2015-08-06 02:51:02 +03:00
|
|
|
|
2015-08-08 02:00:45 +03:00
|
|
|
bool
|
2015-08-06 02:51:02 +03:00
|
|
|
SearchNormal::
|
|
|
|
ProcessOneStack(HypothesisStack* hstack)
|
|
|
|
{
|
|
|
|
if (this->out_of_time()) return false;
|
|
|
|
SentenceStats &stats = m_manager.GetSentenceStats();
|
2015-08-10 02:01:01 +03:00
|
|
|
HypothesisStackNormal &sourceHypoColl
|
|
|
|
= *static_cast<HypothesisStackNormal*>(hstack);
|
2015-08-06 02:51:02 +03:00
|
|
|
|
|
|
|
// the stack is pruned before processing (lazy pruning):
|
|
|
|
VERBOSE(3,"processing hypothesis from next stack");
|
2015-08-08 02:00:45 +03:00
|
|
|
IFVERBOSE(2) stats.StartTimeStack();
|
2015-08-06 02:51:02 +03:00
|
|
|
sourceHypoColl.PruneToSize(m_options.search.stack_size);
|
|
|
|
VERBOSE(3,std::endl);
|
|
|
|
sourceHypoColl.CleanupArcList();
|
2015-08-08 02:00:45 +03:00
|
|
|
IFVERBOSE(2) stats.StopTimeStack();
|
2015-08-06 02:51:02 +03:00
|
|
|
|
|
|
|
// go through each hypothesis on the stack and try to expand it
|
2015-08-10 02:01:01 +03:00
|
|
|
// BOOST_FOREACH(Hypothesis* h, sourceHypoColl)
|
2015-08-07 21:19:04 +03:00
|
|
|
HypothesisStackNormal::const_iterator h;
|
|
|
|
for (h = sourceHypoColl.begin(); h != sourceHypoColl.end(); ++h)
|
2015-08-10 02:01:01 +03:00
|
|
|
ProcessOneHypothesis(**h);
|
2015-08-06 02:51:02 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-12-20 23:22:35 +03:00
|
|
|
/**
|
|
|
|
* Main decoder loop that translates a sentence by expanding
|
|
|
|
* hypotheses stack by stack, until the end of the sentence.
|
|
|
|
*/
|
2014-12-26 10:41:52 +03:00
|
|
|
void SearchNormal::Decode()
|
2009-01-14 16:55:54 +03:00
|
|
|
{
|
2015-08-08 14:57:05 +03:00
|
|
|
// SentenceStats &stats = m_manager.GetSentenceStats();
|
2011-02-24 16:14:42 +03:00
|
|
|
|
|
|
|
// initial seed hypothesis: nothing translated, no words produced
|
2015-10-26 12:20:08 +03:00
|
|
|
const Bitmap &initBitmap = m_bitmaps.GetInitialBitmap();
|
|
|
|
Hypothesis *hypo = new Hypothesis(m_manager, m_source, m_initialTransOpt, initBitmap);
|
2015-10-19 12:58:29 +03:00
|
|
|
|
2011-02-24 16:14:42 +03:00
|
|
|
m_hypoStackColl[0]->AddPrune(hypo);
|
|
|
|
|
|
|
|
// go through each stack
|
2015-08-06 02:51:02 +03:00
|
|
|
BOOST_FOREACH(HypothesisStack* hstack, m_hypoStackColl) {
|
|
|
|
if (!ProcessOneStack(hstack)) return;
|
2015-08-08 02:00:45 +03:00
|
|
|
IFVERBOSE(2) OutputHypoStackSize();
|
2015-08-06 02:51:02 +03:00
|
|
|
actual_hypoStack = static_cast<HypothesisStackNormal*>(hstack);
|
2011-02-24 16:14:42 +03:00
|
|
|
}
|
2008-12-20 23:22:35 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Find all translation options to expand one hypothesis, trigger expansion
|
|
|
|
* this is mostly a check for overlap with already covered words, and for
|
2009-01-14 16:55:54 +03:00
|
|
|
* violation of reordering limits.
|
2008-12-20 23:22:35 +03:00
|
|
|
* \param hypothesis hypothesis to be expanded upon
|
|
|
|
*/
|
2015-02-19 15:27:23 +03:00
|
|
|
void
|
2015-02-06 02:35:53 +03:00
|
|
|
SearchNormal::
|
|
|
|
ProcessOneHypothesis(const Hypothesis &hypothesis)
|
2008-12-20 23:22:35 +03:00
|
|
|
{
|
2011-02-24 16:14:42 +03:00
|
|
|
// since we check for reordering limits, its good to have that limit handy
|
2015-08-06 02:51:02 +03:00
|
|
|
// int maxDistortion = StaticData::Instance().GetMaxDistortion();
|
|
|
|
bool isWordLattice = m_source.GetType() == WordLatticeInput;
|
2011-02-24 16:14:42 +03:00
|
|
|
|
2015-10-26 14:59:20 +03:00
|
|
|
const Bitmap &hypoBitmap = hypothesis.GetWordsBitmap();
|
2015-02-06 02:35:53 +03:00
|
|
|
const size_t hypoFirstGapPos = hypoBitmap.GetFirstGapPos();
|
|
|
|
size_t const sourceSize = m_source.GetSize();
|
|
|
|
|
2015-02-19 15:27:23 +03:00
|
|
|
ReorderingConstraint const&
|
|
|
|
ReoConstraint = m_source.GetReorderingConstraint();
|
2015-02-06 02:35:53 +03:00
|
|
|
|
2011-02-24 16:14:42 +03:00
|
|
|
// no limit of reordering: only check for overlap
|
2015-08-06 02:51:02 +03:00
|
|
|
if (m_options.reordering.max_distortion < 0) {
|
2011-02-24 16:14:42 +03:00
|
|
|
|
2015-02-19 15:27:23 +03:00
|
|
|
for (size_t startPos = hypoFirstGapPos ; startPos < sourceSize ; ++startPos) {
|
|
|
|
TranslationOptionList const* tol;
|
|
|
|
size_t endPos = startPos;
|
|
|
|
for (tol = m_transOptColl.GetTranslationOptionList(startPos, endPos);
|
|
|
|
tol && endPos < sourceSize;
|
|
|
|
tol = m_transOptColl.GetTranslationOptionList(startPos, ++endPos)) {
|
|
|
|
if (tol->size() == 0
|
2015-10-25 16:37:59 +03:00
|
|
|
|| hypoBitmap.Overlap(Range(startPos, endPos))
|
2015-02-19 15:27:23 +03:00
|
|
|
|| !ReoConstraint.Check(hypoBitmap, startPos, endPos)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
//TODO: does this method include incompatible WordLattice hypotheses?
|
|
|
|
ExpandAllHypotheses(hypothesis, startPos, endPos);
|
2011-02-24 16:14:42 +03:00
|
|
|
}
|
2015-02-19 15:27:23 +03:00
|
|
|
}
|
2011-02-24 16:14:42 +03:00
|
|
|
return; // done with special case (no reordering limit)
|
|
|
|
}
|
|
|
|
|
2015-02-06 02:35:53 +03:00
|
|
|
// There are reordering limits. Make sure they are not violated.
|
2011-02-24 16:14:42 +03:00
|
|
|
|
2015-10-25 16:37:59 +03:00
|
|
|
Range prevRange = hypothesis.GetCurrSourceWordsRange();
|
2015-02-19 15:27:23 +03:00
|
|
|
for (size_t startPos = hypoFirstGapPos ; startPos < sourceSize ; ++startPos) {
|
|
|
|
|
|
|
|
// don't bother expanding phrases if the first position is already taken
|
|
|
|
if(hypoBitmap.GetValue(startPos)) continue;
|
|
|
|
|
|
|
|
size_t maxSize = sourceSize - startPos;
|
2015-08-06 02:51:02 +03:00
|
|
|
size_t maxSizePhrase = m_options.search.max_phrase_length;
|
2015-02-19 15:27:23 +03:00
|
|
|
maxSize = (maxSize < maxSizePhrase) ? maxSize : maxSizePhrase;
|
|
|
|
size_t closestLeft = hypoBitmap.GetEdgeToTheLeftOf(startPos);
|
|
|
|
|
|
|
|
if (isWordLattice) {
|
|
|
|
// first question: is there a path from the closest translated word to the left
|
|
|
|
// of the hypothesized extension to the start of the hypothesized extension?
|
|
|
|
// long version:
|
|
|
|
// - is there anything to our left?
|
|
|
|
// - is it farther left than where we're starting anyway?
|
|
|
|
// - can we get to it?
|
|
|
|
|
|
|
|
// closestLeft is exclusive: a value of 3 means 2 is covered, our
|
|
|
|
// arc is currently ENDING at 3 and can start at 3 implicitly
|
|
|
|
if (closestLeft != 0 && closestLeft != startPos
|
|
|
|
&& !m_source.CanIGetFromAToB(closestLeft, startPos))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (prevRange.GetStartPos() != NOT_FOUND &&
|
|
|
|
prevRange.GetStartPos() > startPos &&
|
|
|
|
!m_source.CanIGetFromAToB(startPos, prevRange.GetStartPos()))
|
|
|
|
continue;
|
|
|
|
}
|
2015-02-06 02:35:53 +03:00
|
|
|
|
2015-10-25 16:37:59 +03:00
|
|
|
Range currentStartRange(startPos, startPos);
|
2015-02-19 15:27:23 +03:00
|
|
|
if(m_source.ComputeDistortionDistance(prevRange, currentStartRange)
|
2015-08-06 02:51:02 +03:00
|
|
|
> m_options.reordering.max_distortion)
|
2015-02-19 15:27:23 +03:00
|
|
|
continue;
|
|
|
|
|
|
|
|
TranslationOptionList const* tol;
|
|
|
|
size_t endPos = startPos;
|
|
|
|
for (tol = m_transOptColl.GetTranslationOptionList(startPos, endPos);
|
|
|
|
tol && endPos < sourceSize;
|
|
|
|
tol = m_transOptColl.GetTranslationOptionList(startPos, ++endPos)) {
|
2015-10-25 16:37:59 +03:00
|
|
|
Range extRange(startPos, endPos);
|
2015-02-19 15:27:23 +03:00
|
|
|
if (tol->size() == 0
|
|
|
|
|| hypoBitmap.Overlap(extRange)
|
|
|
|
|| !ReoConstraint.Check(hypoBitmap, startPos, endPos)
|
|
|
|
|| (isWordLattice && !m_source.IsCoveragePossible(extRange))) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ask second question here: we already know we can get to our
|
|
|
|
// starting point from the closest thing to the left. We now ask the
|
|
|
|
// follow up: can we get from our end to the closest thing on the
|
|
|
|
// right?
|
|
|
|
//
|
|
|
|
// long version: is anything to our right? is it farther
|
|
|
|
// right than our (inclusive) end? can our end reach it?
|
|
|
|
bool isLeftMostEdge = (hypoFirstGapPos == startPos);
|
|
|
|
|
|
|
|
size_t closestRight = hypoBitmap.GetEdgeToTheRightOf(endPos);
|
|
|
|
if (isWordLattice) {
|
|
|
|
if (closestRight != endPos
|
|
|
|
&& ((closestRight + 1) < sourceSize)
|
|
|
|
&& !m_source.CanIGetFromAToB(endPos + 1, closestRight + 1)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isLeftMostEdge) {
|
|
|
|
// any length extension is okay if starting at left-most edge
|
|
|
|
ExpandAllHypotheses(hypothesis, startPos, endPos);
|
|
|
|
} else { // starting somewhere other than left-most edge, use caution
|
|
|
|
// the basic idea is this: we would like to translate a phrase
|
|
|
|
// starting from a position further right than the left-most
|
|
|
|
// open gap. The distortion penalty for the following phrase
|
|
|
|
// will be computed relative to the ending position of the
|
|
|
|
// current extension, so we ask now what its maximum value will
|
|
|
|
// be (which will always be the value of the hypothesis starting
|
|
|
|
// at the left-most edge). If this value is less than the
|
|
|
|
// distortion limit, we don't allow this extension to be made.
|
2015-10-25 16:37:59 +03:00
|
|
|
Range bestNextExtension(hypoFirstGapPos, hypoFirstGapPos);
|
2015-02-19 15:27:23 +03:00
|
|
|
|
|
|
|
if (m_source.ComputeDistortionDistance(extRange, bestNextExtension)
|
2015-08-06 02:51:02 +03:00
|
|
|
> m_options.reordering.max_distortion) continue;
|
2015-02-19 15:27:23 +03:00
|
|
|
|
|
|
|
// everything is fine, we're good to go
|
|
|
|
ExpandAllHypotheses(hypothesis, startPos, endPos);
|
|
|
|
}
|
2011-02-24 16:14:42 +03:00
|
|
|
}
|
2015-02-19 15:27:23 +03:00
|
|
|
}
|
2008-12-20 23:22:35 +03:00
|
|
|
}
|
2015-02-19 15:27:23 +03:00
|
|
|
|
2008-12-20 23:22:35 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Expand a hypothesis given a list of translation options
|
|
|
|
* \param hypothesis hypothesis to be expanded upon
|
|
|
|
* \param startPos first word position of span covered
|
|
|
|
* \param endPos last word position of span covered
|
|
|
|
*/
|
|
|
|
|
2015-02-19 15:27:23 +03:00
|
|
|
void
|
2015-02-06 02:35:53 +03:00
|
|
|
SearchNormal::
|
|
|
|
ExpandAllHypotheses(const Hypothesis &hypothesis, size_t startPos, size_t endPos)
|
2008-12-20 23:22:35 +03:00
|
|
|
{
|
2011-02-24 16:14:42 +03:00
|
|
|
// early discarding: check if hypothesis is too bad to build
|
|
|
|
// this idea is explained in (Moore&Quirk, MT Summit 2007)
|
|
|
|
float expectedScore = 0.0f;
|
2015-10-05 19:25:17 +03:00
|
|
|
|
2015-10-25 16:07:25 +03:00
|
|
|
const Bitmap &sourceCompleted = hypothesis.GetWordsBitmap();
|
2015-10-05 19:25:17 +03:00
|
|
|
float futureScore = m_transOptColl.GetFutureScore().CalcFutureScore2( sourceCompleted, startPos, endPos );
|
|
|
|
|
2015-11-09 03:10:07 +03:00
|
|
|
const Range &hypoRange = hypothesis.GetCurrSourceWordsRange();
|
|
|
|
cerr << "DOING " << sourceCompleted << " [" << hypoRange.GetStartPos() << " " << hypoRange.GetEndPos() << "]"
|
|
|
|
" [" << startPos << " " << endPos << "]" << endl;
|
2015-11-09 03:07:34 +03:00
|
|
|
|
2015-08-06 02:51:02 +03:00
|
|
|
if (m_options.search.UseEarlyDiscarding()) {
|
2011-02-24 16:14:42 +03:00
|
|
|
// expected score is based on score of current hypothesis
|
|
|
|
expectedScore = hypothesis.GetScore();
|
2015-02-19 15:27:23 +03:00
|
|
|
|
2011-02-24 16:14:42 +03:00
|
|
|
// add new future score estimate
|
2015-10-05 19:25:17 +03:00
|
|
|
expectedScore += futureScore;
|
2011-02-24 16:14:42 +03:00
|
|
|
}
|
2015-02-19 15:27:23 +03:00
|
|
|
|
2011-02-24 16:14:42 +03:00
|
|
|
// loop through all translation options
|
2015-02-19 15:27:23 +03:00
|
|
|
const TranslationOptionList* tol
|
|
|
|
= m_transOptColl.GetTranslationOptionList(startPos, endPos);
|
2015-10-20 15:04:35 +03:00
|
|
|
if (!tol || tol->size() == 0) return;
|
|
|
|
|
|
|
|
// Create new bitmap
|
|
|
|
const TranslationOption &transOpt = **tol->begin();
|
2015-10-25 16:37:59 +03:00
|
|
|
const Range &nextRange = transOpt.GetSourceWordsRange();
|
2015-10-25 16:07:25 +03:00
|
|
|
const Bitmap &nextBitmap = m_bitmaps.GetBitmap(sourceCompleted, nextRange);
|
2015-10-20 15:04:35 +03:00
|
|
|
|
2011-02-24 16:14:42 +03:00
|
|
|
TranslationOptionList::const_iterator iter;
|
2015-02-06 02:35:53 +03:00
|
|
|
for (iter = tol->begin() ; iter != tol->end() ; ++iter) {
|
2015-10-20 22:16:07 +03:00
|
|
|
const TranslationOption &transOpt = **iter;
|
2015-10-20 15:04:35 +03:00
|
|
|
ExpandHypothesis(hypothesis, transOpt, expectedScore, futureScore, nextBitmap);
|
2011-02-24 16:14:42 +03:00
|
|
|
}
|
2008-12-20 23:22:35 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Expand one hypothesis with a translation option.
|
|
|
|
* this involves initial creation, scoring and adding it to the proper stack
|
|
|
|
* \param hypothesis hypothesis to be expanded upon
|
2009-01-14 16:55:54 +03:00
|
|
|
* \param transOpt translation option (phrase translation)
|
2008-12-20 23:22:35 +03:00
|
|
|
* that is applied to create the new hypothesis
|
2009-01-14 16:55:54 +03:00
|
|
|
* \param expectedScore base score for early discarding
|
2008-12-20 23:22:35 +03:00
|
|
|
* (base hypothesis score plus future score estimation)
|
|
|
|
*/
|
2015-10-05 19:25:17 +03:00
|
|
|
void SearchNormal::ExpandHypothesis(const Hypothesis &hypothesis,
|
2015-10-06 02:00:40 +03:00
|
|
|
const TranslationOption &transOpt,
|
|
|
|
float expectedScore,
|
2015-10-20 15:04:35 +03:00
|
|
|
float futureScore,
|
2015-10-25 16:07:25 +03:00
|
|
|
const Bitmap &bitmap)
|
2008-12-20 23:22:35 +03:00
|
|
|
{
|
2011-02-24 16:14:42 +03:00
|
|
|
const StaticData &staticData = StaticData::Instance();
|
|
|
|
SentenceStats &stats = m_manager.GetSentenceStats();
|
|
|
|
|
|
|
|
Hypothesis *newHypo;
|
2015-08-06 02:51:02 +03:00
|
|
|
if (! m_options.search.UseEarlyDiscarding()) {
|
2011-02-24 16:14:42 +03:00
|
|
|
// simple build, no questions asked
|
|
|
|
IFVERBOSE(2) {
|
2014-01-03 22:45:31 +04:00
|
|
|
stats.StartTimeBuildHyp();
|
2011-02-24 16:14:42 +03:00
|
|
|
}
|
2015-10-20 15:04:35 +03:00
|
|
|
newHypo = new Hypothesis(hypothesis, transOpt, bitmap);
|
2011-02-24 16:14:42 +03:00
|
|
|
IFVERBOSE(2) {
|
2014-01-03 22:45:31 +04:00
|
|
|
stats.StopTimeBuildHyp();
|
2011-02-24 16:14:42 +03:00
|
|
|
}
|
|
|
|
if (newHypo==NULL) return;
|
2015-10-05 19:25:17 +03:00
|
|
|
newHypo->EvaluateWhenApplied(futureScore);
|
2011-02-24 16:14:42 +03:00
|
|
|
} else
|
|
|
|
// early discarding: check if hypothesis is too bad to build
|
|
|
|
{
|
|
|
|
// worst possible score may have changed -> recompute
|
|
|
|
size_t wordsTranslated = hypothesis.GetWordsBitmap().GetNumWordsCovered() + transOpt.GetSize();
|
|
|
|
float allowedScore = m_hypoStackColl[wordsTranslated]->GetWorstScore();
|
2015-08-06 02:51:02 +03:00
|
|
|
if (m_options.search.stack_diversity) {
|
2011-02-24 16:14:42 +03:00
|
|
|
WordsBitmapID id = hypothesis.GetWordsBitmap().GetIDPlus(transOpt.GetStartPos(), transOpt.GetEndPos());
|
|
|
|
float allowedScoreForBitmap = m_hypoStackColl[wordsTranslated]->GetWorstScoreForBitmap( id );
|
|
|
|
allowedScore = std::min( allowedScore, allowedScoreForBitmap );
|
|
|
|
}
|
|
|
|
allowedScore += staticData.GetEarlyDiscardingThreshold();
|
|
|
|
|
|
|
|
// add expected score of translation option
|
|
|
|
expectedScore += transOpt.GetFutureScore();
|
|
|
|
|
|
|
|
// check if transOpt score push it already below limit
|
|
|
|
if (expectedScore < allowedScore) {
|
|
|
|
IFVERBOSE(2) {
|
|
|
|
stats.AddNotBuilt();
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// build the hypothesis without scoring
|
|
|
|
IFVERBOSE(2) {
|
2014-01-03 22:45:31 +04:00
|
|
|
stats.StartTimeBuildHyp();
|
2011-02-24 16:14:42 +03:00
|
|
|
}
|
2015-10-20 16:01:09 +03:00
|
|
|
newHypo = new Hypothesis(hypothesis, transOpt, bitmap);
|
2011-02-24 16:14:42 +03:00
|
|
|
if (newHypo==NULL) return;
|
|
|
|
IFVERBOSE(2) {
|
2014-01-03 22:45:31 +04:00
|
|
|
stats.StopTimeBuildHyp();
|
2011-02-24 16:14:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// ... and check if that is below the limit
|
|
|
|
if (expectedScore < allowedScore) {
|
|
|
|
IFVERBOSE(2) {
|
|
|
|
stats.AddEarlyDiscarded();
|
|
|
|
}
|
2015-10-19 12:58:29 +03:00
|
|
|
delete newHypo;
|
2011-02-24 16:14:42 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// logging for the curious
|
|
|
|
IFVERBOSE(3) {
|
|
|
|
newHypo->PrintHypothesis();
|
|
|
|
}
|
|
|
|
|
|
|
|
// add to hypothesis stack
|
|
|
|
size_t wordsTranslated = newHypo->GetWordsBitmap().GetNumWordsCovered();
|
|
|
|
IFVERBOSE(2) {
|
2014-01-03 22:45:31 +04:00
|
|
|
stats.StartTimeStack();
|
2011-02-24 16:14:42 +03:00
|
|
|
}
|
|
|
|
m_hypoStackColl[wordsTranslated]->AddPrune(newHypo);
|
|
|
|
IFVERBOSE(2) {
|
2014-01-03 22:45:31 +04:00
|
|
|
stats.StopTimeStack();
|
2011-02-24 16:14:42 +03:00
|
|
|
}
|
2008-12-20 23:22:35 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
const std::vector < HypothesisStack* >& SearchNormal::GetHypothesisStacks() const
|
|
|
|
{
|
2011-02-24 16:14:42 +03:00
|
|
|
return m_hypoStackColl;
|
2008-12-20 23:22:35 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Find best hypothesis on the last stack.
|
|
|
|
* This is the end point of the best translation, which can be traced back from here
|
|
|
|
*/
|
|
|
|
const Hypothesis *SearchNormal::GetBestHypothesis() const
|
|
|
|
{
|
2011-02-24 16:14:42 +03:00
|
|
|
if (interrupted_flag == 0) {
|
|
|
|
const HypothesisStackNormal &hypoColl = *static_cast<HypothesisStackNormal*>(m_hypoStackColl.back());
|
|
|
|
return hypoColl.GetBestHypothesis();
|
|
|
|
} else {
|
|
|
|
const HypothesisStackNormal &hypoColl = *actual_hypoStack;
|
|
|
|
return hypoColl.GetBestHypothesis();
|
|
|
|
}
|
2008-12-20 23:22:35 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Logging of hypothesis stack sizes
|
|
|
|
*/
|
|
|
|
void SearchNormal::OutputHypoStackSize()
|
|
|
|
{
|
2011-02-24 16:14:42 +03:00
|
|
|
std::vector < HypothesisStack* >::const_iterator iterStack = m_hypoStackColl.begin();
|
|
|
|
TRACE_ERR( "Stack sizes: " << (int)(*iterStack)->size());
|
|
|
|
for (++iterStack; iterStack != m_hypoStackColl.end() ; ++iterStack) {
|
|
|
|
TRACE_ERR( ", " << (int)(*iterStack)->size());
|
|
|
|
}
|
|
|
|
TRACE_ERR( endl);
|
2008-12-20 23:22:35 +03:00
|
|
|
}
|
|
|
|
|
2014-04-03 20:21:31 +04:00
|
|
|
void SearchNormal::OutputHypoStack()
|
2014-04-03 19:54:46 +04:00
|
|
|
{
|
2015-01-14 14:07:42 +03:00
|
|
|
// all stacks
|
|
|
|
int i = 0;
|
|
|
|
vector < HypothesisStack* >::iterator iterStack;
|
|
|
|
for (iterStack = m_hypoStackColl.begin() ; iterStack != m_hypoStackColl.end() ; ++iterStack) {
|
|
|
|
HypothesisStackNormal &hypoColl = *static_cast<HypothesisStackNormal*>(*iterStack);
|
|
|
|
TRACE_ERR( "Stack " << i++ << ": " << endl << hypoColl << endl);
|
|
|
|
}
|
2014-04-03 19:54:46 +04:00
|
|
|
}
|
|
|
|
|
2008-12-20 23:22:35 +03:00
|
|
|
}
|