|
#include "RuleTrieCYKPlus.h" |
|
|
|
#include <map> |
|
#include <vector> |
|
|
|
#include <boost/functional/hash.hpp> |
|
#include <boost/unordered_map.hpp> |
|
#include <boost/version.hpp> |
|
|
|
#include "moses/NonTerminal.h" |
|
#include "moses/TargetPhrase.h" |
|
#include "moses/TargetPhraseCollection.h" |
|
#include "moses/Util.h" |
|
#include "moses/Word.h" |
|
|
|
namespace Moses |
|
{ |
|
namespace Syntax |
|
{ |
|
namespace S2T |
|
{ |
|
|
|
void RuleTrieCYKPlus::Node::Prune(std::size_t tableLimit) |
|
{ |
|
|
|
for (SymbolMap::iterator p = m_sourceTermMap.begin(); |
|
p != m_sourceTermMap.end(); ++p) { |
|
p->second.Prune(tableLimit); |
|
} |
|
for (SymbolMap::iterator p = m_nonTermMap.begin(); |
|
p != m_nonTermMap.end(); ++p) { |
|
p->second.Prune(tableLimit); |
|
} |
|
|
|
|
|
m_targetPhraseCollection->Prune(true, tableLimit); |
|
} |
|
|
|
void RuleTrieCYKPlus::Node::Sort(std::size_t tableLimit) |
|
{ |
|
|
|
for (SymbolMap::iterator p = m_sourceTermMap.begin(); |
|
p != m_sourceTermMap.end(); ++p) { |
|
p->second.Sort(tableLimit); |
|
} |
|
for (SymbolMap::iterator p = m_nonTermMap.begin(); |
|
p != m_nonTermMap.end(); ++p) { |
|
p->second.Sort(tableLimit); |
|
} |
|
|
|
|
|
m_targetPhraseCollection->Sort(true, tableLimit); |
|
} |
|
|
|
RuleTrieCYKPlus::Node *RuleTrieCYKPlus::Node::GetOrCreateChild( |
|
const Word &sourceTerm) |
|
{ |
|
return &m_sourceTermMap[sourceTerm]; |
|
} |
|
|
|
RuleTrieCYKPlus::Node *RuleTrieCYKPlus::Node::GetOrCreateNonTerminalChild(const Word &targetNonTerm) |
|
{ |
|
UTIL_THROW_IF2(!targetNonTerm.IsNonTerminal(), |
|
"Not a non-terminal: " << targetNonTerm); |
|
|
|
return &m_nonTermMap[targetNonTerm]; |
|
} |
|
|
|
const RuleTrieCYKPlus::Node *RuleTrieCYKPlus::Node::GetChild( |
|
const Word &sourceTerm) const |
|
{ |
|
UTIL_THROW_IF2(sourceTerm.IsNonTerminal(), |
|
"Not a terminal: " << sourceTerm); |
|
|
|
SymbolMap::const_iterator p = m_sourceTermMap.find(sourceTerm); |
|
return (p == m_sourceTermMap.end()) ? NULL : &p->second; |
|
} |
|
|
|
const RuleTrieCYKPlus::Node *RuleTrieCYKPlus::Node::GetNonTerminalChild( |
|
const Word &targetNonTerm) const |
|
{ |
|
UTIL_THROW_IF2(!targetNonTerm.IsNonTerminal(), |
|
"Not a non-terminal: " << targetNonTerm); |
|
|
|
SymbolMap::const_iterator p = m_nonTermMap.find(targetNonTerm); |
|
return (p == m_nonTermMap.end()) ? NULL : &p->second; |
|
} |
|
|
|
TargetPhraseCollection::shared_ptr |
|
RuleTrieCYKPlus:: |
|
GetOrCreateTargetPhraseCollection(const Phrase &source, |
|
const TargetPhrase &target, |
|
const Word *sourceLHS) |
|
{ |
|
Node &currNode = GetOrCreateNode(source, target, sourceLHS); |
|
return currNode.GetTargetPhraseCollection(); |
|
} |
|
|
|
RuleTrieCYKPlus::Node &RuleTrieCYKPlus::GetOrCreateNode( |
|
const Phrase &source, const TargetPhrase &target, const Word *sourceLHS) |
|
{ |
|
const std::size_t size = source.GetSize(); |
|
|
|
const AlignmentInfo &alignmentInfo = target.GetAlignNonTerm(); |
|
AlignmentInfo::const_iterator iterAlign = alignmentInfo.begin(); |
|
|
|
Node *currNode = &m_root; |
|
for (std::size_t pos = 0 ; pos < size ; ++pos) { |
|
const Word& word = source.GetWord(pos); |
|
|
|
if (word.IsNonTerminal()) { |
|
UTIL_THROW_IF2(iterAlign == alignmentInfo.end(), |
|
"No alignment for non-term at position " << pos); |
|
UTIL_THROW_IF2(iterAlign->first != pos, |
|
"Alignment info incorrect at position " << pos); |
|
std::size_t targetNonTermInd = iterAlign->second; |
|
++iterAlign; |
|
const Word &targetNonTerm = target.GetWord(targetNonTermInd); |
|
currNode = currNode->GetOrCreateNonTerminalChild(targetNonTerm); |
|
} else { |
|
currNode = currNode->GetOrCreateChild(word); |
|
} |
|
|
|
UTIL_THROW_IF2(currNode == NULL, "Node not found at position " << pos); |
|
} |
|
|
|
return *currNode; |
|
} |
|
|
|
void RuleTrieCYKPlus::SortAndPrune(std::size_t tableLimit) |
|
{ |
|
if (tableLimit) { |
|
m_root.Sort(tableLimit); |
|
} |
|
} |
|
|
|
bool RuleTrieCYKPlus::HasPreterminalRule(const Word &w) const |
|
{ |
|
const Node::SymbolMap &map = m_root.GetTerminalMap(); |
|
Node::SymbolMap::const_iterator p = map.find(w); |
|
return p != map.end() && p->second.HasRules(); |
|
} |
|
|
|
} |
|
} |
|
} |
|
|