diff --git a/common/include/util.hpp b/common/include/util.hpp
index b2571801fae406ef44520f64ae9b44a66eb2ce80..ac4ffdc5396e45061f60b64a0e1e6b4afa857c9c 100644
--- a/common/include/util.hpp
+++ b/common/include/util.hpp
@@ -79,6 +79,17 @@ bool doIfNameMatch(const std::regex & reg, std::string_view name, const std::fun
 
 bool choiceWithProbability(float probability);
 
+template <typename T>
+std::string join(const std::string & delim, const std::vector<T> elems)
+{
+  std::string result;
+
+  for (unsigned int i = 0; i < elems.size(); i++)
+    result = fmt::format("{}{}{}", result, elems[i], i == elems.size()-1 ? "" : delim);
+
+  return result;
+}
+
 };
 
 template <>
diff --git a/reading_machine/src/Action.cpp b/reading_machine/src/Action.cpp
index 7c496eebd632060e82d56be30ee0617d7e7f55e1..92b44a370fe80db6fa2b6a2af03358280e5142a5 100644
--- a/reading_machine/src/Action.cpp
+++ b/reading_machine/src/Action.cpp
@@ -147,18 +147,23 @@ Action Action::addToHypothesis(const std::string & colName, std::size_t lineInde
 {
   auto apply = [colName, lineIndex, addition](Config & config, Action &)
   {
-    auto & current = config.getLastNotEmptyHyp(colName, lineIndex);
-    current = util::isEmpty(current) ? addition : current.get() + '|' + addition;
+    auto currentElems = util::split(config.getLastNotEmptyHypConst(colName, lineIndex).get(), '|');
+    currentElems.emplace_back(addition);
+
+    std::sort(currentElems.begin(), currentElems.end());
+
+    config.getLastNotEmptyHyp(colName, lineIndex) = util::join("|", currentElems);
   };
 
-  auto undo = [colName, lineIndex](Config & config, Action &)
+  auto undo = [colName, lineIndex, addition](Config & config, Action &)
   {
-    std::string newValue = config.getLastNotEmpty(colName, lineIndex);
-    while (!newValue.empty() and newValue.back() == '|')
-      newValue.pop_back();
-    if (!newValue.empty())
-      newValue.pop_back();
-    config.getLastNotEmpty(colName, lineIndex) = newValue;
+    auto curElems = util::split(config.getLastNotEmptyHypConst(colName, lineIndex).get(), '|');
+    std::vector<std::string> newElems;
+    for (auto & elem : curElems)
+      if (elem != addition)
+        newElems.emplace_back(elem);
+
+    config.getLastNotEmptyHyp(colName, lineIndex) = util::join("|", newElems);
   };
 
   auto appliable = [colName, lineIndex, addition](const Config & config, const Action &)