|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#pragma once |
|
|
|
#include "IntermediateVarSpanNode.h" |
|
#include "moses/Range.h" |
|
|
|
#include <boost/array.hpp> |
|
|
|
#include <map> |
|
|
|
#include <vector> |
|
|
|
namespace Moses |
|
{ |
|
|
|
|
|
|
|
struct VarSpanNode { |
|
public: |
|
struct NonTermRange { |
|
size_t s1; |
|
size_t s2; |
|
size_t e1; |
|
size_t e2; |
|
}; |
|
typedef std::vector<IntermediateVarSpanNode> NodeVec; |
|
typedef boost::array<int, 5> KeyType; |
|
typedef std::map<KeyType, VarSpanNode> MapType; |
|
|
|
VarSpanNode() : m_parent(0), m_label(0), m_rank(0) {} |
|
|
|
VarSpanNode &Insert(const NodeVec &vec) { |
|
if (vec.empty()) { |
|
return *this; |
|
} |
|
return Insert(vec.begin(), vec.end()); |
|
} |
|
|
|
|
|
|
|
void CalculateRanges(int start, int end, |
|
std::vector<NonTermRange> &ranges) const { |
|
ranges.resize(m_rank); |
|
const VarSpanNode *n = this; |
|
size_t firstIndex = m_rank; |
|
while (n->m_parent) { |
|
const KeyType &key = *(n->m_label); |
|
assert(key[0] == 0 || key[0] == key[1]); |
|
assert(key[3] == -1 || key[2] == key[3]); |
|
const int numSplitPoints = key[4]; |
|
firstIndex -= numSplitPoints+1; |
|
const int vsn_start = key[0] == 0 ? start : key[0]; |
|
const int vsn_end = key[3] == -1 ? end : key[3]; |
|
|
|
ranges[firstIndex].s1 = ranges[firstIndex].s2 = vsn_start - start; |
|
|
|
|
|
if (numSplitPoints) { |
|
ranges[firstIndex].e1 = vsn_start - start; |
|
ranges[firstIndex].e2 = vsn_end - start - numSplitPoints; |
|
} else { |
|
ranges[firstIndex].e1 = ranges[firstIndex].e2 = vsn_end - start; |
|
} |
|
|
|
|
|
for (int i = 1; i <= numSplitPoints; ++i) { |
|
ranges[firstIndex+i].s1 = ranges[firstIndex].s1+i; |
|
ranges[firstIndex+i].s2 = ranges[firstIndex].e2+i; |
|
ranges[firstIndex+i].e1 = ranges[firstIndex].s1+i; |
|
ranges[firstIndex+i].e2 = ranges[firstIndex].e2+i; |
|
} |
|
|
|
ranges[firstIndex+numSplitPoints].e1 = vsn_end - start; |
|
ranges[firstIndex+numSplitPoints].e2 = vsn_end - start; |
|
n = n->m_parent; |
|
} |
|
assert(firstIndex == 0); |
|
} |
|
|
|
const VarSpanNode *m_parent; |
|
const KeyType *m_label; |
|
size_t m_rank; |
|
MapType m_children; |
|
|
|
private: |
|
VarSpanNode &Insert(NodeVec::const_iterator first, |
|
NodeVec::const_iterator last) { |
|
assert(first != last); |
|
|
|
KeyType key; |
|
key[0] = first->m_start.first; |
|
key[1] = first->m_start.second; |
|
key[2] = first->m_end.first; |
|
key[3] = first->m_end.second; |
|
key[4] = first->m_numSplitPoints; |
|
|
|
std::pair<MapType::iterator, bool> result = m_children.insert( |
|
std::make_pair(key, VarSpanNode())); |
|
VarSpanNode &child = result.first->second; |
|
if (result.second) { |
|
child.m_parent = this; |
|
child.m_label = &(result.first->first); |
|
child.m_rank = m_rank + first->m_numSplitPoints + 1; |
|
} |
|
if (++first == last) { |
|
return child; |
|
} |
|
return child.Insert(first, last); |
|
} |
|
}; |
|
|
|
} |
|
|