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; +} +