diff --git a/CMakeLists.txt b/CMakeLists.txt
index c9c940540f8216ced054cfb8bf755a6117a76603..36bd70f05a78d8ac61dc7c5f1035b697e4b3c6ef 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -21,7 +21,7 @@ endif()
 
 set(CMAKE_CXX_FLAGS "-Wall -Wextra -std=c++11")
 set(CMAKE_CXX_FLAGS_DEBUG "-g3 -Ofast")
-set(CMAKE_CXX_FLAGS_RELEASE "-Ofast -march=native")
+set(CMAKE_CXX_FLAGS_RELEASE "-Ofast")
 
 include_directories(maca_common/include)
 include_directories(transition_machine/include)
diff --git a/maca_common/include/LimitedStack.hpp b/maca_common/include/LimitedStack.hpp
index 7e45414cbf5ffdd6cc9d2310a57e414ef73be776..8521d3eb914bfc7c7d40c81cce447413eeb388dd 100644
--- a/maca_common/include/LimitedStack.hpp
+++ b/maca_common/include/LimitedStack.hpp
@@ -76,6 +76,22 @@ class LimitedStack
   {
     return nbElements == 0;
   }
+
+  bool contains(const T & element)
+  {
+    int currentIndex = lastElementIndex;
+    for (unsigned int i = 0; i < nbElements; i++)
+    {
+      if (data[currentIndex] == element)
+        return true;
+
+      currentIndex--;
+      if (currentIndex < 0)
+        currentIndex = data.size()-1;
+    }
+
+    return false;
+  }
 };
 
 #endif
diff --git a/transition_machine/include/Config.hpp b/transition_machine/include/Config.hpp
index 83f4831fe1d39b3f98d5b77f871df032a842a53d..015337b1d6ddf29398cafe355f310e9fc15d6fd0 100644
--- a/transition_machine/include/Config.hpp
+++ b/transition_machine/include/Config.hpp
@@ -67,6 +67,8 @@ class Config
   std::string inputFilename;
   /// @brief The sequence of Actions that made that Config.
   LimitedStack< std::pair<std::string, Action> > pastActions;
+  /// @brief An history of hashes, can be used to detect loops.
+  LimitedStack<std::size_t> hashHistory;
 
   public :
 
@@ -183,6 +185,18 @@ class Config
   ///
   /// @param entropy The entropy value.
   void addToEntropyHistory(float entropy);
+  // //////////////////////////////////////////////////////////////////////////
+  /// \brief Compute a hash of this Config.
+  ///
+  /// \return The computed hash.
+  // 
+  ////////////////////////////////////////////////////////////////////////////
+  std::size_t computeHash();
+  // //////////////////////////////////////////////////////////////////////////
+  /// \brief Compute and add current hash to the history of hash.
+  // 
+  ////////////////////////////////////////////////////////////////////////////
+  void addHashToHistory();
 };
 
 #endif
