diff --git a/reading_machine/include/Action.hpp b/reading_machine/include/Action.hpp
index e6b58dc62f41d1cf3785473039a61051dd6b3590..3fd0aef7e122d83d7f8dd91feda82347d95ca252 100644
--- a/reading_machine/include/Action.hpp
+++ b/reading_machine/include/Action.hpp
@@ -30,14 +30,17 @@ class Action
   private :
 
   Type type;
-  std::function<void(Config & config, Action & action)> apply;
-  std::function<void(Config & config, Action & action)> undo;
-  std::function<bool(Config & config, Action & action)> appliable;
   std::vector<std::string> data;
 
   public :
 
-  Action(Type type, std::function<void(Config & config, Action & action)> apply, std::function<void(Config & config, Action & action)> undo, std::function<bool(Config & config, Action & action)> appliable);
+  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;
+
+  private :
+
+  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);
 
   public :
 
diff --git a/reading_machine/include/Config.hpp b/reading_machine/include/Config.hpp
index 697418c0f75a671b99f6123dfe4540f8a3ed0775..6738810d24af1cc3921659c5c9e38083bfbce6dd 100644
--- a/reading_machine/include/Config.hpp
+++ b/reading_machine/include/Config.hpp
@@ -83,7 +83,9 @@ class Config
   bool isEmptyNode(std::size_t lineIndex) const;
   bool isToken(std::size_t lineIndex) const;
   bool moveWordIndex(int relativeMovement);
+  bool canMoveWordIndex(int relativeMovement) const;
   bool moveCharacterIndex(int relativeMovement);
+  bool canMoveCharacterIndex(int relativeMovement) const;
   bool rawInputOnlySeparatorsLeft() const;
   std::size_t getWordIndex() const;
   std::size_t getCharacterIndex() const;
diff --git a/reading_machine/include/Transition.hpp b/reading_machine/include/Transition.hpp
index a250fb26deb1a5d8f4f5e6207641231c8c6adcf7..ecd90dfc68380bd19de4a2b07e3ed40341103c28 100644
--- a/reading_machine/include/Transition.hpp
+++ b/reading_machine/include/Transition.hpp
@@ -20,6 +20,9 @@ class Transition
   public :
 
   Transition(const std::string & name);
+  void apply(Config & config);
+  bool appliable(const Config & config) const;
+  int getCost(const Config & config) const;
 };
 
 #endif
diff --git a/reading_machine/include/TransitionSet.hpp b/reading_machine/include/TransitionSet.hpp
index b1ffd843d02c64e61837495a4842e34c02f9a942..04c1e9098c330812805e308642d0e598f9fe4463 100644
--- a/reading_machine/include/TransitionSet.hpp
+++ b/reading_machine/include/TransitionSet.hpp
@@ -17,6 +17,7 @@ class TransitionSet
   public :
 
   TransitionSet(const std::string & filename);
+  std::vector<std::pair<Transition &, int>> getAppliableTransitionsCosts(const Config & c);
 };
 
 #endif
diff --git a/reading_machine/src/Action.cpp b/reading_machine/src/Action.cpp
index a470bab1cd3b63dff5b3c657f7878720e6dd8edb..6de5017f2583bf8a55bf8ad32166c986195c6c67 100644
--- a/reading_machine/src/Action.cpp
+++ b/reading_machine/src/Action.cpp
@@ -1,6 +1,6 @@
 #include "Action.hpp"
 
-Action::Action(Action::Type type, std::function<void(Config & config, Action & action)> apply, std::function<void(Config & config, Action & action)> undo, std::function<bool(Config & config, Action & action)> appliable)
+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;
@@ -19,7 +19,7 @@ Action Action::addLinesIfNeeded(int nbLines)
   {
   };
 
-  auto appliable = [](Config &, Action &)
+  auto appliable = [](const Config &, const Action &)
   {
     return true;
   };
@@ -39,12 +39,9 @@ Action Action::moveWordIndex(int movement)
     config.moveWordIndex(movement);
   };
 
-  auto appliable = [movement](Config & config, Action &)
+  auto appliable = [movement](const Config & config, const Action &)
   {
-    bool possible = config.moveWordIndex(movement);
-    if (possible)
-      moveWordIndex(-movement);
-    return possible;
+    return config.canMoveWordIndex(movement);
   };
 
   return {Type::MoveWord, apply, undo, appliable};
@@ -62,12 +59,9 @@ Action Action::moveCharacterIndex(int movement)
     config.moveCharacterIndex(movement);
   };
 
-  auto appliable = [movement](Config & config, Action &)
+  auto appliable = [movement](const Config & config, const Action &)
   {
-    bool possible = config.moveCharacterIndex(movement);
-    if (possible)
-      moveCharacterIndex(-movement);
-    return possible;
+    return config.canMoveCharacterIndex(movement);
   };
 
   return {Type::MoveChar, apply, undo, appliable};
