|
|
#include "SymbolRangeCalculator.h" |
|
|
|
|
|
namespace Moses |
|
|
{ |
|
|
namespace Syntax |
|
|
{ |
|
|
namespace S2T |
|
|
{ |
|
|
|
|
|
void SymbolRangeCalculator::Calc(const PatternApplicationKey &key, |
|
|
int spanStart, int spanEnd, |
|
|
std::vector<SymbolRange> &ranges) |
|
|
{ |
|
|
FillInTerminalRanges(key, ranges); |
|
|
FillInAuxSymbolInfo(ranges); |
|
|
FillInGapRanges(key, spanStart, spanEnd, ranges); |
|
|
} |
|
|
|
|
|
|
|
|
void SymbolRangeCalculator::FillInTerminalRanges( |
|
|
const PatternApplicationKey &key, std::vector<SymbolRange> &ranges) |
|
|
{ |
|
|
ranges.resize(key.size()); |
|
|
for (std::size_t i = 0; i < key.size(); ++i) { |
|
|
const PatternApplicationTrie *patNode = key[i]; |
|
|
if (patNode->IsTerminalNode()) { |
|
|
ranges[i].minStart = ranges[i].maxStart = patNode->m_start; |
|
|
ranges[i].minEnd = ranges[i].maxEnd = patNode->m_end; |
|
|
} else { |
|
|
ranges[i].minStart = ranges[i].maxStart = -1; |
|
|
ranges[i].minEnd = ranges[i].maxEnd = -1; |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
void SymbolRangeCalculator::FillInAuxSymbolInfo( |
|
|
const std::vector<SymbolRange> &ranges) |
|
|
{ |
|
|
m_auxSymbolInfo.resize(ranges.size()); |
|
|
|
|
|
|
|
|
int distanceToPrevTerminal = -1; |
|
|
for (std::size_t i = 0; i < ranges.size(); ++i) { |
|
|
const SymbolRange &range = ranges[i]; |
|
|
AuxSymbolInfo &auxInfo = m_auxSymbolInfo[i]; |
|
|
if (range.minStart != -1) { |
|
|
|
|
|
assert(range.maxStart == range.minStart); |
|
|
distanceToPrevTerminal = 1; |
|
|
|
|
|
auxInfo.distanceToPrevTerminal = -1; |
|
|
} else if (distanceToPrevTerminal == -1) { |
|
|
|
|
|
auxInfo.distanceToPrevTerminal = -1; |
|
|
} else { |
|
|
|
|
|
auxInfo.distanceToPrevTerminal = distanceToPrevTerminal++; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
int distanceToNextTerminal = -1; |
|
|
for (std::size_t j = ranges.size(); j > 0; --j) { |
|
|
std::size_t i = j-1; |
|
|
const SymbolRange &range = ranges[i]; |
|
|
AuxSymbolInfo &auxInfo = m_auxSymbolInfo[i]; |
|
|
if (range.minStart != -1) { |
|
|
|
|
|
assert(range.maxStart == range.minStart); |
|
|
distanceToNextTerminal = 1; |
|
|
|
|
|
auxInfo.distanceToNextTerminal = -1; |
|
|
} else if (distanceToNextTerminal == -1) { |
|
|
|
|
|
auxInfo.distanceToNextTerminal = -1; |
|
|
} else { |
|
|
|
|
|
auxInfo.distanceToNextTerminal = distanceToNextTerminal++; |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
void SymbolRangeCalculator::FillInGapRanges(const PatternApplicationKey &key, |
|
|
int spanStart, int spanEnd, |
|
|
std::vector<SymbolRange> &ranges) |
|
|
{ |
|
|
for (std::size_t i = 0; i < key.size(); ++i) { |
|
|
const PatternApplicationTrie *patNode = key[i]; |
|
|
|
|
|
if (patNode->IsTerminalNode()) { |
|
|
continue; |
|
|
} |
|
|
|
|
|
SymbolRange &range = ranges[i]; |
|
|
AuxSymbolInfo &auxInfo = m_auxSymbolInfo[i]; |
|
|
|
|
|
|
|
|
if (auxInfo.distanceToPrevTerminal == -1) { |
|
|
|
|
|
range.minStart = spanStart + i; |
|
|
} else { |
|
|
|
|
|
int j = i - auxInfo.distanceToPrevTerminal; |
|
|
assert(ranges[j].minEnd == ranges[j].maxEnd); |
|
|
range.minStart = ranges[j].maxEnd + auxInfo.distanceToPrevTerminal; |
|
|
} |
|
|
|
|
|
|
|
|
if (i == 0) { |
|
|
|
|
|
range.maxStart = spanStart; |
|
|
} else if (auxInfo.distanceToPrevTerminal == 1) { |
|
|
|
|
|
range.maxStart = ranges[i-1].maxEnd + 1; |
|
|
} else if (auxInfo.distanceToNextTerminal == -1) { |
|
|
|
|
|
int numFollowingGaps = (ranges.size()-1) - i; |
|
|
range.maxStart = spanEnd - numFollowingGaps; |
|
|
} else { |
|
|
|
|
|
int j = i + auxInfo.distanceToNextTerminal; |
|
|
range.maxStart = ranges[j].minStart - auxInfo.distanceToNextTerminal; |
|
|
} |
|
|
|
|
|
|
|
|
if (i+1 == key.size()) { |
|
|
|
|
|
range.minEnd = spanEnd; |
|
|
} else if (auxInfo.distanceToNextTerminal == 1) { |
|
|
|
|
|
range.minEnd = ranges[i+1].minStart - 1; |
|
|
} else if (auxInfo.distanceToPrevTerminal == -1) { |
|
|
|
|
|
range.minEnd = spanStart + i; |
|
|
} else { |
|
|
|
|
|
int j = i - auxInfo.distanceToPrevTerminal; |
|
|
assert(ranges[j].minEnd == ranges[j].maxEnd); |
|
|
range.minEnd = ranges[j].maxEnd + auxInfo.distanceToPrevTerminal; |
|
|
} |
|
|
|
|
|
|
|
|
if (i+1 == key.size()) { |
|
|
|
|
|
range.maxEnd = spanEnd; |
|
|
} else if (auxInfo.distanceToNextTerminal == -1) { |
|
|
|
|
|
int numFollowingGaps = (ranges.size()-1) - i; |
|
|
range.maxEnd = spanEnd - numFollowingGaps; |
|
|
} else { |
|
|
|
|
|
int j = i + auxInfo.distanceToNextTerminal; |
|
|
range.maxEnd = ranges[j].minStart - auxInfo.distanceToNextTerminal; |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|