diff --git a/trainer/src/TrainInfos.cpp b/trainer/src/TrainInfos.cpp index ab7e10618ff568c28431a75f056224bed7f6af6b..ed52f748b4a432981261dd3dab05d3c9f36059df 100644 --- a/trainer/src/TrainInfos.cpp +++ b/trainer/src/TrainInfos.cpp @@ -212,6 +212,8 @@ void TrainInfos::computeTrainScores(Config & c) { if (it.first == "Parser") addTrainScore(it.first, (scoresFloat["UAS"] + scoresFloat["LAS"] + scoresFloat["Sentences"]) / 3); + else if (it.first == "Segmenter") + addTrainScore(it.first, scoresFloat["Sentences"]); else if (it.first == "Tokenizer") addTrainScore(it.first, scoresFloat["Tokens"]); else if (it.first == "Tagger") @@ -268,6 +270,8 @@ void TrainInfos::computeDevScores(Config & c) { if (it.first == "Parser") addDevScore(it.first, (scoresFloat["UAS"] + scoresFloat["LAS"] + scoresFloat["Sentences"]) / 3); + else if (it.first == "Segmenter") + addDevScore(it.first, scoresFloat["Sentences"]); else if (it.first == "Tokenizer") addDevScore(it.first, scoresFloat["Tokens"]); else if (it.first == "Tagger") diff --git a/transition_machine/include/ActionBank.hpp b/transition_machine/include/ActionBank.hpp index 695068cb19811094c0b42260cdc0c964f69a7aba..a42c8ad2103c4dd0f11f04e4aba0cfe5559741f7 100644 --- a/transition_machine/include/ActionBank.hpp +++ b/transition_machine/include/ActionBank.hpp @@ -60,10 +60,11 @@ class ActionBank /// @param config The Config simpleBufferWrite would be called with. /// @param tapeName The name of the tape simpleBufferWrite would be called with. /// @param relativeIndex The relative index simpleBufferWrite would be called with. + /// @param checkEmptyness If true, check if cell that will be written to is empty. /// /// @return Whether or not a call to simpleBufferWrite is possible. static bool simpleBufferWriteAppliable(Config & config, - const std::string & tapeName, int relativeIndex); + const std::string & tapeName, int relativeIndex, bool checkEmptyness); /// @brief Whether or not the transform rule is appliable. /// @@ -97,9 +98,10 @@ class ActionBank /// \param tapeName The tape we will write to /// \param value The value we will write /// \param relativeIndex The write index relative to the buffer's head + /// \param checkEmptyness If true, check if the cell that will be written to is empty /// /// \return A BasicAction doing all of that - static Action::BasicAction bufferWrite(std::string tapeName, std::string value, int relativeIndex); + static Action::BasicAction bufferWrite(std::string tapeName, std::string value, int relativeIndex, bool checkEmptyness); /// \brief Append a string to a cell in the buffer /// @@ -176,9 +178,10 @@ class ActionBank /// \param tapeName The tape we will write to /// \param value The value we will write /// \param stackIndex The stack index of the buffer index + /// \param checkEmptyness If true, check if the cell it will write to is empty /// /// \return A BasicAction doing all of that - static Action::BasicAction stackWrite(std::string tapeName, std::string value, int stackIndex); + static Action::BasicAction stackWrite(std::string tapeName, std::string value, int stackIndex, bool checkEmptyness); /// \brief Push the head of the buffer into the stack /// diff --git a/transition_machine/src/ActionBank.cpp b/transition_machine/src/ActionBank.cpp index 7dedf72aa5c146cb5333b8c1852d2cdcf8b2a511..f4a9e42d02a3129651735dab2b5aa1a3641e8d22 100644 --- a/transition_machine/src/ActionBank.cpp +++ b/transition_machine/src/ActionBank.cpp @@ -130,7 +130,7 @@ Action::BasicAction ActionBank::rawInputBeginsWith(std::string word) return basicAction; } -Action::BasicAction ActionBank::bufferWrite(std::string tapeName, std::string value, int relativeIndex) +Action::BasicAction ActionBank::bufferWrite(std::string tapeName, std::string value, int relativeIndex, bool checkEmptyness) { auto apply = [tapeName, value, relativeIndex](Config & c, Action::BasicAction &) { @@ -140,9 +140,9 @@ Action::BasicAction ActionBank::bufferWrite(std::string tapeName, std::string va { simpleBufferWrite(c, tapeName, "", relativeIndex); }; - auto appliable = [tapeName, relativeIndex](Config & c, Action::BasicAction &) + auto appliable = [tapeName, relativeIndex, checkEmptyness](Config & c, Action::BasicAction &) { - return simpleBufferWriteAppliable(c, tapeName, relativeIndex); + return simpleBufferWriteAppliable(c, tapeName, relativeIndex, checkEmptyness); }; Action::BasicAction basicAction = {Action::BasicAction::Type::Write, value, apply, undo, appliable}; @@ -150,7 +150,7 @@ Action::BasicAction ActionBank::bufferWrite(std::string tapeName, std::string va return basicAction; } -Action::BasicAction ActionBank::stackWrite(std::string tapeName, std::string value, int stackIndex) +Action::BasicAction ActionBank::stackWrite(std::string tapeName, std::string value, int stackIndex, bool checkEmptyness) { auto apply = [tapeName, value, stackIndex](Config & c, Action::BasicAction &) { @@ -164,13 +164,13 @@ Action::BasicAction ActionBank::stackWrite(std::string tapeName, std::string val int relativeIndex = bufferIndex - c.getHead(); simpleBufferWrite(c, tapeName, "", relativeIndex); }; - auto appliable = [tapeName, stackIndex](Config & c, Action::BasicAction &) + auto appliable = [tapeName, stackIndex, checkEmptyness](Config & c, Action::BasicAction &) { if (!c.stackHasIndex(stackIndex)) return false; int bufferIndex = c.stackGetElem(stackIndex); int relativeIndex = bufferIndex - c.getHead(); - return simpleBufferWriteAppliable(c, tapeName, relativeIndex); + return simpleBufferWriteAppliable(c, tapeName, relativeIndex, checkEmptyness); }; Action::BasicAction basicAction = @@ -441,9 +441,51 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na int relativeIndex = std::stoi(object[1]); if (object[0] == "b") - sequence.emplace_back(bufferWrite(tapeName, value, relativeIndex)); + sequence.emplace_back(bufferWrite(tapeName, value, relativeIndex, true)); else if (object[0] == "s") - sequence.emplace_back(stackWrite(tapeName, value, relativeIndex)); + sequence.emplace_back(stackWrite(tapeName, value, relativeIndex, true)); + } + else if(std::string(b1) == "REWRITE") + { + if (sscanf(name.c_str(), "%s %s %s %s", b1, b4, b2, b3) != 4) + invalidNameAndAbort(ERRINFO); + + std::string tapeName(b2); + std::string value(b3); + auto object = util::split(b4, '.'); + + if (object.size() != 2) + invalidNameAndAbort(ERRINFO); + + int relativeIndex = std::stoi(object[1]); + + if (object[0] == "b") + sequence.emplace_back(bufferWrite(tapeName, value, relativeIndex, false)); + else if (object[0] == "s") + sequence.emplace_back(stackWrite(tapeName, value, relativeIndex, false)); + } + else if (std::string(b1) == "SEGMENT") + { + sequence.emplace_back(bufferWrite(ProgramParameters::sequenceDelimiterTape, ProgramParameters::sequenceDelimiter, 0, false)); + // Update the IDs of the words in the new sentence + { + auto apply = [](Config & c, Action::BasicAction &) + { + c.setEosTouched(); + c.updateIdsInSequence(); + }; + auto undo = [](Config &, Action::BasicAction &) + { + }; + auto appliable = [](Config &, Action::BasicAction &) + { + return true; + }; + Action::BasicAction basicAction = + {Action::BasicAction::Type::Write, "", apply, undo, appliable}; + + sequence.emplace_back(basicAction); + } } else if(std::string(b1) == "TOLOWER" || std::string(b1) == "TOUPPER") { @@ -508,7 +550,7 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na auto splits = util::split(name); for(int i = startRelIndex; i <= endRelIndex; i++) - sequence.emplace_back(bufferWrite(tapeName, splits[4+i-startRelIndex], i)); + sequence.emplace_back(bufferWrite(tapeName, splits[4+i-startRelIndex], i, true)); } else if(std::string(b1) == "RULE") { @@ -563,7 +605,7 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na auto undo = [](Config & c, Action::BasicAction &) {simpleBufferWrite(c, "ID", std::string(""), 0);}; auto appliable = [](Config & c, Action::BasicAction &) - {return simpleBufferWriteAppliable(c, "ID", 0);}; + {return simpleBufferWriteAppliable(c, "ID", 0, true);}; Action::BasicAction basicAction = {Action::BasicAction::Type::Write, "", apply, undo, appliable}; @@ -601,7 +643,7 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na for (unsigned int i = 0; i < splited.size(); i++) { - sequence.emplace_back(bufferWrite("FORM", splited[i], i)); + sequence.emplace_back(bufferWrite("FORM", splited[i], i, true)); int splitedSize = (int)splited.size(); auto apply = [i, splitedSize](Config & c, Action::BasicAction &) @@ -609,7 +651,7 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na auto undo = [i](Config & c, Action::BasicAction &) {simpleBufferWrite(c, "ID", std::string(""), i);}; auto appliable = [i](Config & c, Action::BasicAction &) - {return simpleBufferWriteAppliable(c, "ID", i);}; + {return simpleBufferWriteAppliable(c, "ID", i, true);}; Action::BasicAction basicAction = {Action::BasicAction::Type::Write, "", apply, undo, appliable}; @@ -704,7 +746,7 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na return false; } - return simpleBufferWriteAppliable(c, "GOV", s0-b0); + return simpleBufferWriteAppliable(c, "GOV", s0-b0, true); }; Action::BasicAction basicAction = {Action::BasicAction::Type::Write, "", apply, undo, appliable}; @@ -731,7 +773,7 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na return false; int b0 = c.getHead(); int s0 = c.stackTop(); - return simpleBufferWriteAppliable(c, "LABEL", s0-b0); + return simpleBufferWriteAppliable(c, "LABEL", s0-b0, true); }; Action::BasicAction basicAction2 = {Action::BasicAction::Type::Write, b2, apply2, undo2, appliable2}; @@ -786,7 +828,7 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na return false; } - return simpleBufferWriteAppliable(c, "GOV", 0); + return simpleBufferWriteAppliable(c, "GOV", 0, true); }; Action::BasicAction basicAction = {Action::BasicAction::Type::Write, "", apply, undo, appliable}; @@ -805,7 +847,7 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na }; auto appliable2 = [](Config & c, Action::BasicAction &) { - return simpleBufferWriteAppliable(c, "LABEL", 0); + return simpleBufferWriteAppliable(c, "LABEL", 0, true); }; Action::BasicAction basicAction2 = {Action::BasicAction::Type::Write, b2, apply2, undo2, appliable2}; @@ -817,35 +859,50 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na } else if(std::string(b1) == "EOS") { + if (sscanf(name.c_str(), "%s %s", b1, b4) != 2) + invalidNameAndAbort(ERRINFO); + + auto object = util::split(b4, '.'); + + if (object.size() != 2) + invalidNameAndAbort(ERRINFO); + + int relativeIndex = std::stoi(object[1]); + // Puting the EOS tag on the last element of the sentence. + if (object[0] == "s") { - auto apply = [](Config & c, Action::BasicAction &) + auto apply = [relativeIndex](Config & c, Action::BasicAction &) { int b0 = c.getHead(); - int s0 = c.stackTop(); - simpleBufferWrite(c, ProgramParameters::sequenceDelimiterTape, ProgramParameters::sequenceDelimiter, s0-b0); - c.setEosTouched(); + int s = c.stackGetElem(relativeIndex); + simpleBufferWrite(c, ProgramParameters::sequenceDelimiterTape, ProgramParameters::sequenceDelimiter, s-b0); }; - auto undo = [](Config & c, Action::BasicAction) + auto undo = [relativeIndex](Config & c, Action::BasicAction) { int b0 = c.getHead(); - int s0 = c.stackTop(); - simpleBufferWrite(c, ProgramParameters::sequenceDelimiterTape, "", s0-b0); + int s = c.stackGetElem(relativeIndex); + simpleBufferWrite(c, ProgramParameters::sequenceDelimiterTape, "", s-b0); }; - auto appliable = [](Config & c, Action::BasicAction &) + auto appliable = [relativeIndex](Config & c, Action::BasicAction &) { - return !c.isFinal() && !c.stackEmpty() && c.getTape(ProgramParameters::sequenceDelimiterTape).getHyp(c.stackTop()-c.getHead()) != ProgramParameters::sequenceDelimiter; + return !c.isFinal() && !c.stackEmpty() && c.getTape(ProgramParameters::sequenceDelimiterTape).getHyp(c.stackGetElem(relativeIndex)-c.getHead()) != ProgramParameters::sequenceDelimiter; }; Action::BasicAction basicAction = {Action::BasicAction::Type::Write, "", apply, undo, appliable}; sequence.emplace_back(basicAction); } + else if (object[0] == "b") + { + sequence.emplace_back(bufferWrite(ProgramParameters::sequenceDelimiterTape, ProgramParameters::sequenceDelimiter, relativeIndex, false)); + } // Update the IDs of the words in the new sentence { auto apply = [](Config & c, Action::BasicAction &) { + c.setEosTouched(); c.updateIdsInSequence(); }; auto undo = [](Config &, Action::BasicAction &) @@ -864,115 +921,121 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na // Chosing root of the sentence and attaching floating words to it. { auto apply = [](Config & c, Action::BasicAction & ba) + { + if (!c.hasTape("GOV")) + return; + + ba.data = ""; + auto & govs = c.getTape("GOV"); + auto & ids = c.getTape("ID"); + int b0 = c.getHead(); + int rootIndex = -1; + for (int i = c.stackSize()-1; i >= 0; i--) { - ba.data = ""; - auto & govs = c.getTape("GOV"); - auto & ids = c.getTape("ID"); - int b0 = c.getHead(); - int rootIndex = -1; - for (int i = c.stackSize()-1; i >= 0; i--) + auto s = c.stackGetElem(i); + if (c.rawInputHeadIndex > 0) { - auto s = c.stackGetElem(i); - if (c.rawInputHeadIndex > 0) - { - if (util::split(ids.getHyp(s-b0), '-').size() > 1) - continue; - if (util::split(ids.getHyp(s-b0), '.').size() > 1) - continue; - } - else - { - if (util::split(ids.getRef(s-b0), '-').size() > 1) - continue; - if (util::split(ids.getRef(s-b0), '.').size() > 1) - continue; - } - - if (govs.getHyp(s-b0).empty() || govs.getHyp(s-b0) == "0") - { - if (rootIndex == -1) - rootIndex = s; - else - { - simpleBufferWrite(c, "GOV", std::to_string(rootIndex-s), s-b0); - simpleBufferWrite(c, "LABEL", "_", s-b0); - ba.data += "+"+std::to_string(s-b0); - } - } + if (util::split(ids.getHyp(s-b0), '-').size() > 1) + continue; + if (util::split(ids.getHyp(s-b0), '.').size() > 1) + continue; + } + else + { + if (util::split(ids.getRef(s-b0), '-').size() > 1) + continue; + if (util::split(ids.getRef(s-b0), '.').size() > 1) + continue; } - if (rootIndex == -1) + if (govs.getHyp(s-b0).empty() || govs.getHyp(s-b0) == "0") { - if (c.stackEmpty()) + if (rootIndex == -1) + rootIndex = s; + else { - c.printForDebug(stderr); - fprintf(stderr, "ERROR (%s) : no suitable candidate for root. Aborting.\n", ERRINFO); - exit(1); + simpleBufferWrite(c, "GOV", std::to_string(rootIndex-s), s-b0); + simpleBufferWrite(c, "LABEL", "_", s-b0); + ba.data += "+"+std::to_string(s-b0); } + } + } - rootIndex = c.stackGetElem(c.stackSize()-1); + if (rootIndex == -1) + { + if (c.stackEmpty()) + { + c.printForDebug(stderr); + fprintf(stderr, "ERROR (%s) : no suitable candidate for root. Aborting.\n", ERRINFO); + exit(1); } - simpleBufferWrite(c, "GOV", "0", rootIndex-b0); - simpleBufferWrite(c, "LABEL", "root", rootIndex-b0); + rootIndex = c.stackGetElem(c.stackSize()-1); + } + + simpleBufferWrite(c, "GOV", "0", rootIndex-b0); + simpleBufferWrite(c, "LABEL", "root", rootIndex-b0); + + // Attaching floating words to new root + int sentenceEnd = b0; + auto & eos = c.getTape(ProgramParameters::sequenceDelimiterTape); + while (sentenceEnd >= 0 && eos.getHyp(sentenceEnd-b0) != ProgramParameters::sequenceDelimiter) + sentenceEnd--; + int sentenceStart = std::max(0,sentenceEnd-1); + while (sentenceStart >= 0 && eos.getHyp(sentenceStart-b0) != ProgramParameters::sequenceDelimiter) + sentenceStart--; + sentenceStart++; - // Attaching floating words to new root - int sentenceEnd = b0; - auto & eos = c.getTape(ProgramParameters::sequenceDelimiterTape); - while (sentenceEnd >= 0 && eos.getHyp(sentenceEnd-b0) != ProgramParameters::sequenceDelimiter) - sentenceEnd--; - int sentenceStart = std::max(0,sentenceEnd-1); - while (sentenceStart >= 0 && eos.getHyp(sentenceStart-b0) != ProgramParameters::sequenceDelimiter) - sentenceStart--; - sentenceStart++; + if (sentenceEnd < 0) + { + sentenceStart = 0; + sentenceEnd = eos.hypSize()-1; + } - if (sentenceEnd < 0) + for (int i = sentenceStart; i <= sentenceEnd; i++) + { + if (c.rawInputHeadIndex > 0) { - sentenceStart = 0; - sentenceEnd = eos.hypSize()-1; + if (util::split(ids.getHyp(i-b0), '-').size() > 1) + continue; + if (util::split(ids.getHyp(i-b0), '.').size() > 1) + continue; } - - for (int i = sentenceStart; i <= sentenceEnd; i++) + else { - if (c.rawInputHeadIndex > 0) - { - if (util::split(ids.getHyp(i-b0), '-').size() > 1) - continue; - if (util::split(ids.getHyp(i-b0), '.').size() > 1) - continue; - } - else - { - if (util::split(ids.getRef(i-b0), '-').size() > 1) - continue; - if (util::split(ids.getRef(i-b0), '.').size() > 1) - continue; - } + if (util::split(ids.getRef(i-b0), '-').size() > 1) + continue; + if (util::split(ids.getRef(i-b0), '.').size() > 1) + continue; + } - if (govs.getHyp(i-b0).empty()) - { - simpleBufferWrite(c, "GOV", std::to_string(rootIndex-i), i-b0); - simpleBufferWrite(c, "LABEL", "_", i-b0); - ba.data += "+"+std::to_string(i-b0); - } + if (govs.getHyp(i-b0).empty()) + { + simpleBufferWrite(c, "GOV", std::to_string(rootIndex-i), i-b0); + simpleBufferWrite(c, "LABEL", "_", i-b0); + ba.data += "+"+std::to_string(i-b0); } + } - // Delete the arcs from the previous sentence to the new sentence - for (int i = b0; i > c.stackTop(); i--) + // Delete the arcs from the previous sentence to the new sentence + for (int i = b0; i > c.stackTop(); i--) + { + try { - try + if (std::stoi(govs[i-b0])+i <= c.stackTop()) { - if (std::stoi(govs[i-b0])+i <= c.stackTop()) - { - simpleBufferWrite(c, "GOV", "", i-b0); - simpleBufferWrite(c, "LABEL", "", i-b0); - } + simpleBufferWrite(c, "GOV", "", i-b0); + simpleBufferWrite(c, "LABEL", "", i-b0); } - catch (std::exception &) {continue;} } - }; + catch (std::exception &) {continue;} + } + }; auto undo = [](Config & c, Action::BasicAction & ba) { + if (!c.hasTape("GOV")) + return; + auto & govs = c.getTape("GOV"); int b0 = c.getHead(); for (int i = c.stackSize()-1; i >= 0; i--) @@ -996,6 +1059,9 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na }; auto appliable = [](Config & c, Action::BasicAction &) { + if (!c.hasTape("GOV")) + return true; + return !c.stackEmpty(); }; Action::BasicAction basicAction = @@ -1020,6 +1086,9 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na }; auto undo = [](Config & c, Action::BasicAction & ba) { + if (ba.data.empty()) + return; + auto elems = util::split(ba.data); for (auto elem : elems) if (!elem.empty()) @@ -1028,6 +1097,9 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na }; auto appliable = [](Config & c, Action::BasicAction &) { + if (!c.hasTape("GOV")) + return true; + return !c.isFinal() && !c.stackEmpty(); }; Action::BasicAction basicAction = @@ -1166,19 +1238,22 @@ void ActionBank::simpleBufferWrite(Config & config, const std::string & tapeName } bool ActionBank::simpleBufferWriteAppliable(Config & config, - const std::string & tapeName, int relativeIndex) + const std::string & tapeName, int relativeIndex, bool checkEmptyness) { auto & tape = config.getTape(tapeName); int index = config.getHead() + relativeIndex; + if (!checkEmptyness) + return !(index < 0) && index < tape.size(); + return !(index < 0) && index < tape.size() && tape.getHyp(relativeIndex).empty(); } bool ActionBank::isRuleAppliable(Config & config, const std::string & fromTapeName, const std::string & targetTapeName, int relativeIndex, const std::string & rule) { - if (!simpleBufferWriteAppliable(config, targetTapeName, relativeIndex)) + if (!simpleBufferWriteAppliable(config, targetTapeName, relativeIndex, true)) return false; return util::ruleIsAppliable(config.getTape(fromTapeName)[relativeIndex], rule); diff --git a/transition_machine/src/Config.cpp b/transition_machine/src/Config.cpp index 7b5a79145af8e0ef84a27c0520f4719a656af5ac..38492f13d5882e884bf8b3c9f64693778f88a05c 100644 --- a/transition_machine/src/Config.cpp +++ b/transition_machine/src/Config.cpp @@ -944,6 +944,9 @@ void Config::updateIdsInSequence() while (sentenceEnd >= 0 && eos.getHyp(sentenceEnd-getHead()) != ProgramParameters::sequenceDelimiter) sentenceEnd--; + if (endOfTapes()) + sentenceEnd = getHead(); + while (sentenceEnd >= ids.size()) sentenceEnd--; diff --git a/transition_machine/src/Oracle.cpp b/transition_machine/src/Oracle.cpp index 7d1b27f060321d174e7b29dc393fca7ec11a7fc3..288faa0975ba1e31a084c1670d57c4413391cb05 100644 --- a/transition_machine/src/Oracle.cpp +++ b/transition_machine/src/Oracle.cpp @@ -189,6 +189,25 @@ void Oracle::createDatabase() return 0; }))); + str2oracle.emplace("segmenter", std::unique_ptr<Oracle>(new Oracle( + [](Oracle *) + { + }, + [](Config &, Oracle *) + { + fprintf(stderr, "ERROR (%s) : getAction called on Oracle of trainable Classifier. Aborting.\n", ERRINFO); + exit(1); + + return std::string(""); + }, + [](Config & c, Oracle *, const std::string & action) + { + if (c.getTape(ProgramParameters::sequenceDelimiterTape).getRef(0) == ProgramParameters::sequenceDelimiter) + return action == "EOS b.0" ? 0 : 1; + + return action != "EOS b.0" ? 0 : 1; + }))); + str2oracle.emplace("tagger", std::unique_ptr<Oracle>(new Oracle( [](Oracle *) { @@ -359,6 +378,22 @@ void Oracle::createDatabase() return 0; }))); + str2oracle.emplace("strategy_segmenter", std::unique_ptr<Oracle>(new Oracle( + [](Oracle *) + { + }, + [](Config & c, Oracle *) + { + if (c.pastActions.size() == 0) + return std::string("MOVE segmenter 0"); + + return std::string("MOVE segmenter 1"); + }, + [](Config &, Oracle *, const std::string &) + { + return 0; + }))); + str2oracle.emplace("strategy_tagger", std::unique_ptr<Oracle>(new Oracle( [](Oracle *) { @@ -977,7 +1012,7 @@ void Oracle::createDatabase() int stackHead = c.stackEmpty() ? 0 : c.stackTop(); if (head >= eos.size()) - return action == "EOS" ? 0 : 1; + return action == "EOS s.0" ? 0 : 1; if (ids.getRef(0).empty()) {