diff --git a/decoder/src/Decoder.cpp b/decoder/src/Decoder.cpp
index 16d7b73099d391b8cec2c6ac3814d294a5bc2989..359bd810419cc4d50ff0d5815fd35212e67e36c3 100644
--- a/decoder/src/Decoder.cpp
+++ b/decoder/src/Decoder.cpp
@@ -57,7 +57,7 @@ void printAdvancement(Config & config, float currentSpeed)
   if (ProgramParameters::interactive)
   {
     int totalSize = config.tapes[0].hyp.size();
-    int steps = config.head;
+    int steps = config.getHead();
     if (steps && (steps % 200 == 0 || totalSize-steps < 200))
       fprintf(stderr, "Decode : %.2f%%  speed : %s actions/s\r", 100.0*steps/totalSize, int2humanStr((int)currentSpeed).c_str());
   }
@@ -101,7 +101,7 @@ std::pair<float,std::string> getClassifierAction(Config & config, Classifier::We
     if(!action->appliable(config) || nbValidActions-1 != index)
     {
       // First case the analysis is finished but without an empty stack
-      if (config.head == (int)config.tapes[0].ref.size()-1)
+      if (config.getHead() == (int)config.tapes[0].ref.size()-1)
       {
         while (!config.stackEmpty())
           config.stackPop();
@@ -140,10 +140,10 @@ void computeAndPrintSequenceEntropy(Config & config, bool & justFlipped, Errors
 {
   if (ProgramParameters::printEntropy || ProgramParameters::errorAnalysis)
   {
-    if (config.head >= 1 && config.getTape(ProgramParameters::sequenceDelimiterTape)[config.head-1] != ProgramParameters::sequenceDelimiter)
+    if (config.getHead() >= 1 && config.getTape(ProgramParameters::sequenceDelimiterTape)[config.getHead()-1] != ProgramParameters::sequenceDelimiter)
       justFlipped = false;
 
-    if ((config.head >= 1 && config.getTape(ProgramParameters::sequenceDelimiterTape)[config.head-1] == ProgramParameters::sequenceDelimiter && !justFlipped))
+    if ((config.getHead() >= 1 && config.getTape(ProgramParameters::sequenceDelimiterTape)[config.getHead()-1] == ProgramParameters::sequenceDelimiter && !justFlipped))
     {
       justFlipped = true;
       errors.newSequence();
diff --git a/trainer/src/Trainer.cpp b/trainer/src/Trainer.cpp
index 3da6393d916355da015dc346562ac64f2e70c50c..6784c3ccc369f90e81898d2e55447395eb85d435 100644
--- a/trainer/src/Trainer.cpp
+++ b/trainer/src/Trainer.cpp
@@ -57,7 +57,7 @@ void Trainer::computeScoreOnDev()
       if (ProgramParameters::interactive)
       {
         int totalSize = devConfig->tapes[0].hyp.size();
-        int steps = devConfig->head;
+        int steps = devConfig->getHead();
         if (steps && (steps % 200 == 0 || totalSize-steps < 200))
         {
           fprintf(stderr, "                                                      \r");
@@ -126,10 +126,10 @@ void Trainer::computeScoreOnDev()
 
         entropyAccumulator += entropy;
 
-        if (devConfig->head >= 1 && devConfig->getTape(ProgramParameters::sequenceDelimiterTape)[devConfig->head-1] != ProgramParameters::sequenceDelimiter)
+        if (devConfig->getHead() >= 1 && devConfig->getTape(ProgramParameters::sequenceDelimiterTape)[devConfig->getHead()-1] != ProgramParameters::sequenceDelimiter)
         justFlipped = false;
 
-        if ((devConfig->head >= 1 && devConfig->getTape(ProgramParameters::sequenceDelimiterTape)[devConfig->head-1] == ProgramParameters::sequenceDelimiter && !justFlipped))
+        if ((devConfig->getHead() >= 1 && devConfig->getTape(ProgramParameters::sequenceDelimiterTape)[devConfig->getHead()-1] == ProgramParameters::sequenceDelimiter && !justFlipped))
         {
           justFlipped = true;
           entropyAccumulator /= nbActionsInSequence;
@@ -209,7 +209,7 @@ void Trainer::train()
         if (ProgramParameters::interactive)
         {
           int totalSize = ProgramParameters::iterationSize == -1 ? trainConfig.tapes[0].hyp.size() : ProgramParameters::iterationSize;
-          int steps = ProgramParameters::iterationSize == -1 ? trainConfig.head : nbSteps;
+          int steps = ProgramParameters::iterationSize == -1 ? trainConfig.getHead() : nbSteps;
           if (steps % 200 == 0 || totalSize-steps < 200)
           {
             fprintf(stderr, "                                                      \r");
@@ -226,7 +226,7 @@ void Trainer::train()
 
         if (zeroCostActions.empty())
         {
-          if (trainConfig.head >= (int)trainConfig.tapes[0].ref.size()-1)
+          if (trainConfig.getHead() >= (int)trainConfig.tapes[0].ref.size()-1)
           {
             while (!trainConfig.stackEmpty())
               trainConfig.stackPop();
diff --git a/transition_machine/include/Config.hpp b/transition_machine/include/Config.hpp
index 6d1923261ffad64067ff8369d4cdbdbc2cdf796f..f04fe555dc3a94d54b12ca6fd44091346a04eeab 100644
--- a/transition_machine/include/Config.hpp
+++ b/transition_machine/include/Config.hpp
@@ -28,11 +28,12 @@ class Config
     std::string name;
     /// @brief Whether or not the content of this Tape is known at the start of the program (it is an input).
     bool isKnown;
-
     /// @brief Content of the cells of this Tape, that was given as an input to this program.
     std::vector<std::string> ref;
     /// @brief Content of the cells of this Tape, which have been predicted by the program so far.
     std::vector<std::string> hyp;
+    /// @brief The head of this Tape, an index.
+    int head;
     /// @brief Access the value of a cell.
     ///
     /// If isKnown is true, the vector ref will be read, otherwise the vector hyp will be read.
@@ -55,17 +56,17 @@ class Config
   std::vector<int> stack;
   /// @brief The lastest popped element from the stack
   int stackHistory;
+  /// @brief The name of the input file used to fill the tapes.
+  std::string inputFilename;
+  /// @brief The BD that describes the tapes of this Config.
+  BD & bd;
+  /// @brief The head of this Config. An index of the multi-tapes buffer.
+  int head;
 
   public :
 
-  /// @brief The BD that describes the tapes of this Config.
-  BD & bd;
   /// @brief The tapes of the multi-tapes buffer. They all have the same size.
   std::vector<Tape> tapes;
-  /// @brief The head of this Config. An index of the multi-tapes buffer.
-  int head;
-  /// @brief The name of the input file used to fill the tapes.
-  std::string inputFilename;
   /// @brief An history of hashes, can be used to detect loops.
   LimitedStack<std::size_t> hashHistory;
   /// @brief The sequence of Actions that made that Config.
@@ -198,6 +199,22 @@ class Config
   // 
   ////////////////////////////////////////////////////////////////////////////
   void addHashToHistory();
+  /// @brief Get the Dict of a Line from its index.
+  ///
+  /// @param num The index of the Line.
+  ///
+  /// @return The Dict of the Line.
+  Dict * getDictOfLine(int num);
+  /// @brief Get the Dict of a Line from its name.
+  ///
+  /// @param name The name of the Line.
+  ///
+  /// @return The Dict of the Line.
+  Dict * getDictOfLine(const std::string & name);
+  /// @brief Get the value of the head.
+  ///
+  /// @return The head of the multi-tapes buffer.
+  int getHead() const;
 };
 
 #endif
diff --git a/transition_machine/src/ActionBank.cpp b/transition_machine/src/ActionBank.cpp
index 7946d1fa74ef33da9a9c7e0a2043036adc2b05c8..0e3787dac1a0a374c64b6df7e69a41667cfba078 100644
--- a/transition_machine/src/ActionBank.cpp
+++ b/transition_machine/src/ActionBank.cpp
@@ -60,14 +60,14 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na
         {
           int stackIndex = std::stoi(object[1]);
           int bufferIndex = c.stackGetElem(stackIndex);
-          int relativeIndex = bufferIndex - c.head;
+          int relativeIndex = bufferIndex - c.getHead();
           simpleBufferWrite(c, tapeName, value, relativeIndex);
         };
       auto undo = [tapeName, object](Config & c, Action::BasicAction &)
         {
           int stackIndex = std::stoi(object[1]);
           int bufferIndex = c.stackGetElem(stackIndex);
-          int relativeIndex = bufferIndex - c.head;
+          int relativeIndex = bufferIndex - c.getHead();
           simpleBufferWrite(c, tapeName, "", relativeIndex);
         };
       auto appliable = [tapeName, object](Config & c, Action::BasicAction &)
@@ -76,7 +76,7 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na
           if (!c.stackHasIndex(stackIndex))
             return false;
           int bufferIndex = c.stackGetElem(stackIndex);
-          int relativeIndex = bufferIndex - c.head;
+          int relativeIndex = bufferIndex - c.getHead();
           return simpleBufferWriteAppliable(c, tapeName, relativeIndex);
         };
       Action::BasicAction basicAction =
@@ -172,11 +172,11 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na
   else if(std::string(b1) == "SHIFT")
   {
     auto apply = [](Config & c, Action::BasicAction &)
-      {c.stackPush(c.head);};
+      {c.stackPush(c.getHead());};
     auto undo = [](Config & c, Action::BasicAction &)
       {c.stackPop();};
     auto appliable = [](Config & c, Action::BasicAction &)
-      {return c.head < (int)c.tapes[0].ref.size()-1;};
+      {return c.getHead() < (int)c.tapes[0].ref.size()-1;};
     Action::BasicAction basicAction =
       {Action::BasicAction::Type::Push, "", apply, undo, appliable};
 
@@ -200,13 +200,13 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na
   {
     auto apply = [](Config & c, Action::BasicAction &)
       {
-        int b0 = c.head;
+        int b0 = c.getHead();
         int s0 = c.stackTop();
         simpleBufferWrite(c, "GOV", std::to_string(b0-s0), s0-b0);
       };
     auto undo = [](Config & c, Action::BasicAction &)
       {
-        int b0 = c.head;
+        int b0 = c.getHead();
         int s0 = c.stackTop();
         simpleBufferWrite(c, "GOV", "", s0-b0);
       };
@@ -214,7 +214,7 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na
       {
         if (c.stackEmpty())
           return false;
-        int b0 = c.head;
+        int b0 = c.getHead();
         int s0 = c.stackTop();
         return simpleBufferWriteAppliable(c, "GOV", s0-b0);
       };
@@ -227,13 +227,13 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na
     {
       auto apply2 = [b2](Config & c, Action::BasicAction &)
         {
-          int b0 = c.head;
+          int b0 = c.getHead();
           int s0 = c.stackTop();
           simpleBufferWrite(c, "LABEL", b2, s0-b0);
         };
       auto undo2 = [](Config & c, Action::BasicAction &)
         {
-          int b0 = c.head;
+          int b0 = c.getHead();
           int s0 = c.stackTop();
           simpleBufferWrite(c, "LABEL", "", s0-b0);
         };
@@ -241,7 +241,7 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na
         {
           if (c.stackEmpty())
             return false;
-          int b0 = c.head;
+          int b0 = c.getHead();
           int s0 = c.stackTop();
           return simpleBufferWriteAppliable(c, "LABEL", s0-b0);
         };
@@ -264,7 +264,7 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na
       {
         if (c.stackEmpty())
           return false;
-        return !c.isFinal() && c.head < (int)c.tapes[0].ref.size()-1;
+        return !c.isFinal() && c.getHead() < (int)c.tapes[0].ref.size()-1;
       };
     Action::BasicAction basicAction3 =
       {Action::BasicAction::Type::Pop, b1, apply3, undo3, appliable3};
@@ -275,7 +275,7 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na
   {
     auto apply = [](Config & c, Action::BasicAction &)
       {
-        int b0 = c.head;
+        int b0 = c.getHead();
         int s0 = c.stackTop();
         simpleBufferWrite(c, "GOV", std::to_string(s0-b0), 0);
       };
@@ -314,7 +314,7 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na
 
     auto apply3 = [](Config & c, Action::BasicAction &)
       {
-        c.stackPush(c.head);
+        c.stackPush(c.getHead());
       };
     auto undo3 = [](Config & c, Action::BasicAction &)
       {
@@ -322,7 +322,7 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na
       };
     auto appliable3 = [](Config & c, Action::BasicAction &)
       {
-        return !c.isFinal() && c.head < (int)c.tapes[0].ref.size()-1;
+        return !c.isFinal() && c.getHead() < (int)c.tapes[0].ref.size()-1;
       };
     Action::BasicAction basicAction3 =
       {Action::BasicAction::Type::Push, b1, apply3, undo3, appliable3};
@@ -333,13 +333,13 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na
   {
     auto apply0 = [b2](Config & c, Action::BasicAction &)
       {
-        int b0 = c.head;
+        int b0 = c.getHead();
         int s0 = c.stackTop();
         simpleBufferWrite(c, ProgramParameters::sequenceDelimiterTape, ProgramParameters::sequenceDelimiter, s0-b0);
       };
     auto undo0 = [](Config & c, Action::BasicAction)
       {
-        int b0 = c.head;
+        int b0 = c.getHead();
         int s0 = c.stackTop();
         simpleBufferWrite(c, ProgramParameters::sequenceDelimiterTape, "", s0-b0);
       };
@@ -355,7 +355,7 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na
     auto apply = [](Config & c, Action::BasicAction & ba)
       {
         auto & govs = c.getTape("GOV");
-        int b0 = c.head;
+        int b0 = c.getHead();
         int rootIndex = -1;
         for (int i = c.stackSize()-1; i >= 0; i--)
         {
@@ -390,7 +390,7 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na
     auto undo = [](Config & c, Action::BasicAction & ba)
       {
         auto & govs = c.getTape("GOV");
-        int b0 = c.head;
+        int b0 = c.getHead();
         for (int i = c.stackSize()-1; i >= 0; i--)
         {
           auto s = c.stackGetElem(i);
@@ -417,7 +417,7 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na
     auto apply2 = [b2](Config & c, Action::BasicAction & ba)
       {
         auto & labels = c.getTape("LABEL");
-        int b0 = c.head;
+        int b0 = c.getHead();
         int rootIndex = -1;
 
         for (int i = c.stackSize()-1; i >= 0; i--)
@@ -441,7 +441,7 @@ std::vector<Action::BasicAction> ActionBank::str2sequence(const std::string & na
     auto undo2 = [](Config & c, Action::BasicAction & ba)
       {
         auto & labels = c.getTape("LABEL");
-        int b0 = c.head;
+        int b0 = c.getHead();
 
         for (int i = c.stackSize()-1; i >= 0; i--)
         {
@@ -578,7 +578,7 @@ void ActionBank::simpleBufferWrite(Config & config, const std::string & tapeName
 {
   auto & tape = config.getTape(tapeName);
 
-  int index = config.head + relativeIndex;
+  int index = config.getHead() + relativeIndex;
 
   tape.hyp[index] = value;
 }
@@ -588,7 +588,7 @@ bool ActionBank::simpleBufferWriteAppliable(Config & config,
 {
   auto & tape = config.getTape(tapeName);
 
-  int index = config.head + relativeIndex;
+  int index = config.getHead() + relativeIndex;
 
   if (index == (int)tape.hyp.size()-1)
     return true;
@@ -601,7 +601,7 @@ bool ActionBank::isRuleAppliable(Config & config,
 {
   if (!simpleBufferWriteAppliable(config, tapeName, relativeIndex))
     return false;
-  return ruleIsAppliable(config.getTape(tapeName)[config.head+relativeIndex], rule);
+  return ruleIsAppliable(config.getTape(tapeName)[config.getHead()+relativeIndex], rule);
 }
 
 void ActionBank::writeRuleResult(Config & config, const std::string & fromTapeName, const std::string & targetTapeName, const std::string & rule, int relativeIndex)
@@ -609,9 +609,9 @@ void ActionBank::writeRuleResult(Config & config, const std::string & fromTapeNa
   auto & fromTape = config.getTape(fromTapeName);
   auto & toTape = config.getTape(targetTapeName);
 
-  auto & from = fromTape.ref[config.head + relativeIndex];
+  auto & from = fromTape.ref[config.getHead() + relativeIndex];
 
-  toTape.hyp[config.head + relativeIndex] = applyRule(from, rule);
+  toTape.hyp[config.getHead() + relativeIndex] = applyRule(from, rule);
 }
 
 int ActionBank::getLinkLength(const Config & c, const std::string & action)
@@ -627,7 +627,7 @@ int ActionBank::getLinkLength(const Config & c, const std::string & action)
     }
 
     int stackIndex = c.stackGetElem(0);
-    return std::abs(c.head - stackIndex);
+    return std::abs(c.getHead() - stackIndex);
   }
 
   return 0;
diff --git a/transition_machine/src/Config.cpp b/transition_machine/src/Config.cpp
index 5105644f97a77f5c30af469c8bdee51b3bbab06f..15f6e745700f420cf01c6a0d8cc5c51565be11b8 100644
--- a/transition_machine/src/Config.cpp
+++ b/transition_machine/src/Config.cpp
@@ -166,7 +166,12 @@ void Config::printAsOutput(FILE * output)
 void Config::moveHead(int mvt)
 {
   if (head + mvt < (int)tapes[0].ref.size())
+  {
     head += mvt;
+
+    for (auto & tape : tapes)
+      tape.head += mvt;
+  }
 }
 
 bool Config::isFinal()
@@ -381,3 +386,18 @@ void Config::addHashToHistory()
   hashHistory.push(computeHash());
 }
 
+Dict * Config::getDictOfLine(int num)
+{
+  return bd.getDictOfLine(num);
+}
+
+Dict * Config::getDictOfLine(const std::string & name)
+{
+  return bd.getDictOfLine(name);
+}
+
+int Config::getHead() const
+{
+  return head;
+}
+
diff --git a/transition_machine/src/FeatureBank.cpp b/transition_machine/src/FeatureBank.cpp
index ee038bd72d61c0109d634fd62ab8f8fe1a40e28d..fca1c6021ba23946ab4386c7bf4cc39a9c4c3ce0 100644
--- a/transition_machine/src/FeatureBank.cpp
+++ b/transition_machine/src/FeatureBank.cpp
@@ -188,7 +188,7 @@ FeatureModel::FeatureValue FeatureBank::ldep(Config & config, int index, const s
   auto & tape = config.getTape(tapeName);
   auto & govs = config.getTape("GOV");
   auto & eos = config.getTape(ProgramParameters::sequenceDelimiterTape);
-  Dict * dict = config.bd.getDictOfLine(tapeName);
+  Dict * dict = config.getDictOfLine(tapeName);
   auto policy = dictPolicy2FeaturePolicy(dict->policy);
 
   if(object == "s")
@@ -200,7 +200,7 @@ FeatureModel::FeatureValue FeatureBank::ldep(Config & config, int index, const s
   }
   else
   {
-    index += config.head;
+    index += config.getHead();
   }
 
   if(index < 0 || index >= (int)tape.hyp.size())
@@ -237,7 +237,7 @@ FeatureModel::FeatureValue FeatureBank::dist(Config & config, const std::string
     if(index1 < 0 || index1 >= (int)config.tapes[0].hyp.size())
       return {dict, featName, Dict::nullValueStr, policy};
 
-    elem1 = config.head + index1;
+    elem1 = config.getHead() + index1;
   }
   else
   {
@@ -252,7 +252,7 @@ FeatureModel::FeatureValue FeatureBank::dist(Config & config, const std::string
     if(index2 < 0 || index2 >= (int)config.tapes[0].hyp.size())
       return {dict, featName, Dict::nullValueStr, policy};
 
-    elem2 = config.head + index2;
+    elem2 = config.getHead() + index2;
   }
   else
   {
@@ -270,7 +270,7 @@ FeatureModel::FeatureValue FeatureBank::rdep(Config & config, int index, const s
   auto & tape = config.getTape(tapeName);
   auto & govs = config.getTape("GOV");
   auto & eos = config.getTape(ProgramParameters::sequenceDelimiterTape);
-  Dict * dict = config.bd.getDictOfLine(tapeName);
+  Dict * dict = config.getDictOfLine(tapeName);
   auto policy = dictPolicy2FeaturePolicy(dict->policy);
 
   if(object == "s")
@@ -282,7 +282,7 @@ FeatureModel::FeatureValue FeatureBank::rdep(Config & config, int index, const s
   }
   else
   {
-    index += config.head;
+    index += config.getHead();
   }
 
   if(index < 0 || index >= (int)tape.hyp.size())
@@ -310,10 +310,10 @@ FeatureModel::FeatureValue FeatureBank::rdep(Config & config, int index, const s
 FeatureModel::FeatureValue FeatureBank::simpleBufferAccess(Config & config, int relativeIndex, const std::string & tapeName, const std::string & featName)
 {
   auto & tape = config.getTape(tapeName);
-  Dict * dict = config.bd.getDictOfLine(tapeName);
+  Dict * dict = config.getDictOfLine(tapeName);
   auto policy = dictPolicy2FeaturePolicy(dict->policy);
 
-  int index = config.head + relativeIndex;
+  int index = config.getHead() + relativeIndex;
 
   if(index < 0 || index >= (int)tape.hyp.size())
     return {dict, featName, Dict::nullValueStr, policy};
@@ -327,7 +327,7 @@ FeatureModel::FeatureValue FeatureBank::simpleBufferAccess(Config & config, int
 FeatureModel::FeatureValue FeatureBank::simpleStackAccess(Config & config, int relativeIndex, const std::string & tapeName, const std::string & featName)
 {
   auto & tape = config.getTape(tapeName);
-  Dict * dict = config.bd.getDictOfLine(tapeName);
+  Dict * dict = config.getDictOfLine(tapeName);
   auto policy = dictPolicy2FeaturePolicy(dict->policy);
 
   if(!config.stackHasIndex(relativeIndex))
@@ -419,7 +419,7 @@ FeatureModel::FeatureValue FeatureBank::aggregateBuffer(Config & c, int from, in
 
   for (auto & tape : c.tapes)
   {
-    Dict * dict = c.bd.getDictOfLine(tape.name);
+    Dict * dict = c.getDictOfLine(tape.name);
     auto policy = dictPolicy2FeaturePolicy(dict->policy);
     bool ignored = false;
     for (auto & except : exceptions)
@@ -433,7 +433,7 @@ FeatureModel::FeatureValue FeatureBank::aggregateBuffer(Config & c, int from, in
 
     for (int i = from; i <= to; i++)
     {
-      int index = c.head + i;
+      int index = c.getHead() + i;
       std::string featName = "b."+std::to_string(i)+"."+tape.name;
       if(index < 0 || index >= (int)tape.hyp.size())
       {
@@ -468,7 +468,7 @@ FeatureModel::FeatureValue FeatureBank::aggregateStack(Config & c, int from, con
 
   for (auto & tape : c.tapes)
   {
-    Dict * dict = c.bd.getDictOfLine(tape.name);
+    Dict * dict = c.getDictOfLine(tape.name);
     auto policy = dictPolicy2FeaturePolicy(dict->policy);
     bool ignored = false;
     for (auto & except : exceptions)
diff --git a/transition_machine/src/Oracle.cpp b/transition_machine/src/Oracle.cpp
index de42be0411a479bcde03d784b0dd9d8a327b908e..36cdc17d603b0e2cd4c348818baaefee9b6d8582 100644
--- a/transition_machine/src/Oracle.cpp
+++ b/transition_machine/src/Oracle.cpp
@@ -120,16 +120,16 @@ void Oracle::createDatabase()
 
     auto & pos = c.getTape("POS");
 
-    if (c.head > 0 && pos[c.head-1] != pos.ref[c.head-1] && pos[c.head-1] == "det" && pos[c.head] == "prorel")
+    if (c.getHead() > 0 && pos[c.getHead()-1] != pos.ref[c.getHead()-1] && pos[c.getHead()-1] == "det" && pos[c.getHead()] == "prorel")
       return std::string("BACK 1");
 
-    if (c.head > 0 && pos[c.head-1] != pos.ref[c.head-1] && pos[c.head-1] == "det" && pos[c.head] == "prep")
+    if (c.getHead() > 0 && pos[c.getHead()-1] != pos.ref[c.getHead()-1] && pos[c.getHead()-1] == "det" && pos[c.getHead()] == "prep")
       return std::string("BACK 1");
 
-    if (c.head > 0 && pos[c.head-1] != pos.ref[c.head-1] && pos[c.head-1] == "nc" && pos[c.head] == "nc")
+    if (c.getHead() > 0 && pos[c.getHead()-1] != pos.ref[c.getHead()-1] && pos[c.getHead()-1] == "nc" && pos[c.getHead()] == "nc")
       return std::string("BACK 1");
 
-    if (c.head > 0 && pos[c.head-1] != pos.ref[c.head-1] && pos[c.head-1] == "nc" && pos[c.head] == "prep")
+    if (c.getHead() > 0 && pos[c.getHead()-1] != pos.ref[c.getHead()-1] && pos[c.getHead()-1] == "nc" && pos[c.getHead()] == "prep")
       return std::string("BACK 1");
 
     return std::string("EPSILON");
@@ -165,12 +165,12 @@ void Oracle::createDatabase()
 
     auto & morpho = c.getTape("MORPHO");
 
-    if (c.head <= 0)
+    if (c.getHead() <= 0)
       return std::string("EPSILON");
 
-    auto & morphoRef = morpho.ref[c.head-1];
-    auto & morpho0 = morpho[c.head-1];
-    auto & morpho1 = morpho[c.head];
+    auto & morphoRef = morpho.ref[c.getHead()-1];
+    auto & morpho0 = morpho[c.getHead()-1];
+    auto & morpho1 = morpho[c.getHead()];
 
     if (morpho0 == morphoRef)
       return std::string("EPSILON");
@@ -204,7 +204,7 @@ void Oracle::createDatabase()
   },
   [](Config & c, Oracle *, const std::string & action)
   {
-    return action == "WRITE b.0 POS " + c.getTape("POS").ref[c.head] || c.head >= (int)c.tapes[0].ref.size()-1 ? 0 : 1;
+    return action == "WRITE b.0 POS " + c.getTape("POS").ref[c.getHead()] || c.getHead() >= (int)c.tapes[0].ref.size()-1 ? 0 : 1;
   })));
 
   str2oracle.emplace("tokenizer", std::unique_ptr<Oracle>(new Oracle(
@@ -220,7 +220,7 @@ void Oracle::createDatabase()
   },
   [](Config & c, Oracle *, const std::string & action)
   {
-    return action == "WRITE b.0 BIO " + c.getTape("BIO").ref[c.head] || c.head >= (int)c.tapes[0].ref.size()-1 ? 0 : 1;
+    return action == "WRITE b.0 BIO " + c.getTape("BIO").ref[c.getHead()] || c.getHead() >= (int)c.tapes[0].ref.size()-1 ? 0 : 1;
   })));
 
   str2oracle.emplace("eos", std::unique_ptr<Oracle>(new Oracle(
@@ -236,7 +236,7 @@ void Oracle::createDatabase()
   },
   [](Config & c, Oracle *, const std::string & action)
   {
-    return action == "WRITE b.0 " + ProgramParameters::sequenceDelimiterTape + " " + (c.getTape(ProgramParameters::sequenceDelimiterTape).ref[c.head] == std::string(ProgramParameters::sequenceDelimiter) ? std::string(ProgramParameters::sequenceDelimiter) : std::string("0")) || c.head >= (int)c.tapes[0].ref.size()-1 ? 0 : 1;
+    return action == "WRITE b.0 " + ProgramParameters::sequenceDelimiterTape + " " + (c.getTape(ProgramParameters::sequenceDelimiterTape).ref[c.getHead()] == std::string(ProgramParameters::sequenceDelimiter) ? std::string(ProgramParameters::sequenceDelimiter) : std::string("0")) || c.getHead() >= (int)c.tapes[0].ref.size()-1 ? 0 : 1;
   })));
 
   str2oracle.emplace("morpho", std::unique_ptr<Oracle>(new Oracle(
@@ -252,7 +252,7 @@ void Oracle::createDatabase()
   },
   [](Config & c, Oracle *, const std::string & action)
   {
-    return action == "WRITE b.0 MORPHO " + c.getTape("MORPHO").ref[c.head] || c.head >= (int)c.tapes[0].ref.size()-1 ? 0 : 1;
+    return action == "WRITE b.0 MORPHO " + c.getTape("MORPHO").ref[c.getHead()] || c.getHead() >= (int)c.tapes[0].ref.size()-1 ? 0 : 1;
   })));
 
   str2oracle.emplace("signature", std::unique_ptr<Oracle>(new Oracle(
@@ -270,8 +270,8 @@ void Oracle::createDatabase()
   [](Config & c, Oracle * oracle)
   {
     int window = 3;
-    int start = std::max<int>(c.head-window, 0);
-    int end = std::min<int>(c.head+window, c.getTape("SGN").hyp.size()-1);
+    int start = std::max<int>(c.getHead()-window, 0);
+    int end = std::min<int>(c.getHead()+window, c.getTape("SGN").hyp.size()-1);
 
     while (start < (int)c.getTape("SGN").hyp.size() && !c.getTape("SGN").hyp[start].empty())
       start++;
@@ -279,7 +279,7 @@ void Oracle::createDatabase()
     if (start > end)
       return std::string("NOTHING");
 
-    std::string action("MULTIWRITE " + std::to_string(start-c.head) + " " + std::to_string(end-c.head) + " " + std::string("SGN"));
+    std::string action("MULTIWRITE " + std::to_string(start-c.getHead()) + " " + std::to_string(end-c.getHead()) + " " + std::string("SGN"));
 
     for(int i = start; i <= end; i++)
     {
@@ -321,8 +321,8 @@ void Oracle::createDatabase()
   },
   [](Config & c, Oracle * oracle)
   {
-    const std::string & form = c.getTape("FORM")[c.head];
-    const std::string & pos = c.getTape("POS")[c.head];
+    const std::string & form = c.getTape("FORM")[c.getHead()];
+    const std::string & pos = c.getTape("POS")[c.getHead()];
     std::string & lemma = oracle->data[form + "_" + pos];
 
     if(lemma.empty())
@@ -357,11 +357,11 @@ void Oracle::createDatabase()
   },
   [](Config & c, Oracle *, const std::string & action)
   {
-    const std::string & form = c.getTape("FORM").ref[c.head];
-    const std::string & lemma = c.getTape("LEMMA").ref[c.head];
+    const std::string & form = c.getTape("FORM").ref[c.getHead()];
+    const std::string & lemma = c.getTape("LEMMA").ref[c.getHead()];
     std::string rule = getRule(form, lemma);
 
-    return action == std::string("RULE LEMMA ON FORM ") + rule || c.head >= (int)c.tapes[0].ref.size()-1 ? 0 : 1;
+    return action == std::string("RULE LEMMA ON FORM ") + rule || c.getHead() >= (int)c.tapes[0].ref.size()-1 ? 0 : 1;
   })));
 
   str2oracle.emplace("parser", std::unique_ptr<Oracle>(new Oracle(
@@ -381,12 +381,12 @@ void Oracle::createDatabase()
     auto & govs = c.getTape("GOV");
     auto & eos = c.getTape(ProgramParameters::sequenceDelimiterTape);
 
-    int head = c.head;
+    int head = c.getHead();
     int stackHead = c.stackEmpty() ? 0 : c.stackTop();
     int stackGov = stackHead + std::stoi(govs.ref[stackHead]);
     int headGov = head + std::stoi(govs.ref[head]);
-    int sentenceStart = c.head-1 < 0 ? 0 : c.head-1;
-    int sentenceEnd = c.head;
+    int sentenceStart = c.getHead()-1 < 0 ? 0 : c.getHead()-1;
+    int sentenceEnd = c.getHead();
 
     int cost = 0;
 
@@ -430,9 +430,9 @@ void Oracle::createDatabase()
       if (object[0] == "b")
       {
         if (parts[2] == "LABEL")
-          return action == "WRITE b.0 LABEL " + c.getTape("LABEL").ref[c.head] || c.head >= (int)c.tapes[0].ref.size()-1 || c.getTape("LABEL").ref[c.head] == "root" ? 0 : 1;
+          return action == "WRITE b.0 LABEL " + c.getTape("LABEL").ref[c.getHead()] || c.getHead() >= (int)c.tapes[0].ref.size()-1 || c.getTape("LABEL").ref[c.getHead()] == "root" ? 0 : 1;
         else if (parts[2] == "GOV")
-          return action == "WRITE b.0 GOV " + c.getTape("GOV").ref[c.head] || c.head >= (int)c.tapes[0].ref.size()-1 ? 0 : 1;
+          return action == "WRITE b.0 GOV " + c.getTape("GOV").ref[c.getHead()] || c.getHead() >= (int)c.tapes[0].ref.size()-1 ? 0 : 1;
       }
       else if (object[0] == "s")
       {
@@ -557,13 +557,13 @@ void Oracle::explainCostOfAction(FILE * output, Config & c, const std::string &
 
     if (object[0] == "b")
     {
-      int index = c.head + std::stoi(object[1]);
+      int index = c.getHead() + std::stoi(object[1]);
       expected = c.getTape(tape).ref[index];
     }
     else if (object[0] == "s")
     {
       int stackIndex = std::stoi(object[1]);
-      int bufferIndex = c.stackGetElem(stackIndex) + c.head;
+      int bufferIndex = c.stackGetElem(stackIndex) + c.getHead();
       expected = c.getTape(tape).ref[bufferIndex];
     }
     else
@@ -579,12 +579,12 @@ void Oracle::explainCostOfAction(FILE * output, Config & c, const std::string &
   auto & govs = c.getTape("GOV");
   auto & eos = c.getTape(ProgramParameters::sequenceDelimiterTape);
 
-  int head = c.head;
+  int head = c.getHead();
   int stackHead = c.stackEmpty() ? 0 : c.stackTop();
   int stackGov = stackHead + std::stoi(govs.ref[stackHead]);
   int headGov = head + std::stoi(govs.ref[head]);
-  int sentenceStart = c.head-1 < 0 ? 0 : c.head-1;
-  int sentenceEnd = c.head;
+  int sentenceStart = c.getHead()-1 < 0 ? 0 : c.getHead()-1;
+  int sentenceEnd = c.getHead();
 
   while(sentenceStart >= 0 && eos.ref[sentenceStart] != ProgramParameters::sequenceDelimiter)
     sentenceStart--;
@@ -608,12 +608,12 @@ void Oracle::explainCostOfAction(FILE * output, Config & c, const std::string &
         {
           if (otherGov == head)
           {
-            fprintf(output, "Word on stack %d(%s)\'s governor is the current head\n", s, c.getTape("FORM").ref[s].c_str());
+            fprintf(output, "Word on stack %d(%s)\'s governor is the current getHead()\n", s, c.getTape("FORM").ref[s].c_str());
             return;
           }
           else if (headGov == s)
           {
-            fprintf(output, "The current head\'s governor is on the stack %d(%s)\n", s, c.getTape("FORM").ref[s].c_str());
+            fprintf(output, "The current getHead()\'s governor is on the stack %d(%s)\n", s, c.getTape("FORM").ref[s].c_str());
             return;
           }
         }
@@ -637,7 +637,7 @@ void Oracle::explainCostOfAction(FILE * output, Config & c, const std::string &
       int otherGov = i + std::stoi(govs.ref[i]);
       if (otherGov == stackHead)
       {
-        fprintf(output, "Stack head is the governor of %d(%s)\n", i, c.getTape("FORM").ref[i].c_str());
+        fprintf(output, "Stack getHead() is the governor of %d(%s)\n", i, c.getTape("FORM").ref[i].c_str());
         return;
       }
     }
@@ -659,7 +659,7 @@ void Oracle::explainCostOfAction(FILE * output, Config & c, const std::string &
       fprintf(output, "Zero cost\n");
       return;
     }
-    if (parts.size() == 1 && stackGov == head )
+    if (parts.size() == 1 && stackGov == head)
     {
       fprintf(output, "Zero cost\n");
       return;
@@ -667,7 +667,7 @@ void Oracle::explainCostOfAction(FILE * output, Config & c, const std::string &
 
     if (labels.ref[stackHead] != parts[1])
     {
-      fprintf(output, "Stack head label %s mismatch with action label %s\n", labels.ref[stackHead].c_str(), parts[1].c_str());
+      fprintf(output, "Stack getHead() label %s mismatch with action label %s\n", labels.ref[stackHead].c_str(), parts[1].c_str());
 	  return;
     }
 
@@ -676,12 +676,12 @@ void Oracle::explainCostOfAction(FILE * output, Config & c, const std::string &
       int otherGov = i + std::stoi(govs.ref[i]);
       if (otherGov == stackHead)
       {
-        fprintf(output, "Word %d(%s)\'s governor is the stack head\n", i, c.getTape("FORM").ref[i].c_str());
+        fprintf(output, "Word %d(%s)\'s governor is the stack getHead()\n", i, c.getTape("FORM").ref[i].c_str());
         return;
       }
       else if (stackGov == i)
       {
-        fprintf(output, "Stack head\'s governor is the word %d(%s)\n", i, c.getTape("FORM").ref[i].c_str());
+        fprintf(output, "Stack getHead()\'s governor is the word %d(%s)\n", i, c.getTape("FORM").ref[i].c_str());
         return;
       }
     }