diff --git a/transition_machine/src/Action.cpp b/transition_machine/src/Action.cpp
index 6c5973f950c518a1818d931dabb6b5be89e6f633..9d64573765e294b65644f1dbd579619cdd333af5 100644
--- a/transition_machine/src/Action.cpp
+++ b/transition_machine/src/Action.cpp
@@ -4,6 +4,8 @@
 
 void Action::apply(Config & config)
 {
+  config.addHashToHistory();
+
   for(auto & basicAction : sequence)
     basicAction.apply(config, basicAction);
 
diff --git a/transition_machine/src/ActionBank.cpp b/transition_machine/src/ActionBank.cpp
index 0e2d98a0bd0b4e9c44596e7fefe2cc93753044c3..7946d1fa74ef33da9a9c7e0a2043036adc2b05c8 100644
--- a/transition_machine/src/ActionBank.cpp
+++ b/transition_machine/src/ActionBank.cpp
@@ -503,29 +503,39 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na
 
       auto apply = [dist](Config & c, Action::BasicAction &)
         {
-          static auto undoOneTime = [](Config & c)
+          std::string classifierName = c.pastActions.top().first;
+          if (ProgramParameters::debug)
+            fprintf(stderr, "classifierName = <%s>\n", classifierName.c_str());
+
+          static auto undoOneTime = [classifierName](Config & c)
           {
+            if (ProgramParameters::debug)
+              fprintf(stderr, "classifierName = <%s>\n", classifierName.c_str());
+
             while (true)
             {
               auto a = c.pastActions.pop();
               if (ProgramParameters::debug)
-                fprintf(stderr, "Undoing... <%s>\n", a.second.name.c_str());
+                fprintf(stderr, "Undoing... <%s><%s>\n", a.first.c_str(), a.second.name.c_str());
               a.second.undoOnlyStack(c);
 
-              if (a.first == "tagger")
+              if (a.first == classifierName)
                 return;
             }
           };
 
-          static auto undoForReal = [](Config & c)
+          static auto undoForReal = [classifierName](Config & c)
           {
+            if (ProgramParameters::debug)
+              fprintf(stderr, "classifierName = <%s>\n", classifierName.c_str());
+
             while (true)
             {
               auto a = c.pastActions.pop();
               if (ProgramParameters::debug)
-                fprintf(stderr, "Undoing... <%s>\n", a.second.name.c_str());
+                fprintf(stderr, "Undoing... <%s><%s>\n", a.first.c_str(), a.second.name.c_str());
 
-              if (a.first == "tagger")
+              if (a.first == classifierName)
               {
                 a.second.undo(c);
                 return;
diff --git a/transition_machine/src/Config.cpp b/transition_machine/src/Config.cpp
index 25477a74041ab5e9847f92d5c39aee5f2055d85a..c75a000c31539ec27a84d71a147d2649bfcd8f5d 100644
--- a/transition_machine/src/Config.cpp
+++ b/transition_machine/src/Config.cpp
@@ -4,7 +4,7 @@
 #include "ProgramParameters.hpp"
 #include "Action.hpp"
 
-Config::Config(BD & bd) : bd(bd), tapes(bd.getNbLines()), pastActions(100)
+Config::Config(BD & bd) : bd(bd), hashHistory(10), tapes(bd.getNbLines()), pastActions(100)
 {
   this->stackHistory = -1;
   this->currentStateName = nullptr;
@@ -215,6 +215,7 @@ void Config::reset()
 
   actionHistory.clear();
   pastActions.clear();
+  hashHistory.clear();
 
   stack.clear();
   stackHistory = -1;
@@ -499,3 +500,25 @@ void Config::addToEntropyHistory(float entropy)
   entropyHistory[*currentStateName].emplace_back(entropy);
 }
 
+std::size_t Config::computeHash()
+{
+  static int window = 3;
+
+  unsigned int start = std::max(0, head-window);
+  unsigned int end = std::min((unsigned int)tapes[0].ref.size()-1, (unsigned int)head+window);
+
+  std::hash<std::string> hasher;
+  std::size_t result = 0;
+
+  for (unsigned int i = start; i < end; i++)
+    for (auto & tape : tapes)
+      result ^= (hasher(tape[i])*0x9e3779b9+(result << 6)+(result >>2));
+
+  return result;
+}
+
+void Config::addHashToHistory()
+{
+  hashHistory.push(computeHash());
+}
+
diff --git a/transition_machine/src/Oracle.cpp b/transition_machine/src/Oracle.cpp
index 6a4d618922999991bd98e463f86ad44632660386..f0246c6654bcb0d4392092d418f17681562b0955 100644
--- a/transition_machine/src/Oracle.cpp
+++ b/transition_machine/src/Oracle.cpp
@@ -106,6 +106,9 @@ void Oracle::createDatabase()
     if (c.getCurrentStateHistory().size() < 2)
       return std::string("EPSILON");
 
+    if (c.hashHistory.contains(c.computeHash()))
+      return std::string("EPSILON");
+
     //return std::string("BACK 1");
 
     auto & pos = c.getTape("POS");
@@ -135,12 +138,22 @@ void Oracle::createDatabase()
   },
   [](Config & c, Oracle *)
   {
+    //fprintf(stderr, "HistorySize = %lu\n", c.getCurrentStateHistory().size());
+    //if (c.getCurrentStateHistory().size() >= 2)
+      //fprintf(stderr, "<%s> <%s>\n", c.getCurrentStateHistory()[c.getCurrentStateHistory().size()-2].c_str(), c.getCurrentStateHistory()[c.getCurrentStateHistory().size()-1].c_str());
+
     if (c.getCurrentStateHistory().size() >= 2 && (c.getCurrentStateHistory().back() == "BACK" || c.getCurrentStateHistory()[c.getCurrentStateHistory().size()-2] == "BACK"))
+    {
+//      fprintf(stderr, "Avoiding loop\n");
       return std::string("EPSILON");
+    }
 
     if (c.getCurrentStateHistory().size() < 2)
       return std::string("EPSILON");
 
+    if (c.hashHistory.contains(c.computeHash()))
+      return std::string("EPSILON");
+
     //return std::string("BACK 1");
 
     auto & morpho = c.getTape("MORPHO");
@@ -155,8 +168,8 @@ void Oracle::createDatabase()
     if (morpho0 == morphoRef)
       return std::string("EPSILON");
 
-    auto & genre0 = split(morpho0, '|')[0];
-    auto & genre1 = split(morpho1, '|')[0];
+    auto genre0 = split(morpho0, '|')[0];
+    auto genre1 = split(morpho1, '|')[0];
 
     if (genre0 == "g=f" && genre1 == "g=m")
       return std::string("BACK 1");