Newer
Older
Action::Action(Action::Type type, std::function<void(Config & config, Action & action)> apply, std::function<void(Config & config, Action & action)> undo, std::function<bool(const Config & config, const Action & action)> appliable)
{
this->type = type;
this->apply = apply;
this->undo = undo;
this->appliable = appliable;
}
Action Action::addLinesIfNeeded(int nbLines)
{
auto apply = [nbLines](Config & config, Action &)
{
while (!config.has(0, config.getWordIndex()+nbLines, 0))
config.addLines(1);
};
auto undo = [](Config &, Action &)
{
};
auto appliable = [](const Config &, const Action &)
{
return true;
};
return {Type::AddLines, apply, undo, appliable};
}
Action Action::moveWordIndex(int movement)
{
auto apply = [movement](Config & config, Action &)
{
config.moveWordIndex(movement);
};
auto undo = [movement](Config & config, Action &)
{
auto appliable = [movement](const Config & config, const Action &)
return config.canMoveWordIndex(movement);
};
return {Type::MoveWord, apply, undo, appliable};
}
Franck Dary
committed
Action Action::setMultiwordIds(int multiwordSize)
{
auto apply = [multiwordSize](Config & config, Action & a)
{
addHypothesisRelative(Config::idColName, Config::Object::Buffer, 0, fmt::format("{}-{}", config.getCurrentWordId()+1, config.getCurrentWordId()+multiwordSize)).apply(config, a);
Franck Dary
committed
for (int i = 0; i < multiwordSize; i++)
addHypothesisRelative(Config::idColName, Config::Object::Buffer, i+1, fmt::format("{}", config.getCurrentWordId()+1+i)).apply(config, a);
addHypothesisRelative(Config::isMultiColName, Config::Object::Buffer, i+1, Config::EOSSymbol1).apply(config, a);
Franck Dary
committed
auto undo = [multiwordSize](Config & config, Action &)
{
config.getLastNotEmpty(Config::idColName, config.getWordIndex()) = "";
Franck Dary
committed
for (int i = 0; i < multiwordSize; i++)
config.getLastNotEmpty(Config::idColName, config.getWordIndex()+1+i) = "";
};
auto appliable = [](const Config &, const Action &)
{
return true;
};
return {Type::Write, apply, undo, appliable};
}
Action Action::consumeCharacterIndex(const util::utf8string & consumed)
{
auto apply = [consumed](Config & config, Action &)
{
Franck Dary
committed
config.moveCharacterIndex(consumed.size());
};
auto undo = [consumed](Config & config, Action &)
{
config.moveCharacterIndex(-consumed.size());
};
auto appliable = [consumed](const Config & config, const Action &)
{
if (!config.canMoveCharacterIndex(consumed.size()))
return false;
for (unsigned int i = 0; i < consumed.size(); i++)
{
if (!config.hasCharacter(config.getCharacterIndex()+i))
return false;
const util::utf8char & letter = config.getLetter(config.getCharacterIndex()+i);
const util::utf8char & consumedLetter = consumed[i];
if (util::lower(letter) != util::lower(consumedLetter))
return true;
};
return {Type::MoveWord, apply, undo, appliable};
}
Action Action::moveCharacterIndex(int movement)
{
auto apply = [movement](Config & config, Action &)
{
config.moveCharacterIndex(movement);
};
auto undo = [movement](Config & config, Action &)
{
auto appliable = [movement](const Config & config, const Action &)
return config.canMoveCharacterIndex(movement);
};
return {Type::MoveChar, apply, undo, appliable};
}
Action Action::addHypothesis(const std::string & colName, std::size_t lineIndex, const std::string & hypothesis)
{
auto apply = [colName, lineIndex, hypothesis](Config & config, Action &)
{
config.getFirstEmpty(colName, lineIndex) = hypothesis;
};
auto undo = [colName, lineIndex](Config & config, Action &)
{
config.getLastNotEmpty(colName, lineIndex) = "";
};
Franck Dary
committed
auto appliable = [](const Config &, const Action &)
Franck Dary
committed
return true;
};
return {Type::Write, apply, undo, appliable};
}
Action Action::addToHypothesis(const std::string & colName, std::size_t lineIndex, const std::string & addition)
{
auto apply = [colName, lineIndex, addition](Config & config, Action &)
{
auto currentElems = util::split(std::string(config.getLastNotEmptyHypConst(colName, lineIndex)), '|');
currentElems.emplace_back(addition);
std::sort(currentElems.begin(), currentElems.end());
config.getLastNotEmptyHyp(colName, lineIndex) = util::join("|", currentElems);
auto undo = [colName, lineIndex, addition](Config & config, Action &)
auto curElems = util::split(std::string(config.getLastNotEmptyHypConst(colName, lineIndex)), '|');
std::vector<std::string> newElems;
for (auto & elem : curElems)
if (elem != addition)
newElems.emplace_back(elem);
config.getLastNotEmptyHyp(colName, lineIndex) = util::join("|", newElems);
};
auto appliable = [colName, lineIndex, addition](const Config & config, const Action &)
{
if (!config.has(colName, lineIndex, 0))
return false;
auto & current = config.getLastNotEmptyHypConst(colName, lineIndex);
auto splited = util::split(std::string(current), '|');
for (auto & part : splited)
if (part == addition)
return false;
return true;
};
return {Type::Write, apply, undo, appliable};
}
Action Action::sumToHypothesis(const std::string & colName, std::size_t lineIndex, float addition, bool mean)
auto apply = [colName, lineIndex, addition, mean](Config & config, Action &)
std::string totalStr = std::string(config.getLastNotEmptyHypConst(colName, lineIndex));
totalStr = fmt::format("{}={}|{}", std::string(config.getState()), 0.0, 0);
auto byStates = util::split(totalStr, ',');
int index = -1;
for (unsigned int i = 0; i < byStates.size(); i++)
{
auto state = util::split(byStates[i], '=')[0];
if (state == config.getState())
{
index = i;
break;
}
}
if (index == -1)
{
byStates.emplace_back(fmt::format("{}={}|{}", std::string(config.getState()), 0.0, 0));
index = byStates.size()-1;
}
auto splited = util::split(util::split(byStates[index], '=')[1], '|');
float curVal = 0.0;
int curNb = 0;
if (splited.size() == 2)
{
curVal = std::stof(splited[0]);
curNb = std::stoi(splited[1]);
}
curNb += 1;
if (mean)
{
// Knuth’s algorithm for online mean
float delta = addition - curVal;
curVal += delta / curNb;
}
else
{
curVal += addition;
}
byStates[index] = fmt::format("{}={}|{}", std::string(config.getState()), curVal, curNb);
config.getLastNotEmptyHyp(colName, lineIndex) = util::join(",", byStates);
auto undo = [colName, lineIndex, addition, mean](Config & config, Action &)
std::string totalStr = std::string(config.getLastNotEmptyHypConst(colName, lineIndex));
totalStr = fmt::format("{}={}|{}", std::string(config.getState()), 0.0, 0);
auto byStates = util::split(totalStr, ',');
int index = -1;
for (unsigned int i = 0; i < byStates.size(); i++)
{
auto state = util::split(byStates[i], '=')[0];
if (state == config.getState())
{
index = i;
break;
}
}
if (index == -1)
{
byStates.emplace_back(fmt::format("{}={}|{}", std::string(config.getState()), 0.0, 0));
auto splited = util::split(util::split(byStates[index], '=')[1], '|');
float curVal = 0.0;
int curNb = 0;
if (splited.size() == 2)
{
curVal = std::stof(splited[0]);
curNb = std::stoi(splited[1]);
}
curNb -= 1;
// Knuth’s algorithm for online mean
if (mean)
curVal = (curNb*curVal - addition) / (curNb - 1);
else
curVal -= addition;
byStates[index] = fmt::format("{}={}|{}", std::string(config.getState()), curVal, curNb);
config.getLastNotEmptyHyp(colName, lineIndex) = util::join(",", byStates);
};
auto appliable = [colName, lineIndex, addition](const Config & config, const Action &)
{
return config.has(colName, lineIndex, 0);
};
return {Type::Write, apply, undo, appliable};
}
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
Action Action::maxWithHypothesis(const std::string & colName, std::size_t lineIndex, float addition)
{
auto apply = [colName, lineIndex, addition](Config & config, Action &)
{
std::string totalStr = std::string(config.getLastNotEmptyHypConst(colName, lineIndex));
if (totalStr.empty() || totalStr == "_")
totalStr = fmt::format("{}={}|{}", std::string(config.getState()), 0.0, 0);
auto byStates = util::split(totalStr, ',');
int index = -1;
for (unsigned int i = 0; i < byStates.size(); i++)
{
auto state = util::split(byStates[i], '=')[0];
if (state == config.getState())
{
index = i;
break;
}
}
if (index == -1)
{
byStates.emplace_back(fmt::format("{}={}|{}", std::string(config.getState()), 0.0, 0));
index = byStates.size()-1;
}
auto splited = util::split(util::split(byStates[index], '=')[1], '|');
float curVal = 0.0;
int curNb = 0;
if (splited.size() == 2)
{
curVal = std::stof(splited[0]);
curNb = std::stoi(splited[1]);
}
curNb += 1;
curVal = addition;
byStates[index] = fmt::format("{}={}|{}", std::string(config.getState()), curVal, curNb);
config.getLastNotEmptyHyp(colName, lineIndex) = util::join(",", byStates);
};
auto undo = [](Config &, Action &)
{
//TODO: not done
};
auto appliable = [colName, lineIndex, addition](const Config & config, const Action &)
{
return config.has(colName, lineIndex, 0);
};
return {Type::Write, apply, undo, appliable};
}
Action Action::addToHypothesisRelative(const std::string & colName, Config::Object object, int relativeIndex, const std::string & addition)
{
auto apply = [colName, object, relativeIndex, addition](Config & config, Action & a)
{
int lineIndex = config.getRelativeWordIndex(object, relativeIndex);
return addToHypothesis(colName, lineIndex, addition).apply(config, a);
};
auto undo = [colName, object, relativeIndex](Config & config, Action & a)
{
int lineIndex = config.getRelativeWordIndex(object, relativeIndex);
return addToHypothesis(colName, lineIndex, "").undo(config, a);
};
auto appliable = [colName, object, relativeIndex, addition](const Config & config, const Action & a)
{
int lineIndex = config.getRelativeWordIndex(object, relativeIndex);
return addToHypothesis(colName, lineIndex, addition).appliable(config, a);
};
return {Type::Write, apply, undo, appliable};
}
Action Action::addHypothesisRelative(const std::string & colName, Config::Object object, int relativeIndex, const std::string & hypothesis)
{
auto apply = [colName, object, relativeIndex, hypothesis](Config & config, Action & a)
{
int lineIndex = config.getRelativeWordIndex(object, relativeIndex);
return addHypothesis(colName, lineIndex, hypothesis).apply(config, a);
};
auto undo = [colName, object, relativeIndex](Config & config, Action & a)
{
int lineIndex = config.getRelativeWordIndex(object, relativeIndex);
return addHypothesis(colName, lineIndex, "").undo(config, a);
};
auto appliable = [colName, object, relativeIndex](const Config & config, const Action & a)
int lineIndex = config.getRelativeWordIndex(object, relativeIndex);
return addHypothesis(colName, lineIndex, "").appliable(config, a);
};
return {Type::Write, apply, undo, appliable};
}
Action Action::addHypothesisRelativeRelaxed(const std::string & colName, Config::Object object, int relativeIndex, const std::string & hypothesis)
{
auto apply = [colName, object, relativeIndex, hypothesis](Config & config, Action & a)
{
int lineIndex = config.getRelativeWordIndex(object, relativeIndex);
return addHypothesis(colName, lineIndex, hypothesis).apply(config, a);
};
auto undo = [colName, object, relativeIndex](Config & config, Action & a)
{
int lineIndex = config.getRelativeWordIndex(object, relativeIndex);
return addHypothesis(colName, lineIndex, "").undo(config, a);
};
auto appliable = [](const Config &, const Action &)
{
return true;
};
return {Type::Write, apply, undo, appliable};
}
Action Action::pushWordIndexOnStack()
{
if (config.isTokenPredicted(config.getWordIndex()))
{
a.data.emplace_back();
config.addToStack(config.getWordIndex());
}
if (!a.data.empty())
{
config.popStack();
a.data.pop_back();
}
auto appliable = [](const Config & config, const Action &)
if (config.hasStack(0) and config.getStack(0) == config.getWordIndex())
return false;
if (config.hasStack(0) and !config.isTokenPredicted(config.getStack(0)))
return false;
return (int)config.getWordIndex() != config.getLastPoppedStack();
};
return {Type::Push, apply, undo, appliable};
}
auto apply = [relIndex](Config & config, Action & a)
a.data.push_back(std::to_string(toSave));
for (int i = 0; relIndex-1-i >= 0; i++)
config.swapStack(relIndex-i, relIndex-1-i);
auto undo = [relIndex](Config & config, Action & a)
{
config.addToStack(std::stoi(a.data.back()));
for (int i = 0; i+1 <= relIndex; i++)
config.swapStack(i, i+1);
auto appliable = [relIndex](const Config & config, const Action &)
return config.hasStack(relIndex) and config.getStack(relIndex) != config.getWordIndex();
};
return {Type::Pop, apply, undo, appliable};
}
Action Action::endWord()
{
auto apply = [](Config & config, Action & a)
{
config.setCurrentWordId(config.getCurrentWordId()+1);
addHypothesisRelative(Config::idColName, Config::Object::Buffer, 0, std::to_string(config.getCurrentWordId())).apply(config, a);
if (!config.rawInputOnlySeparatorsLeft() and !config.has(0,config.getWordIndex()+1,0))
config.addLines(1);
};
auto undo = [](Config & config, Action &)
{
config.setCurrentWordId(config.getCurrentWordId()-1);
config.getLastNotEmpty(Config::idColName, config.getWordIndex()) = "";
};
auto appliable = [](const Config & config, const Action &)
{
if (std::string(config.getAsFeature("FORM", config.getWordIndex())).empty())
if (!std::string(config.getAsFeature(Config::idColName, config.getWordIndex())).empty() and config.getAsFeature(Config::isMultiColName, config.getWordIndex()) != Config::EOSSymbol1)
};
return {Type::Write, apply, undo, appliable};
}
Action Action::emptyStack()
{
auto apply = [](Config & config, Action & a)
{
while (config.hasStack(0))
{
a.data.push_back(std::to_string(config.getStack(0)));
config.popStack();
}
};
auto undo = [](Config & config, Action & a)
{
while (a.data.size())
{
config.addToStack(std::stoi(a.data.back()));
a.data.pop_back();
}
};
auto appliable = [](const Config &, const Action &)
{
return true;
};
return {Type::Pop, apply, undo, appliable};
}
Action Action::ignoreCurrentCharacter()
{
auto apply = [](Config & config, Action &)
{
config.moveCharacterIndex(1);
};
{
config.moveCharacterIndex(-1);
};
auto appliable = [](const Config & config, const Action &)
{
return config.hasCharacter(config.getCharacterIndex()) and util::isSeparator(config.getLetter(config.getCharacterIndex())) and config.canMoveCharacterIndex(1);
};
return {Type::MoveChar, apply, undo, appliable};
}
Action Action::assertIsEmpty(const std::string & colName, Config::Object object, int relativeIndex)
Franck Dary
committed
{
auto apply = [](Config &, Action &)
{
};
auto undo = [](Config &, Action &)
{
};
auto appliable = [colName, object, relativeIndex](const Config & config, const Action &)
Franck Dary
committed
{
try
{
if (!config.hasRelativeWordIndex(object, relativeIndex))
return false;
auto lineIndex = config.getRelativeWordIndex(object, relativeIndex);
return std::string(config.getAsFeature(colName, lineIndex)).empty();
} catch (std::exception & e)
{
util::myThrow(fmt::format("colName='{}' object='{}' relativeIndex='{}' {}", colName, object == Config::Object::Stack ? "Stack" : "Buffer", relativeIndex, e.what()));
}
return false;
};
return {Type::Check, apply, undo, appliable};
}
Action Action::assertIsNotEmpty(const std::string & colName, Config::Object object, int relativeIndex)
{
auto apply = [](Config &, Action &)
{
};
auto undo = [](Config &, Action &)
{
};
auto appliable = [colName, object, relativeIndex](const Config & config, const Action &)
{
try
{
if (!config.hasRelativeWordIndex(object, relativeIndex))
return false;
auto lineIndex = config.getRelativeWordIndex(object, relativeIndex);
return !std::string(config.getAsFeature(colName, lineIndex)).empty();
} catch (std::exception & e)
{
util::myThrow(fmt::format("colName='{}' object='{}' relativeIndex='{}' {}", colName, object == Config::Object::Stack ? "Stack" : "Buffer", relativeIndex, e.what()));
}
return false;
Franck Dary
committed
};
return {Type::Check, apply, undo, appliable};
}
Action Action::addCharsToCol(const std::string & col, int n, Config::Object object, int relativeIndex)
auto apply = [col, n, object, relativeIndex](Config & config, Action &)
auto index = config.getRelativeWordIndex(object, relativeIndex);
auto & curWord = config.getLastNotEmptyHyp(col, index);
if (col == "FORM")
{
if (std::string(config.getAsFeature(Config::rawRangeStartColName, index)).empty())
config.getLastNotEmptyHyp(Config::rawRangeStartColName, index) = fmt::format("{}", config.getCharacterIndex());
config.getLastNotEmptyHyp(Config::rawRangeEndColName, index) = fmt::format("{}", config.getCharacterIndex());
int curEndValue = std::stoi(config.getAsFeature(Config::rawRangeEndColName, index));
config.getLastNotEmptyHyp(Config::rawRangeEndColName, index) = fmt::format("{}", curEndValue+n);
}
for (int i = 0; i < n; i++)
curWord = fmt::format("{}{}", std::string(curWord), config.getLetter(config.getCharacterIndex()+i));
auto undo = [col, n, object, relativeIndex](Config & config, Action &)
auto index = config.getRelativeWordIndex(object, relativeIndex);
auto & curWord = config.getLastNotEmptyHyp(col, index);
auto newWord = util::splitAsUtf8(std::string(curWord));
for (int i = 0; i < n; i++)
curWord = fmt::format("{}", newWord);
if (newWord.size() == 0)
config.getLastNotEmptyHyp(Config::rawRangeStartColName, index) = "0";
int curEndValue = std::stoi(config.getAsFeature(Config::rawRangeEndColName, index));
config.getLastNotEmptyHyp(Config::rawRangeEndColName, index) = fmt::format("{}", curEndValue-n);
auto appliable = [col, n, object, relativeIndex](const Config & config, const Action &)
if (!config.hasCharacter(config.getCharacterIndex()+n-1))
auto firstLetter = config.getLetter(config.getCharacterIndex());
if (firstLetter == ' ' and std::string(config.getAsFeature(col, config.getRelativeWordIndex(object, relativeIndex))).empty())
for (int i = 0; i < n; i++)
if (util::isIllegal(config.getLetter(config.getCharacterIndex()+i)))
return false;
return true;
};
return {Type::Write, apply, undo, appliable};
}
int lineIndex = config.getRelativeWordIndex(Config::Object::Buffer, bufferIndex);
int searchStartIndex = lineIndex;
if (searchStartIndex > 0 and config.getAsFeature(Config::idColName, lineIndex) != "1")
searchStartIndex--;
int firstSentIndex = lineIndex;
for (int i = searchStartIndex; true; --i)
{
if (!config.has(0, i, 0))
{
if (i < 0)
break;
util::myThrow("The current sentence is too long to be completly held by the data strucure. Consider increasing SubConfig::SpanSize");
}
if (config.getAsFeature(Config::EOSColName, i) == Config::EOSSymbol1)
firstSentIndex = i;
}
for (int i = lineIndex; i >= firstSentIndex; --i)
{
if (!config.isTokenPredicted(i))
continue;
if (std::string(config.getAsFeature(Config::headColName, i)).empty())
{
rootIndex = i;
a.data.push_back(std::to_string(i));
}
}
for (int i = lineIndex; i >= firstSentIndex; --i)
if (std::string(config.getAsFeature(Config::headColName, i)).empty())
config.getFirstEmpty(Config::headColName, i) = "-1";
config.getFirstEmpty(Config::deprelColName, i) = "root";
}
else
{
config.getFirstEmpty(Config::headColName, i) = std::to_string(rootIndex);
}
}
}
};
auto undo = [](Config & config, Action & a)
{
while (a.data.size())
{
config.getLastNotEmptyHyp(Config::headColName, std::stoi(a.data.back())) = "";
a.data.pop_back();
}
};
auto appliable = [bufferIndex](const Config & config, const Action &)
int lineIndex = config.getRelativeWordIndex(Config::Object::Buffer, bufferIndex);
return config.has(0,lineIndex,0) and config.isTokenPredicted(lineIndex) and config.getAsFeature(Config::isMultiColName, lineIndex) != Config::EOSSymbol1;
};
return {Type::Write, apply, undo, appliable};
}
auto apply = [bufferIndex](Config & config, Action &)
int lineIndex = config.getRelativeWordIndex(Config::Object::Buffer, bufferIndex);
int lastSentId = -1;
for (int i = lineIndex; true; --i)
{
if (!config.has(0, i, 0))
{
if (i < 0)
break;
util::myThrow("The current sentence is too long to be completly held by the data strucure. Consider increasing SubConfig::SpanSize");
}
if (config.isEmptyNode(i))
continue;
if (config.getLastNotEmptyHypConst(Config::EOSColName, i) == Config::EOSSymbol1)
{
lastSentId = std::stoi(config.getAsFeature(Config::sentIdColName, i));
firstIndexOfSentence = i;
}
if (firstIndexOfSentence < 0)
util::myThrow("could not find any token in current sentence");
for (int i = firstIndexOfSentence, currentId = 1; i <= lineIndex; ++i)
if (config.isEmptyNode(i))
if (config.isMultiwordPredicted(i))
config.getFirstEmpty(Config::idColName, i) = fmt::format("{}-{}", currentId, currentId+config.getMultiwordSizePredicted(i));
else
config.getFirstEmpty(Config::idColName, i) = fmt::format("{}", currentId++);
config.getFirstEmpty(Config::sentIdColName, i) = fmt::format("{}", lastSentId+1);
// Update metadata '# text = ...' and '# sent_id = X' before the sentence
if (config.hasCharacter(0))
if (config.has(0,firstIndexOfSentence,0))
{
std::string textMetadata = "# text = ";
int firstIndex = 0;
int lastIndex = 0;
try {firstIndex = std::stoi(config.getAsFeature(Config::rawRangeStartColName, firstIndexOfSentence));}
catch (std::exception & e) {util::myThrow(fmt::format("{} : '{}'", e.what(), std::string(config.getAsFeature(Config::rawRangeStartColName, firstIndexOfSentence))));}
try {lastIndex = std::stoi(config.getAsFeature(Config::rawRangeEndColName, lineIndex));}
catch (std::exception & e) {util::myThrow(fmt::format("{} : '{}'", e.what(), std::string(config.getAsFeature(Config::rawRangeEndColName, lineIndex))));}
for (auto i = firstIndex; i < lastIndex; i++)
textMetadata = fmt::format("{}{}", textMetadata, config.getLetter(i));
config.getLastNotEmptyHyp(Config::commentsColName, firstIndexOfSentence) = fmt::format("{}\n# sent_id = {}", textMetadata, std::string(config.getAsFeature(Config::sentIdColName, firstIndexOfSentence)));
{
// TODO : undo this
};
auto appliable = [](const Config &, const Action &)
{
return true;
};
return {Type::Write, apply, undo, appliable};
}
Action Action::attach(Config::Object governorObject, int governorIndex, Config::Object dependentObject, int dependentIndex)
{
auto apply = [governorObject, governorIndex, dependentObject, dependentIndex](Config & config, Action & a)
{
long govIndex = config.getRelativeWordIndex(governorObject, governorIndex);
long depIndex = config.getRelativeWordIndex(dependentObject, dependentIndex);
addHypothesisRelative(Config::headColName, dependentObject, dependentIndex, std::to_string(govIndex)).apply(config, a);
addToHypothesisRelative(Config::childsColName, governorObject, governorIndex, std::to_string(depIndex)).apply(config, a);
a.data.emplace_back(std::to_string(config.getLastAttached()));
config.setLastAttached(depIndex);
};
auto undo = [governorObject, governorIndex, dependentObject, dependentIndex](Config & config, Action & a)
{
addHypothesisRelative(Config::headColName, dependentObject, dependentIndex, "").undo(config, a);
addToHypothesisRelative(Config::childsColName, governorObject, governorIndex, "").apply(config, a);
config.setLastAttached(std::stoi(a.data.back()));
a.data.pop_back();
auto appliable = [governorObject, governorIndex, dependentObject, dependentIndex](const Config & config, const Action &)
if (!config.hasRelativeWordIndex(governorObject, governorIndex) or !config.hasRelativeWordIndex(dependentObject, dependentIndex))
return false;
long govLineIndex = config.getRelativeWordIndex(governorObject, governorIndex);
long depLineIndex = config.getRelativeWordIndex(dependentObject, dependentIndex);
if (!config.isTokenPredicted(govLineIndex) or !config.isTokenPredicted(depLineIndex))
return false;
// Check if dep and head belongs to the same sentence
if (config.getAsFeature(Config::sentIdColName, govLineIndex) != config.getAsFeature(Config::sentIdColName, depLineIndex))
return false;
// Check if dep is not already attached
if (!std::string(config.getAsFeature(Config::headColName, depLineIndex)).empty())
Franck Dary
committed
return true;
};
return {Type::Write, apply, undo, appliable};
}
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
Action Action::split(int index)
{
auto apply = [index](Config & config, Action &)
{
Transition * t = config.getAppliableSplitTransitions()[index];
t->apply(config);
};
auto undo = [](Config &, Action &)
{
//TODO : undo this
};
auto appliable = [index](const Config & config, const Action &)
{
auto & transitions = config.getAppliableSplitTransitions();
if (index < 0 or index >= (int)transitions.size())
return false;
Transition * t = transitions[index];
return t->appliable(config);
};
return {Type::Write, apply, undo, appliable};
}
Action Action::setRootUpdateIdsEmptyStackIfSentChanged()
{
auto apply = [](Config & config, Action &)
int rootIndex = lineIndex;
int lastSentId = -1;
int firstIndexOfSentence = lineIndex;
if (config.getAsFeature(Config::EOSColName, lineIndex) != Config::EOSSymbol1)
return;
for (int i = lineIndex-1; true; --i)
{
if (!config.has(0, i, 0))
{
if (i < 0)
break;
util::myThrow("The current sentence is too long to be completly held by the data strucure. Consider increasing SubConfig::SpanSize");
}
if (!config.isTokenPredicted(i))
continue;
if (config.getAsFeature(Config::EOSColName, i) == Config::EOSSymbol1)
{
lastSentId = std::stoi(config.getAsFeature(Config::sentIdColName, i));
break;
}
if (std::string(config.getAsFeature(Config::headColName, i)).empty())
rootIndex = i;
firstIndexOfSentence = i;
}
for (int i = firstIndexOfSentence; i <= lineIndex; ++i)
{
if (!config.has(0, i, 0))
{
if (i < 0)
break;
util::myThrow("The current sentence is too long to be completly held by the data strucure. Consider increasing SubConfig::SpanSize");
}
if (!config.isTokenPredicted(i))
continue;
if (std::string(config.getAsFeature(Config::headColName, i)).empty())
{
if (i == rootIndex)
{
config.getFirstEmpty(Config::headColName, i) = "0";
config.getFirstEmpty(Config::deprelColName, i) = "root";
}
else
{
config.getFirstEmpty(Config::headColName, i) = std::to_string(rootIndex);
}
}
}
for (int i = firstIndexOfSentence, currentId = 1; i <= lineIndex; ++i)
{
if (config.isEmptyNode(i))
continue;
if (config.isMultiwordPredicted(i))
config.getFirstEmpty(Config::idColName, i) = fmt::format("{}-{}", currentId, currentId+config.getMultiwordSizePredicted(i));
else
config.getFirstEmpty(Config::idColName, i) = fmt::format("{}", currentId++);
config.getFirstEmpty(Config::sentIdColName, i) = fmt::format("{}", lastSentId+1);
}
while (config.hasStack(0))
config.popStack();
};