00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <algorithm>
00023 #include <limits>
00024 #include <utility>
00025
00026 #include "BitmapContainer.h"
00027 #include "HypothesisStackCubePruning.h"
00028 #include "DummyScoreProducers.h"
00029 #include "TranslationOptionList.h"
00030 #include "TranslationSystem.h"
00031
00032 namespace Moses
00033 {
00034
00035 class HypothesisScoreOrdererNoDistortion
00036 {
00037 public:
00038 bool operator()(const Hypothesis* hypoA, const Hypothesis* hypoB) const {
00039 const float scoreA = hypoA->GetScore();
00040 const float scoreB = hypoB->GetScore();
00041
00042 if (scoreA > scoreB) {
00043 return true;
00044 } else if (scoreA < scoreB) {
00045 return false;
00046 } else {
00047 return hypoA < hypoB;
00048 }
00049 }
00050 };
00051
00052 class HypothesisScoreOrdererWithDistortion
00053 {
00054 public:
00055 HypothesisScoreOrdererWithDistortion(const WordsRange* transOptRange, const TranslationSystem* system) :
00056 m_transOptRange(transOptRange), m_system(system) {}
00057
00058 const WordsRange* m_transOptRange;
00059 const TranslationSystem* m_system;
00060
00061 bool operator()(const Hypothesis* hypoA, const Hypothesis* hypoB) const {
00062 CHECK(m_transOptRange != NULL);
00063
00064 const float weightDistortion = m_system->GetWeightDistortion();
00065 const DistortionScoreProducer *dsp = m_system->GetDistortionProducer();
00066 const float distortionScoreA = dsp->CalculateDistortionScore(
00067 *hypoA,
00068 hypoA->GetCurrSourceWordsRange(),
00069 *m_transOptRange,
00070 hypoA->GetWordsBitmap().GetFirstGapPos()
00071 );
00072 const float distortionScoreB = dsp->CalculateDistortionScore(
00073 *hypoB,
00074 hypoB->GetCurrSourceWordsRange(),
00075 *m_transOptRange,
00076 hypoB->GetWordsBitmap().GetFirstGapPos()
00077 );
00078
00079 const float scoreA = hypoA->GetScore() + distortionScoreA * weightDistortion;
00080 const float scoreB = hypoB->GetScore() + distortionScoreB * weightDistortion;
00081
00082 if (scoreA > scoreB) {
00083 return true;
00084 } else if (scoreA < scoreB) {
00085 return false;
00086 } else {
00087 return hypoA < hypoB;
00088 }
00089 }
00090
00091 };
00092
00094
00096
00097 BackwardsEdge::BackwardsEdge(const BitmapContainer &prevBitmapContainer
00098 , BitmapContainer &parent
00099 , const TranslationOptionList &translations
00100 , const SquareMatrix &futureScore,
00101 const InputType& itype,
00102 const TranslationSystem* system)
00103 : m_initialized(false)
00104 , m_prevBitmapContainer(prevBitmapContainer)
00105 , m_parent(parent)
00106 , m_translations(translations)
00107 , m_futurescore(futureScore)
00108 , m_seenPosition()
00109 {
00110
00111
00112 if(m_prevBitmapContainer.GetHypotheses().size() == 0 || m_translations.size() == 0) {
00113 VERBOSE(3, "Empty cube on BackwardsEdge" << std::endl);
00114 return;
00115 }
00116
00117
00118 int maxDistortion = StaticData::Instance().GetMaxDistortion();
00119
00120 if (maxDistortion == -1) {
00121 for (HypothesisSet::const_iterator iter = m_prevBitmapContainer.GetHypotheses().begin(); iter != m_prevBitmapContainer.GetHypotheses().end(); ++iter) {
00122 m_hypotheses.push_back(*iter);
00123 }
00124 return;
00125 }
00126
00127 const WordsRange &transOptRange = translations.Get(0)->GetSourceWordsRange();
00128
00129 HypothesisSet::const_iterator iterHypo = m_prevBitmapContainer.GetHypotheses().begin();
00130 HypothesisSet::const_iterator iterEnd = m_prevBitmapContainer.GetHypotheses().end();
00131
00132 while (iterHypo != iterEnd) {
00133 const Hypothesis &hypo = **iterHypo;
00134
00135
00136
00137 if (hypo.GetWordsBitmap().GetNumWordsCovered() == 0) {
00138 if ((int)transOptRange.GetStartPos() <= maxDistortion)
00139 m_hypotheses.push_back(&hypo);
00140 } else {
00141 int distortionDistance = itype.ComputeDistortionDistance(hypo.GetCurrSourceWordsRange()
00142 , transOptRange);
00143
00144 if (distortionDistance <= maxDistortion)
00145 m_hypotheses.push_back(&hypo);
00146 }
00147
00148 ++iterHypo;
00149 }
00150
00151 if (m_translations.size() > 1) {
00152 CHECK(m_translations.Get(0)->GetFutureScore() >= m_translations.Get(1)->GetFutureScore());
00153 }
00154
00155 if (m_hypotheses.size() > 1) {
00156 CHECK(m_hypotheses[0]->GetTotalScore() >= m_hypotheses[1]->GetTotalScore());
00157 }
00158
00159 HypothesisScoreOrdererWithDistortion orderer (&transOptRange, system);
00160 std::sort(m_hypotheses.begin(), m_hypotheses.end(), orderer);
00161
00162
00163 }
00164
00165 BackwardsEdge::~BackwardsEdge()
00166 {
00167 m_seenPosition.clear();
00168 m_hypotheses.clear();
00169 }
00170
00171
00172 void
00173 BackwardsEdge::Initialize()
00174 {
00175 if(m_hypotheses.size() == 0 || m_translations.size() == 0) {
00176 m_initialized = true;
00177 return;
00178 }
00179
00180 Hypothesis *expanded = CreateHypothesis(*m_hypotheses[0], *m_translations.Get(0));
00181 m_parent.Enqueue(0, 0, expanded, this);
00182 SetSeenPosition(0, 0);
00183 m_initialized = true;
00184 }
00185
00186 Hypothesis *BackwardsEdge::CreateHypothesis(const Hypothesis &hypothesis, const TranslationOption &transOpt)
00187 {
00188
00189 Hypothesis *newHypo = hypothesis.CreateNext(transOpt, NULL);
00190 newHypo->CalcScore(m_futurescore);
00191
00192 return newHypo;
00193 }
00194
00195 bool
00196 BackwardsEdge::SeenPosition(const size_t x, const size_t y)
00197 {
00198 std::set< int >::iterator iter = m_seenPosition.find((x<<16) + y);
00199 return (iter != m_seenPosition.end());
00200 }
00201
00202 void
00203 BackwardsEdge::SetSeenPosition(const size_t x, const size_t y)
00204 {
00205 CHECK(x < (1<<17));
00206 CHECK(y < (1<<17));
00207
00208 m_seenPosition.insert((x<<16) + y);
00209 }
00210
00211
00212 bool
00213 BackwardsEdge::GetInitialized()
00214 {
00215 return m_initialized;
00216 }
00217
00218 const BitmapContainer&
00219 BackwardsEdge::GetBitmapContainer() const
00220 {
00221 return m_prevBitmapContainer;
00222 }
00223
00224 void
00225 BackwardsEdge::PushSuccessors(const size_t x, const size_t y)
00226 {
00227 Hypothesis *newHypo;
00228
00229 if(y + 1 < m_translations.size() && !SeenPosition(x, y + 1)) {
00230 SetSeenPosition(x, y + 1);
00231 newHypo = CreateHypothesis(*m_hypotheses[x], *m_translations.Get(y + 1));
00232 if(newHypo != NULL) {
00233 m_parent.Enqueue(x, y + 1, newHypo, (BackwardsEdge*)this);
00234 }
00235 }
00236
00237 if(x + 1 < m_hypotheses.size() && !SeenPosition(x + 1, y)) {
00238 SetSeenPosition(x + 1, y);
00239 newHypo = CreateHypothesis(*m_hypotheses[x + 1], *m_translations.Get(y));
00240 if(newHypo != NULL) {
00241 m_parent.Enqueue(x + 1, y, newHypo, (BackwardsEdge*)this);
00242 }
00243 }
00244 }
00245
00246
00248
00250
00251 BitmapContainer::BitmapContainer(const WordsBitmap &bitmap
00252 , HypothesisStackCubePruning &stack)
00253 : m_bitmap(bitmap)
00254 , m_stack(stack)
00255 , m_numStackInsertions(0)
00256 {
00257 m_hypotheses = HypothesisSet();
00258 m_edges = BackwardsEdgeSet();
00259 m_queue = HypothesisQueue();
00260 }
00261
00262 BitmapContainer::~BitmapContainer()
00263 {
00264
00265 HypothesisQueueItem *item = NULL;
00266
00267 while (!m_queue.empty()) {
00268 item = m_queue.top();
00269 FREEHYPO(item->GetHypothesis());
00270 delete item;
00271 m_queue.pop();
00272 }
00273
00274
00275 RemoveAllInColl(m_edges);
00276
00277 m_hypotheses.clear();
00278 m_edges.clear();
00279 }
00280
00281
00282 void
00283 BitmapContainer::Enqueue(int hypothesis_pos
00284 , int translation_pos
00285 , Hypothesis *hypothesis
00286 , BackwardsEdge *edge)
00287 {
00288 HypothesisQueueItem *item = new HypothesisQueueItem(hypothesis_pos
00289 , translation_pos
00290 , hypothesis
00291 , edge);
00292 m_queue.push(item);
00293 }
00294
00295 HypothesisQueueItem*
00296 BitmapContainer::Dequeue(bool keepValue)
00297 {
00298 if (!m_queue.empty()) {
00299 HypothesisQueueItem *item = m_queue.top();
00300
00301 if (!keepValue) {
00302 m_queue.pop();
00303 }
00304
00305 return item;
00306 }
00307
00308 return NULL;
00309 }
00310
00311 HypothesisQueueItem*
00312 BitmapContainer::Top() const
00313 {
00314 return m_queue.top();
00315 }
00316
00317 size_t
00318 BitmapContainer::Size()
00319 {
00320 return m_queue.size();
00321 }
00322
00323 bool
00324 BitmapContainer::Empty() const
00325 {
00326 return m_queue.empty();
00327 }
00328
00329
00330 const WordsBitmap&
00331 BitmapContainer::GetWordsBitmap()
00332 {
00333 return m_bitmap;
00334 }
00335
00336 const HypothesisSet&
00337 BitmapContainer::GetHypotheses() const
00338 {
00339 return m_hypotheses;
00340 }
00341
00342 size_t
00343 BitmapContainer::GetHypothesesSize() const
00344 {
00345 return m_hypotheses.size();
00346 }
00347
00348 const BackwardsEdgeSet&
00349 BitmapContainer::GetBackwardsEdges()
00350 {
00351 return m_edges;
00352 }
00353
00354 void
00355 BitmapContainer::AddHypothesis(Hypothesis *hypothesis)
00356 {
00357 bool itemExists = false;
00358 HypothesisSet::const_iterator iter = m_hypotheses.begin();
00359 HypothesisSet::const_iterator iterEnd = m_hypotheses.end();
00360
00361
00362 while (iter != iterEnd) {
00363 if (*iter == hypothesis) {
00364 itemExists = true;
00365 break;
00366 }
00367
00368 ++iter;
00369 }
00370 CHECK(itemExists == false);
00371 m_hypotheses.push_back(hypothesis);
00372 }
00373
00374 void
00375 BitmapContainer::AddBackwardsEdge(BackwardsEdge *edge)
00376 {
00377 m_edges.insert(edge);
00378 }
00379
00380 void
00381 BitmapContainer::InitializeEdges()
00382 {
00383 BackwardsEdgeSet::iterator iter = m_edges.begin();
00384 BackwardsEdgeSet::iterator iterEnd = m_edges.end();
00385
00386 while (iter != iterEnd) {
00387 BackwardsEdge *edge = *iter;
00388 edge->Initialize();
00389
00390 ++iter;
00391 }
00392 }
00393
00394 void
00395 BitmapContainer::EnsureMinStackHyps(const size_t minNumHyps)
00396 {
00397 while ((!Empty()) && m_numStackInsertions < minNumHyps) {
00398 ProcessBestHypothesis();
00399 }
00400 }
00401
00402 void
00403 BitmapContainer::ProcessBestHypothesis()
00404 {
00405 if (m_queue.empty()) {
00406 return;
00407 }
00408
00409
00410 HypothesisQueueItem *item = Dequeue();
00411
00412
00413 CHECK(item != NULL);
00414
00415
00416 if (!Empty()) {
00417 HypothesisQueueItem *check = Dequeue(true);
00418 CHECK(item->GetHypothesis()->GetTotalScore() >= check->GetHypothesis()->GetTotalScore());
00419 }
00420
00421
00422 IFVERBOSE(3) {
00423
00424 item->GetHypothesis()->PrintHypothesis();
00425 }
00426
00427
00428 const bool newstackentry = m_stack.AddPrune(item->GetHypothesis());
00429 if (newstackentry)
00430 m_numStackInsertions++;
00431
00432 IFVERBOSE(3) {
00433 TRACE_ERR("new stack entry flag is " << newstackentry << std::endl);
00434 }
00435
00436
00437 item->GetBackwardsEdge()->PushSuccessors(item->GetHypothesisPos(), item->GetTranslationPos());
00438
00439
00440 delete item;
00441 }
00442
00443 void
00444 BitmapContainer::SortHypotheses()
00445 {
00446 std::sort(m_hypotheses.begin(), m_hypotheses.end(), HypothesisScoreOrderer());
00447 }
00448
00449 }
00450