|
|
#include "PatternApplicationTrie.h" |
|
|
|
|
|
#include "moses/Syntax/PVertex.h" |
|
|
|
|
|
namespace Moses |
|
|
{ |
|
|
namespace Syntax |
|
|
{ |
|
|
namespace S2T |
|
|
{ |
|
|
|
|
|
int PatternApplicationTrie::Depth() const |
|
|
{ |
|
|
if (m_parent) { |
|
|
return m_parent->Depth() + 1; |
|
|
} |
|
|
return 0; |
|
|
} |
|
|
|
|
|
const PatternApplicationTrie * |
|
|
PatternApplicationTrie::GetHighestTerminalNode() const |
|
|
{ |
|
|
|
|
|
if (m_highestTerminalNode) { |
|
|
return m_highestTerminalNode; |
|
|
} |
|
|
|
|
|
if (!m_parent) { |
|
|
return 0; |
|
|
} |
|
|
|
|
|
if (!m_parent->m_parent) { |
|
|
if (IsTerminalNode()) { |
|
|
m_highestTerminalNode = this; |
|
|
return this; |
|
|
} else { |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
if (const PatternApplicationTrie *p = m_parent->GetHighestTerminalNode()) { |
|
|
m_highestTerminalNode = p; |
|
|
return p; |
|
|
} |
|
|
|
|
|
if (IsTerminalNode()) { |
|
|
m_highestTerminalNode = this; |
|
|
} |
|
|
return m_highestTerminalNode; |
|
|
} |
|
|
|
|
|
const PatternApplicationTrie * |
|
|
PatternApplicationTrie::GetLowestTerminalNode() const |
|
|
{ |
|
|
|
|
|
if (m_lowestTerminalNode) { |
|
|
return m_lowestTerminalNode; |
|
|
} |
|
|
|
|
|
if (!m_parent) { |
|
|
return 0; |
|
|
} |
|
|
|
|
|
if (IsTerminalNode()) { |
|
|
m_lowestTerminalNode = this; |
|
|
return this; |
|
|
} |
|
|
|
|
|
if (!m_parent->m_parent) { |
|
|
return 0; |
|
|
} |
|
|
|
|
|
return m_parent->GetLowestTerminalNode(); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void PatternApplicationTrie::DetermineStartRange(int sentenceLength, |
|
|
int &minStart, |
|
|
int &maxStart) const |
|
|
{ |
|
|
|
|
|
const PatternApplicationTrie *n = GetHighestTerminalNode(); |
|
|
if (!n) { |
|
|
|
|
|
minStart = 0; |
|
|
maxStart = sentenceLength-Depth(); |
|
|
return; |
|
|
} |
|
|
assert(n->m_parent); |
|
|
if (!n->m_parent->m_parent) { |
|
|
|
|
|
|
|
|
minStart = n->m_start; |
|
|
maxStart = n->m_start; |
|
|
} else { |
|
|
|
|
|
|
|
|
|
|
|
minStart = 0; |
|
|
maxStart = n->m_start - (n->Depth()-1); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void PatternApplicationTrie::DetermineEndRange(int sentenceLength, |
|
|
int &minEnd, |
|
|
int &maxEnd) const |
|
|
{ |
|
|
|
|
|
const PatternApplicationTrie *n = GetLowestTerminalNode(); |
|
|
if (!n) { |
|
|
|
|
|
minEnd = Depth()-1; |
|
|
maxEnd = sentenceLength-1; |
|
|
return; |
|
|
} |
|
|
if (n == this) { |
|
|
|
|
|
minEnd = m_end; |
|
|
maxEnd = m_end; |
|
|
} else { |
|
|
|
|
|
|
|
|
|
|
|
minEnd = n->m_end + (Depth()-n->Depth()); |
|
|
maxEnd = sentenceLength-1; |
|
|
} |
|
|
} |
|
|
|
|
|
void PatternApplicationTrie::Extend(const RuleTrieScope3::Node &node, |
|
|
int minPos, const SentenceMap &sentMap, |
|
|
bool followsGap) |
|
|
{ |
|
|
const RuleTrieScope3::Node::TerminalMap &termMap = node.GetTerminalMap(); |
|
|
for (RuleTrieScope3::Node::TerminalMap::const_iterator p = termMap.begin(); |
|
|
p != termMap.end(); ++p) { |
|
|
const Word &word = p->first; |
|
|
const RuleTrieScope3::Node &child = p->second; |
|
|
SentenceMap::const_iterator q = sentMap.find(word); |
|
|
if (q == sentMap.end()) { |
|
|
continue; |
|
|
} |
|
|
for (std::vector<const PVertex *>::const_iterator r = q->second.begin(); |
|
|
r != q->second.end(); ++r) { |
|
|
const PVertex *v = *r; |
|
|
std::size_t start = v->span.GetStartPos(); |
|
|
std::size_t end = v->span.GetEndPos(); |
|
|
if (start == (std::size_t)minPos || |
|
|
(followsGap && start > (std::size_t)minPos) || |
|
|
minPos == -1) { |
|
|
PatternApplicationTrie *subTrie = |
|
|
new PatternApplicationTrie(start, end, child, v, this); |
|
|
subTrie->Extend(child, end+1, sentMap, false); |
|
|
m_children.push_back(subTrie); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
const RuleTrieScope3::Node *child = node.GetNonTerminalChild(); |
|
|
if (!child) { |
|
|
return; |
|
|
} |
|
|
int start = followsGap ? -1 : minPos; |
|
|
PatternApplicationTrie *subTrie = |
|
|
new PatternApplicationTrie(start, -1, *child, 0, this); |
|
|
int newMinPos = (minPos == -1 ? 1 : minPos+1); |
|
|
subTrie->Extend(*child, newMinPos, sentMap, true); |
|
|
m_children.push_back(subTrie); |
|
|
} |
|
|
|
|
|
void PatternApplicationTrie::ReadOffPatternApplicationKey( |
|
|
PatternApplicationKey &key) const |
|
|
{ |
|
|
const int depth = Depth(); |
|
|
key.resize(depth); |
|
|
const PatternApplicationTrie *p = this; |
|
|
std::size_t i = depth-1; |
|
|
while (p->m_parent != 0) { |
|
|
key[i--] = p; |
|
|
p = p->m_parent; |
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|