| |
| |
| |
| |
| |
| |
| #include <boost/foreach.hpp> |
| #include <cstdlib> |
| #include <vector> |
| #include <sstream> |
| #include "../System.h" |
| #include "../TranslationModel/PhraseTable.h" |
| #include "Manager.h" |
| #include "InputPath.h" |
| #include "Hypothesis.h" |
| #include "TargetPhraseImpl.h" |
| #include "ActiveChart.h" |
| #include "Sentence.h" |
|
|
| #include "nbest/KBestExtractor.h" |
|
|
| using namespace std; |
|
|
| namespace Moses2 |
| { |
|
|
| namespace SCFG |
| { |
|
|
| Manager::Manager(System &sys, const TranslationTask &task, |
| const std::string &inputStr, long translationId) |
| :ManagerBase(sys, task, inputStr, translationId) |
| { |
|
|
| } |
|
|
| Manager::~Manager() |
| { |
|
|
| } |
|
|
| void Manager::Decode() |
| { |
| |
| |
| InitPools(); |
| |
|
|
| FactorCollection &vocab = system.GetVocab(); |
| m_input = Sentence::CreateFromString(GetPool(), vocab, system, m_inputStr, |
| m_translationId); |
|
|
| const SCFG::Sentence &sentence = static_cast<const SCFG::Sentence&>(GetInput()); |
|
|
| size_t inputSize = sentence.GetSize(); |
| |
|
|
| m_inputPaths.Init(sentence, *this); |
| |
|
|
| m_stacks.Init(*this, inputSize); |
| |
|
|
| for (int startPos = inputSize - 1; startPos >= 0; --startPos) { |
| |
| SCFG::InputPath &initPath = *m_inputPaths.GetMatrix().GetValue(startPos, 0); |
|
|
| |
| InitActiveChart(initPath); |
| |
|
|
| int maxPhraseSize = inputSize - startPos + 1; |
| for (int phraseSize = 1; phraseSize < maxPhraseSize; ++phraseSize) { |
| |
|
|
| SCFG::InputPath &path = *m_inputPaths.GetMatrix().GetValue(startPos, phraseSize); |
|
|
| Stack &stack = m_stacks.GetStack(startPos, phraseSize); |
|
|
| |
| Lookup(path); |
| |
| Decode(path, stack); |
| |
|
|
| LookupUnary(path); |
| |
|
|
| |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| } |
|
|
| void Manager::InitActiveChart(SCFG::InputPath &path) |
| { |
| size_t numPt = system.mappings.size(); |
| |
|
|
| for (size_t i = 0; i < numPt; ++i) { |
| const PhraseTable &pt = *system.mappings[i]; |
| |
| pt.InitActiveChart(GetPool(), *this, path); |
| |
| } |
| } |
|
|
| void Manager::Lookup(SCFG::InputPath &path) |
| { |
| size_t numPt = system.mappings.size(); |
| |
|
|
| for (size_t i = 0; i < numPt; ++i) { |
| const PhraseTable &pt = *system.mappings[i]; |
| size_t maxChartSpan = system.maxChartSpans[i]; |
| pt.Lookup(GetPool(), *this, maxChartSpan, m_stacks, path); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| } |
|
|
| void Manager::LookupUnary(SCFG::InputPath &path) |
| { |
| size_t numPt = system.mappings.size(); |
| |
|
|
| for (size_t i = 0; i < numPt; ++i) { |
| const PhraseTable &pt = *system.mappings[i]; |
| pt.LookupUnary(GetPool(), *this, m_stacks, path); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| } |
|
|
| |
| |
| |
| void Manager::Decode(SCFG::InputPath &path, Stack &stack) |
| { |
| |
| |
| |
| Recycler<HypothesisBase*> &hypoRecycler = GetHypoRecycler(); |
| while (!m_queue.empty()) { |
| QueueItem *item = m_queue.top(); |
| m_queue.pop(); |
| |
| Hypothesis *hypo = item->hypo; |
| hypoRecycler.Recycle(hypo); |
|
|
| |
| m_queueItemRecycler.push_back(item); |
| } |
|
|
| m_seenPositions.clear(); |
|
|
| |
| BOOST_FOREACH(const InputPath::Coll::value_type &valPair, path.targetPhrases) { |
| const SymbolBind &symbolBind = valPair.first; |
| const SCFG::TargetPhrases &tps = *valPair.second; |
|
|
| CreateQueue(path, symbolBind, tps); |
| } |
|
|
| |
| size_t pops = 0; |
| while (!m_queue.empty() && pops < system.options.cube.pop_limit) { |
| |
| QueueItem *item = m_queue.top(); |
| m_queue.pop(); |
|
|
| |
| Hypothesis *hypo = item->hypo; |
|
|
| |
| stack.Add(hypo, GetHypoRecycler(), arcLists); |
| |
|
|
| item->CreateNext(GetSystemPool(), GetPool(), *this, m_queue, m_seenPositions, path); |
| |
| m_queueItemRecycler.push_back(item); |
|
|
| ++pops; |
| } |
|
|
| } |
|
|
| void Manager::CreateQueue( |
| const SCFG::InputPath &path, |
| const SymbolBind &symbolBind, |
| const SCFG::TargetPhrases &tps) |
| { |
| MemPool &pool = GetPool(); |
|
|
| SeenPosition *seenItem = new (pool.Allocate<SeenPosition>()) SeenPosition(pool, symbolBind, tps, symbolBind.numNT); |
| bool unseen = m_seenPositions.Add(seenItem); |
| assert(unseen); |
|
|
| QueueItem *item = QueueItem::Create(GetPool(), *this); |
| item->Init(GetPool(), symbolBind, tps, seenItem->hypoIndColl); |
| for (size_t i = 0; i < symbolBind.coll.size(); ++i) { |
| const SymbolBindElement &ele = symbolBind.coll[i]; |
| if (ele.hypos) { |
| const Moses2::Hypotheses *hypos = ele.hypos; |
| item->AddHypos(*hypos); |
| } |
| } |
|
|
| item->CreateHypo(GetSystemPool(), *this, path, symbolBind); |
|
|
| |
|
|
| m_queue.push(item); |
| } |
|
|
| |
| |
| |
| void Manager::ExpandHypo( |
| const SCFG::InputPath &path, |
| const SCFG::SymbolBind &symbolBind, |
| const SCFG::TargetPhraseImpl &tp, |
| Stack &stack) |
| { |
| Recycler<HypothesisBase*> &hypoRecycler = GetHypoRecycler(); |
|
|
| std::vector<const SymbolBindElement*> ntEles = symbolBind.GetNTElements(); |
| Vector<size_t> prevHyposIndices(GetPool(), symbolBind.numNT); |
| assert(ntEles.size() == symbolBind.numNT); |
| |
|
|
| size_t ind = 0; |
| while (IncrPrevHypoIndices(prevHyposIndices, ind, ntEles)) { |
| SCFG::Hypothesis *hypo = SCFG::Hypothesis::Create(*this); |
| hypo->Init(*this, path, symbolBind, tp, prevHyposIndices); |
| hypo->EvaluateWhenApplied(); |
|
|
| stack.Add(hypo, hypoRecycler, arcLists); |
|
|
| ++ind; |
| } |
| } |
|
|
| bool Manager::IncrPrevHypoIndices( |
| Vector<size_t> &prevHyposIndices, |
| size_t ind, |
| const std::vector<const SymbolBindElement*> ntEles) |
| { |
| if (ntEles.size() == 0) { |
| |
| return ind ? false : true; |
| } |
|
|
| size_t numHypos = 0; |
|
|
| |
| for (size_t i = 0; i < ntEles.size() - 1; ++i) { |
| const SymbolBindElement &ele = *ntEles[i]; |
| const Hypotheses &hypos = *ele.hypos; |
| numHypos = hypos.size(); |
|
|
| std::div_t divRet = std::div((int)ind, (int)numHypos); |
| ind = divRet.quot; |
|
|
| size_t hypoInd = divRet.rem; |
| prevHyposIndices[i] = hypoInd; |
| |
| } |
|
|
| |
| prevHyposIndices.back() = ind; |
|
|
|
|
| |
| const SymbolBindElement &ele = *ntEles.back(); |
| const Hypotheses &hypos = *ele.hypos; |
| numHypos = hypos.size(); |
|
|
| |
| |
|
|
| if (ind >= numHypos) { |
| return false; |
| } else { |
| return true; |
| } |
| } |
|
|
| std::string Manager::OutputBest() const |
| { |
| string out; |
| const Stack &lastStack = m_stacks.GetLastStack(); |
| const SCFG::Hypothesis *bestHypo = lastStack.GetBestHypo(); |
|
|
| if (bestHypo) { |
| |
| |
| stringstream outStrm; |
| Moses2::FixPrecision(outStrm); |
|
|
| bestHypo->OutputToStream(outStrm); |
|
|
| out = outStrm.str(); |
| out = out.substr(4, out.size() - 10); |
|
|
| if (system.options.output.ReportHypoScore) { |
| out = SPrint(bestHypo->GetScores().GetTotalScore()) + " " + out; |
| } |
| } else { |
| if (system.options.output.ReportHypoScore) { |
| out = "0 "; |
| } |
|
|
| |
| } |
|
|
| return out; |
| } |
|
|
| std::string Manager::OutputNBest() |
| { |
| stringstream out; |
| |
|
|
| arcLists.Sort(); |
| |
|
|
| KBestExtractor extractor(*this); |
| extractor.OutputToStream(out); |
|
|
| return out.str(); |
| } |
|
|
| std::string Manager::OutputTransOpt() |
| { |
| const Stack &lastStack = m_stacks.GetLastStack(); |
| const SCFG::Hypothesis *bestHypo = lastStack.GetBestHypo(); |
|
|
| if (bestHypo) { |
| stringstream outStrm; |
| bestHypo->OutputTransOpt(outStrm); |
| return outStrm.str(); |
| } else { |
| return ""; |
| } |
| } |
|
|
| } |
| } |
|
|
|
|