@@ -85,7 +79,7 @@ Action Action::addHypothesis(const std::string & colName, std::size_t lineIndex,
     config.getLastNotEmpty(colName, lineIndex) = "";
   };
 
-  auto appliable = [colName, lineIndex](Config & config, Action &)
+  auto appliable = [colName, lineIndex](const Config & config, const Action &)
   {
     return config.has(colName, lineIndex, 0);
   };
@@ -117,7 +111,7 @@ Action Action::addHypothesisRelative(const std::string & colName, Object object,
     return addHypothesis(colName, lineIndex, "").undo(config, a);
   };
 
-  auto appliable = [colName, object, relativeIndex](Config & config, Action & a)
+  auto appliable = [colName, object, relativeIndex](const Config & config, const Action & a)
   {
     int lineIndex = 0;
     if (object == Object::Buffer)
diff --git a/reading_machine/src/Config.cpp b/reading_machine/src/Config.cpp
index a8d8134ac62d4a0b75a159b6df9094941311c6fe..96500a71d690bb690765b66189bd6647fe8551c2 100644
--- a/reading_machine/src/Config.cpp
+++ b/reading_machine/src/Config.cpp
@@ -275,22 +275,38 @@ bool Config::moveWordIndex(int relativeMovement)
   return true;
 }
 
-bool Config::moveCharacterIndex(int relativeMovement)
+bool Config::canMoveWordIndex(int relativeMovement) const
 {
-  int oldVal = characterIndex;
-  for (int i = 0; i < relativeMovement; i++)
+  int nbMovements = 0;
+  int oldVal = wordIndex;
+  while (nbMovements != relativeMovement)
   {
-    relativeMovement > 0 ? characterIndex++ : characterIndex--;
-    if (!hasCharacter(characterIndex))
+    do
     {
-      characterIndex = oldVal;
-      return false;
+      relativeMovement > 0 ? oldVal++ : oldVal--;
+      if (!has(0,oldVal,0))
+        return false;
     }
+    while (!isToken(oldVal));
+    nbMovements += relativeMovement > 0 ? 1 : -1;
   }
 
   return true;
 }
 
+bool Config::moveCharacterIndex(int relativeMovement)
+{
+  int oldVal = characterIndex;
+  characterIndex = std::max(0, (int)std::min(characterIndex+relativeMovement, util::getSize(rawInput)));
+  return (int)characterIndex == oldVal + relativeMovement;
+}
+
+bool Config::canMoveCharacterIndex(int relativeMovement) const
+{
+  int target = std::max(0, (int)std::min(characterIndex+relativeMovement, util::getSize(rawInput)));
+  return target == (int)characterIndex + relativeMovement;
+}
+
 bool Config::rawInputOnlySeparatorsLeft() const
 {
   for (unsigned int i = characterIndex; i < rawInput.size(); i++)
diff --git a/reading_machine/src/Transition.cpp b/reading_machine/src/Transition.cpp
index b0ced3642a286fc2960cf222af0ad96a208df809..d8b9c8a1b62929f6138063fc3c47c017816b7249 100644
--- a/reading_machine/src/Transition.cpp
+++ b/reading_machine/src/Transition.cpp
@@ -19,6 +19,26 @@ Transition::Transition(const std::string & name)
 
 }
 
+void Transition::apply(Config & config)
+{
+  for (Action & action : sequence)
+    action.apply(config, action);
+}
+
+bool Transition::appliable(const Config & config) const
+{
+  for (const Action & action : sequence)
+    if (!action.appliable(config, action))
+      return false;
+
+  return true;
+}
+
+int Transition::getCost(const Config & config) const
+{
+  return cost(config);
+}
+
 void Transition::initWrite(std::string colName, std::string object, std::string index, std::string value)
 {
   auto objectValue = Action::str2object(object);
diff --git a/reading_machine/src/TransitionSet.cpp b/reading_machine/src/TransitionSet.cpp
index 1bf42b13096c1d51f54bcaffffadbd7b42941060..467ad42e659670e343a3a333fb53a751f56bf10e 100644
--- a/reading_machine/src/TransitionSet.cpp
+++ b/reading_machine/src/TransitionSet.cpp
@@ -23,3 +23,21 @@ TransitionSet::TransitionSet(const std::string & filename)
   std::fclose(file);
 }
 
+std::vector<std::pair<Transition &, int>> TransitionSet::getAppliableTransitionsCosts(const Config & c)
+{
+  using Pair = std::pair<Transition &, int>;
+  std::vector<Pair> appliableTransitions;
+
+  for (auto & transition : transitions)
+    if (transition.appliable(c))
+      appliableTransitions.emplace_back(transition, transition.getCost(c));
+
+  std::sort(appliableTransitions.begin(), appliableTransitions.end(), 
+  [](const Pair & a, const Pair & b)
+  {
+    return a.second < b.second;
+  });
+
+  return appliableTransitions;
+}
+