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 &)
{
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};
}
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) = "";
};
auto appliable = [colName, lineIndex](const Config & config, const Action &)
{
return config.has(colName, lineIndex, 0);
};
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 & current = config.getLastNotEmptyHyp(colName, lineIndex);
current = util::isEmpty(current) ? addition : current.get() + '|' + addition;
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
};
auto undo = [colName, lineIndex](Config & config, Action &)
{
std::string newValue = config.getLastNotEmpty(colName, lineIndex);
while (!newValue.empty() and newValue.back() == '|')
newValue.pop_back();
if (!newValue.empty())
newValue.pop_back();
config.getLastNotEmpty(colName, lineIndex) = newValue;
};
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(current.get(), '|');
for (auto & part : splited)
if (part == addition)
return false;
return true;
};
return {Type::Write, apply, undo, appliable};
}
Action Action::addToHypothesisRelative(const std::string & colName, Object object, int relativeIndex, const std::string & addition)
{
auto apply = [colName, object, relativeIndex, addition](Config & config, Action & a)
{
int lineIndex = 0;
if (object == Object::Buffer)
lineIndex = config.getWordIndex() + relativeIndex;
else
lineIndex = config.getStack(relativeIndex);
return addToHypothesis(colName, lineIndex, addition).apply(config, a);
};
auto undo = [colName, object, relativeIndex](Config & config, Action & a)
{
int lineIndex = 0;
if (object == Object::Buffer)
lineIndex = config.getWordIndex() + relativeIndex;
else
lineIndex = config.getStack(relativeIndex);
return addToHypothesis(colName, lineIndex, "").undo(config, a);
};
auto appliable = [colName, object, relativeIndex, addition](const Config & config, const Action & a)
{
int lineIndex = 0;
if (object == Object::Buffer)
lineIndex = config.getWordIndex() + relativeIndex;
else if (config.hasStack(relativeIndex))
lineIndex = config.getStack(relativeIndex);
else
return false;
return addToHypothesis(colName, lineIndex, addition).appliable(config, a);
};
return {Type::Write, apply, undo, appliable};
}
Action Action::addHypothesisRelative(const std::string & colName, Object object, int relativeIndex, const std::string & hypothesis)
{
auto apply = [colName, object, relativeIndex, hypothesis](Config & config, Action & a)
{
int lineIndex = 0;
if (object == Object::Buffer)
lineIndex = config.getWordIndex() + relativeIndex;
else
lineIndex = config.getStack(relativeIndex);
return addHypothesis(colName, lineIndex, hypothesis).apply(config, a);
};
auto undo = [colName, object, relativeIndex](Config & config, Action & a)
{
int lineIndex = 0;
if (object == Object::Buffer)
lineIndex = config.getWordIndex() + relativeIndex;
else
lineIndex = config.getStack(relativeIndex);
return addHypothesis(colName, lineIndex, "").undo(config, a);
};
auto appliable = [colName, object, relativeIndex](const Config & config, const Action & a)
{
int lineIndex = 0;
if (object == Object::Buffer)
lineIndex = config.getWordIndex() + relativeIndex;
else if (config.hasStack(relativeIndex))
lineIndex = config.getStack(relativeIndex);
else
return false;
return addHypothesis(colName, lineIndex, "").appliable(config, a);
};
return {Type::Write, apply, undo, appliable};
}
Action Action::pushWordIndexOnStack()
{
auto apply = [](Config & config, Action &)
{
config.addToStack(config.getWordIndex());
};
auto undo = [](Config & config, Action &)
{
config.popStack();
};
auto appliable = [](const Config & config, const Action &)
if (config.hasStack(0) and config.getStack(0) == config.getWordIndex())
return false;
return (int)config.getWordIndex() != config.getLastPoppedStack();
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
};
return {Type::Push, apply, undo, appliable};
}
Action Action::popStack()
{
auto apply = [](Config & config, Action & a)
{
auto toSave = config.getStack(0);
a.data.push_back(std::to_string(toSave));
config.popStack();
};
auto undo = [](Config & config, Action & a)
{
config.addToStack(std::stoi(a.data.back()));
};
auto appliable = [](const Config & config, const Action &)
{
return config.hasStack(0);
};
return {Type::Pop, apply, undo, appliable};
}
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
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 & config, const Action &)
{
return true;
};
return {Type::Pop, apply, undo, appliable};
}
Action Action::setRoot()
{
auto apply = [](Config & config, Action & a)
{
int rootIndex = -1;
for (int i = config.getStack(0); 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.isToken(i))
continue;
if (config.getLastNotEmptyHypConst(Config::EOSColName, i) == Config::EOSSymbol1)
break;
if (util::isEmpty(config.getLastNotEmptyHypConst(Config::headColName, i)))
{
rootIndex = i;
a.data.push_back(std::to_string(i));
}
}
for (int i = config.getStack(0); 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.isToken(i))
continue;
if (config.getLastNotEmptyHypConst(Config::EOSColName, i) == Config::EOSSymbol1)
break;
if (util::isEmpty(config.getLastNotEmptyHypConst(Config::headColName, i)))
{
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);
else
{
if (std::stoi(config.getLastNotEmptyHypConst(Config::headColName, i)) < firstSentenceIndex)
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 = [](const Config & config, const Action &)
{
return config.hasStack(0);
};
return {Type::Write, apply, undo, appliable};
}
Action Action::updateIds()
{
auto apply = [](Config & config, Action & a)
{
int firstIndexOfSentence = -1;
for (int i = config.getStack(0); 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.isComment(i) || config.isEmptyNode(i))
continue;
if (config.getLastNotEmptyHypConst(Config::EOSColName, i) == Config::EOSSymbol1)
break;
firstIndexOfSentence = i;
}
if (firstIndexOfSentence < 0)
util::myThrow("could not find any token in current sentence");
for (unsigned int i = firstIndexOfSentence, currentId = 1; i <= config.getStack(0); ++i)
if (config.isComment(i) || config.isEmptyNode(i))
continue;
if (config.getLastNotEmptyHypConst(Config::EOSColName, i) == Config::EOSSymbol1)
break;
if (config.isMultiword(i))
config.getFirstEmpty(Config::idColName, i) = fmt::format("{}-{}", currentId, currentId+config.getMultiwordSize(i));
else
config.getFirstEmpty(Config::idColName, i) = fmt::format("{}", currentId++);
}
};
auto undo = [](Config & config, Action & a)
{
// TODO : undo this
};
auto appliable = [](const Config &, const Action &)
{
return true;
};
return {Type::Write, apply, undo, appliable};
}
Action Action::attach(Object governorObject, int governorIndex, Object dependentObject, int dependentIndex)
{
auto apply = [governorObject, governorIndex, dependentObject, dependentIndex](Config & config, Action & a)
{
int lineIndex = 0;
if (governorObject == Object::Buffer)
lineIndex = config.getWordIndex() + governorIndex;
else
lineIndex = config.getStack(governorIndex);
addHypothesisRelative(Config::headColName, dependentObject, dependentIndex, std::to_string(lineIndex)).apply(config, a);
};
auto undo = [governorObject, governorIndex, dependentObject, dependentIndex](Config & config, Action & a)
{
addHypothesisRelative(Config::headColName, dependentObject, dependentIndex, "").undo(config, a);
};
auto appliable = [governorObject, governorIndex, dependentObject, dependentIndex](const Config & config, const Action & action)
{
int govLineIndex = 0;
if (governorObject == Object::Buffer)
{
govLineIndex = config.getWordIndex() + governorIndex;
if (!config.has(0, govLineIndex, 0))
return false;
}
else
{
if (!config.hasStack(governorIndex))
return false;
govLineIndex = config.getStack(governorIndex);
}
int depLineIndex = 0;
if (dependentObject == Object::Buffer)
{
depLineIndex = config.getWordIndex() + dependentIndex;
if (!config.has(0, depLineIndex, 0))
return false;
}
else
{
if (!config.hasStack(dependentIndex))
return false;
depLineIndex = config.getStack(dependentIndex);
}
// Check for cycles
while (govLineIndex != depLineIndex)
{
try
{
govLineIndex = std::stoi(config.getLastNotEmptyHypConst(Config::headColName, govLineIndex));
} catch(std::exception &) {return true;}
}
return false;
};
return {Type::Write, apply, undo, appliable};
}
Action::Object Action::str2object(const std::string & s)
{
if (s == "b")
return Object::Buffer;
if (s == "s")
return Object::Stack;
util::myThrow(fmt::format("Invalid object '{}'", s));
return Object::Buffer;
}