diff --git a/transition_machine/src/Oracle.cpp b/transition_machine/src/Oracle.cpp
index 9d02cffab24cb072714ce69f8e179f8a358ba119..1283b7c2871678966aebddd1860a04e6cb4b06ff 100644
--- a/transition_machine/src/Oracle.cpp
+++ b/transition_machine/src/Oracle.cpp
@@ -581,6 +581,116 @@ void Oracle::createDatabase()
     return 0;
   })));
 
+  str2oracle.emplace("strategy_tagger,morpho,lemmatizer,parser_sequential", std::unique_ptr<Oracle>(new Oracle(
+  [](Oracle *)
+  {
+  },
+  [](Config & c, Oracle *)
+  {
+    if (c.pastActions.size() == 0)
+      return std::string("MOVE tagger 0");
+
+    std::string previousState = util::noAccentLower(c.pastActions.getElem(0).first);
+    std::string previousAction = util::noAccentLower(c.pastActions.getElem(0).second.name);
+    std::string newState;
+    int movement = 0;
+
+    static constexpr int lookahead = 2;
+    static std::map<std::string,int> done{{"tagger",0},{"morpho",0},{"lemmatizer_case",0},{"parser",0}};
+    static std::map<std::string,int> lastIndexDone{{"tagger",-1},{"morpho",-1},{"lemmatizer_case",-1},{"parser",-1}};
+    static std::map<std::string,int> todo{{"tagger",3*lookahead+1},{"morpho",2*lookahead+1},{"lemmatizer_case",lookahead+1}};
+
+    if (previousState == "tagger")
+    {
+      done[previousState]++;
+      lastIndexDone[previousState] = c.getHead();
+      if (done[previousState] != todo[previousState])
+      {
+        newState = "tagger";
+        movement = 1;
+      }
+      else
+      {
+        done[previousState] = 0;
+        newState = "morpho";
+        movement = lastIndexDone[newState]-c.getHead()+1;
+      }
+    }
+    else if (previousState == "morpho")
+    {
+      newState = "morpho";
+      if (previousAction == "nothing")
+      {
+        done[previousState]++;
+        lastIndexDone[previousState] = c.getHead();
+        if (done[previousState] != todo[previousState])
+        {
+          newState = "morpho";
+          movement = 1;
+        }
+        else
+        {
+          done[previousState] = 0;
+          newState = "lemmatizer_lookup";
+          movement = lastIndexDone["lemmatizer_case"]-c.getHead()+1;
+        }
+      }
+    }
+    else if (previousState == "lemmatizer_lookup")
+    {
+      if (previousAction == "notfound")
+        newState = "lemmatizer_rules";
+      else
+        newState = "lemmatizer_case";
+    }
+    else if (previousState == "lemmatizer_rules")
+      newState = "lemmatizer_case";
+    else if (previousState == "lemmatizer_case")
+    {
+      newState = "parser";
+      done[previousState]++;
+      lastIndexDone[previousState] = c.getHead();
+      if (done[previousState] != todo[previousState])
+      {
+        newState = "lemmatizer_rules";
+        movement = 1;
+      }
+      else
+      {
+        newState = "parser";
+        done[previousState] = 0;
+        movement = lastIndexDone[newState]-c.getHead()+1;
+      }
+    }
+    else if (previousState == "parser")
+    {
+      if (util::split(previousAction, ' ')[0] == "shift" || util::split(previousAction, ' ')[0] == "right")
+      {
+        newState = "tagger";
+        movement = lastIndexDone[newState]-c.getHead()+1;
+        lastIndexDone[previousState] = c.getHead();
+        if (c.endOfTapes())
+        {
+          newState = "parser";
+          movement = 1;
+        }
+        todo["tagger"] = 1;
+        todo["morpho"] = 1;
+        todo["lemmatizer_case"] = 1;
+      }
+      else
+        newState = "parser";
+    }
+    else
+      newState = "unknown("+std::string(ERRINFO)+")("+previousState+")("+previousAction+")";
+
+    return "MOVE " + newState + " " + std::to_string(movement);
+  },
+  [](Config &, Oracle *, const std::string &)
+  {
+    return 0;
+  })));
+
   str2oracle.emplace("strategy_tokenizer,tagger,morpho,lemmatizer,parser", std::unique_ptr<Oracle>(new Oracle(
   [](Oracle *)
   {