00001 #include "SymbolRangeCalculator.h"
00002
00003 namespace Moses
00004 {
00005 namespace Syntax
00006 {
00007 namespace S2T
00008 {
00009
00010 void SymbolRangeCalculator::Calc(const PatternApplicationKey &key,
00011 int spanStart, int spanEnd,
00012 std::vector<SymbolRange> &ranges)
00013 {
00014 FillInTerminalRanges(key, ranges);
00015 FillInAuxSymbolInfo(ranges);
00016 FillInGapRanges(key, spanStart, spanEnd, ranges);
00017 }
00018
00019
00020 void SymbolRangeCalculator::FillInTerminalRanges(
00021 const PatternApplicationKey &key, std::vector<SymbolRange> &ranges)
00022 {
00023 ranges.resize(key.size());
00024 for (std::size_t i = 0; i < key.size(); ++i) {
00025 const PatternApplicationTrie *patNode = key[i];
00026 if (patNode->IsTerminalNode()) {
00027 ranges[i].minStart = ranges[i].maxStart = patNode->m_start;
00028 ranges[i].minEnd = ranges[i].maxEnd = patNode->m_end;
00029 } else {
00030 ranges[i].minStart = ranges[i].maxStart = -1;
00031 ranges[i].minEnd = ranges[i].maxEnd = -1;
00032 }
00033 }
00034 }
00035
00036 void SymbolRangeCalculator::FillInAuxSymbolInfo(
00037 const std::vector<SymbolRange> &ranges)
00038 {
00039 m_auxSymbolInfo.resize(ranges.size());
00040
00041
00042 int distanceToPrevTerminal = -1;
00043 for (std::size_t i = 0; i < ranges.size(); ++i) {
00044 const SymbolRange &range = ranges[i];
00045 AuxSymbolInfo &auxInfo = m_auxSymbolInfo[i];
00046 if (range.minStart != -1) {
00047
00048 assert(range.maxStart == range.minStart);
00049 distanceToPrevTerminal = 1;
00050
00051 auxInfo.distanceToPrevTerminal = -1;
00052 } else if (distanceToPrevTerminal == -1) {
00053
00054 auxInfo.distanceToPrevTerminal = -1;
00055 } else {
00056
00057 auxInfo.distanceToPrevTerminal = distanceToPrevTerminal++;
00058 }
00059 }
00060
00061
00062 int distanceToNextTerminal = -1;
00063 for (std::size_t j = ranges.size(); j > 0; --j) {
00064 std::size_t i = j-1;
00065 const SymbolRange &range = ranges[i];
00066 AuxSymbolInfo &auxInfo = m_auxSymbolInfo[i];
00067 if (range.minStart != -1) {
00068
00069 assert(range.maxStart == range.minStart);
00070 distanceToNextTerminal = 1;
00071
00072 auxInfo.distanceToNextTerminal = -1;
00073 } else if (distanceToNextTerminal == -1) {
00074
00075 auxInfo.distanceToNextTerminal = -1;
00076 } else {
00077
00078 auxInfo.distanceToNextTerminal = distanceToNextTerminal++;
00079 }
00080 }
00081 }
00082
00083 void SymbolRangeCalculator::FillInGapRanges(const PatternApplicationKey &key,
00084 int spanStart, int spanEnd,
00085 std::vector<SymbolRange> &ranges)
00086 {
00087 for (std::size_t i = 0; i < key.size(); ++i) {
00088 const PatternApplicationTrie *patNode = key[i];
00089
00090 if (patNode->IsTerminalNode()) {
00091 continue;
00092 }
00093
00094 SymbolRange &range = ranges[i];
00095 AuxSymbolInfo &auxInfo = m_auxSymbolInfo[i];
00096
00097
00098 if (auxInfo.distanceToPrevTerminal == -1) {
00099
00100 range.minStart = spanStart + i;
00101 } else {
00102
00103 int j = i - auxInfo.distanceToPrevTerminal;
00104 assert(ranges[j].minEnd == ranges[j].maxEnd);
00105 range.minStart = ranges[j].maxEnd + auxInfo.distanceToPrevTerminal;
00106 }
00107
00108
00109 if (i == 0) {
00110
00111 range.maxStart = spanStart;
00112 } else if (auxInfo.distanceToPrevTerminal == 1) {
00113
00114 range.maxStart = ranges[i-1].maxEnd + 1;
00115 } else if (auxInfo.distanceToNextTerminal == -1) {
00116
00117 int numFollowingGaps = (ranges.size()-1) - i;
00118 range.maxStart = spanEnd - numFollowingGaps;
00119 } else {
00120
00121 int j = i + auxInfo.distanceToNextTerminal;
00122 range.maxStart = ranges[j].minStart - auxInfo.distanceToNextTerminal;
00123 }
00124
00125
00126 if (i+1 == key.size()) {
00127
00128 range.minEnd = spanEnd;
00129 } else if (auxInfo.distanceToNextTerminal == 1) {
00130
00131 range.minEnd = ranges[i+1].minStart - 1;
00132 } else if (auxInfo.distanceToPrevTerminal == -1) {
00133
00134 range.minEnd = spanStart + i;
00135 } else {
00136
00137 int j = i - auxInfo.distanceToPrevTerminal;
00138 assert(ranges[j].minEnd == ranges[j].maxEnd);
00139 range.minEnd = ranges[j].maxEnd + auxInfo.distanceToPrevTerminal;
00140 }
00141
00142
00143 if (i+1 == key.size()) {
00144
00145 range.maxEnd = spanEnd;
00146 } else if (auxInfo.distanceToNextTerminal == -1) {
00147
00148 int numFollowingGaps = (ranges.size()-1) - i;
00149 range.maxEnd = spanEnd - numFollowingGaps;
00150 } else {
00151
00152 int j = i + auxInfo.distanceToNextTerminal;
00153 range.maxEnd = ranges[j].minStart - auxInfo.distanceToNextTerminal;
00154 }
00155 }
00156 }
00157
00158 }
00159 }
00160 }