diff --git a/.gitignore b/.gitignore index 432de573..94526814 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ build install docs/html .vscode +examples/flight/mermaid.html # Prerequisites *.d diff --git a/examples/flight/flight.cc b/examples/flight/flight.cc index 97ee9a4d..be88f3d4 100644 --- a/examples/flight/flight.cc +++ b/examples/flight/flight.cc @@ -5,6 +5,7 @@ #include "symmetri/parsers.h" #include "symmetri/symmetri.h" +#include "symmetri/utilities.hpp" #include "transition.hpp" using namespace symmetri; diff --git a/examples/hello_world/main.cc b/examples/hello_world/main.cc index 1d78db31..f5988965 100644 --- a/examples/hello_world/main.cc +++ b/examples/hello_world/main.cc @@ -9,6 +9,7 @@ #include #include "symmetri/symmetri.h" +#include "symmetri/utilities.hpp" // Before main, we define a bunch of functions that can be bound to // transitions in the petri net. diff --git a/examples/model_benchmark/model_benchmark.cc b/examples/model_benchmark/model_benchmark.cc index 56a24949..e166b237 100644 --- a/examples/model_benchmark/model_benchmark.cc +++ b/examples/model_benchmark/model_benchmark.cc @@ -2,6 +2,7 @@ #include "symmetri/parsers.h" #include "symmetri/symmetri.h" +#include "symmetri/utilities.hpp" int main(int, char *argv[]) { spdlog::set_pattern("[%Y-%m-%d %H:%M:%S.%f] [%^%l%$] [thread %t] %v"); diff --git a/symmetri/include/symmetri/types.h b/symmetri/include/symmetri/types.h index 644c1c43..1fbfa548 100644 --- a/symmetri/include/symmetri/types.h +++ b/symmetri/include/symmetri/types.h @@ -60,72 +60,4 @@ using PriorityTable = std::vector>; ///< Priority is limited from ///< -128 to 127 -/** - * @brief Checks if the markings are exactly the same. Note that this uses a - * different type for Marking compared to the Marking type used to - * construct a net (an unordered map of strings). In this format the amount of - * tokens in a particular place is represented by how often that place occurs in - * the vector. For example: {"A","A","B"} is a marking with two tokens in place - * "A" and one token in place "B". This format does not have the overhead of - * mentioning all empty places. - * - * @tparam T - * @param m1 - * @param m2 - * @return true - * @return false - */ -template -bool MarkingEquality(const std::vector& m1, const std::vector& m2); - -/** - * @brief Checks if marking is at least a subset of final_marking. Note - * that this uses a different type for Marking compared to the Marking - * type used to construct a net (an unordered map of strings). In this - * format the amount of tokens in a particular place is represented by how often - * that place occurs in the vector. For example: {"A","A","B"} is a marking with - * two tokens in place "A" and one token in place "B". This format does not have - * the overhead of mentioning all empty places. - * - * @tparam T - * @param marking - * @param final_marking - * @return true - * @return false - */ -template -bool MarkingReached(const std::vector& marking, - const std::vector& final_marking); - -/** - * @brief Checks if two petri-nets have equal amount of arcs between places - * and transitions of the same name. - * - * @param net1 - * @param net2 - * @return true - * @return false - */ -bool stateNetEquality(const Net& net1, const Net& net2); - -/** - * @brief Calculates a hash given an event log. This hash is only influenced by - * the order of the completions of transitions and if the output of those - * transitions is Completed, or something else. - * - * @param event_log An eventlog, can both be from a terminated or a still active - * net. - * @return size_t The hashed result. - */ -size_t calculateTrace(const Eventlog& event_log) noexcept; - -/** - * @brief A convenience function to get a string representation of the - * state-enum. - * - * @param s The State - * @return std::string The State as a human readable string. - */ -std::string printState(State s) noexcept; - } // namespace symmetri diff --git a/symmetri/include/symmetri/utilities.hpp b/symmetri/include/symmetri/utilities.hpp new file mode 100644 index 00000000..f5eea8ef --- /dev/null +++ b/symmetri/include/symmetri/utilities.hpp @@ -0,0 +1,93 @@ +#pragma once +#include "symmetri/types.h" + +namespace symmetri { + +/** + * @brief Checks if the markings are exactly the same. Note that this uses a + * different type for Marking compared to the Marking type used to + * construct a net (an unordered map of strings). In this format the amount of + * tokens in a particular place is represented by how often that place occurs in + * the vector. For example: {"A","A","B"} is a marking with two tokens in place + * "A" and one token in place "B". This format does not have the overhead of + * mentioning all empty places. + * + * @tparam T + * @param m1 + * @param m2 + * @return true + * @return false + */ +template +bool MarkingEquality(const std::vector& m1, const std::vector& m2) { + auto m1_sorted = m1; + auto m2_sorted = m2; + std::sort(m1_sorted.begin(), m1_sorted.end()); + std::sort(m2_sorted.begin(), m2_sorted.end()); + return m1_sorted == m2_sorted; +} + +/** + * @brief Checks if marking is at least a subset of final_marking. Note + * that this uses a different type for Marking compared to the Marking + * type used to construct a net (an unordered map of strings). In this + * format the amount of tokens in a particular place is represented by how often + * that place occurs in the vector. For example: {"A","A","B"} is a marking with + * two tokens in place "A" and one token in place "B". This format does not have + * the overhead of mentioning all empty places. + * + * @tparam T + * @param marking + * @param final_marking + * @return true + * @return false + */ +template +bool MarkingReached(const std::vector& marking, + const std::vector& final_marking) { + if (final_marking.empty()) { + return false; + } + auto unique = final_marking; + std::sort(unique.begin(), unique.end()); + auto last = std::unique(unique.begin(), unique.end()); + unique.erase(last, unique.end()); + + return std::all_of(std::begin(unique), std::end(unique), [&](const auto& p) { + return std::count(marking.begin(), marking.end(), p) == + std::count(final_marking.begin(), final_marking.end(), p); + }); +} + +/** + * @brief Checks if two petri-nets have equal amount of arcs between places + * and transitions of the same name. + * + * @param net1 + * @param net2 + * @return true + * @return false + */ +bool stateNetEquality(const Net& net1, const Net& net2); + +/** + * @brief Calculates a hash given an event log. This hash is only influenced by + * the order of the completions of transitions and if the output of those + * transitions is Completed, or something else. + * + * @param event_log An eventlog, can both be from a terminated or a still active + * net. + * @return size_t The hashed result. + */ +size_t calculateTrace(const Eventlog& event_log) noexcept; + +/** + * @brief A convenience function to get a string representation of the + * state-enum. + * + * @param s The State + * @return std::string The State as a human readable string. + */ +std::string printState(State s) noexcept; + +} // namespace symmetri diff --git a/symmetri/symmetri.cc b/symmetri/symmetri.cc index 802a7eb5..f8db5888 100644 --- a/symmetri/symmetri.cc +++ b/symmetri/symmetri.cc @@ -8,6 +8,7 @@ #include "model.h" #include "symmetri/parsers.h" +#include "symmetri/utilities.hpp" namespace symmetri { diff --git a/symmetri/tests/test_bugs.cc b/symmetri/tests/test_bugs.cc index 10942ec5..1b50958a 100644 --- a/symmetri/tests/test_bugs.cc +++ b/symmetri/tests/test_bugs.cc @@ -2,6 +2,7 @@ #include #include "model.h" +#include "symmetri/utilities.hpp" using namespace symmetri; diff --git a/symmetri/tests/test_model.cc b/symmetri/tests/test_model.cc index 87602b0b..e1de9f33 100644 --- a/symmetri/tests/test_model.cc +++ b/symmetri/tests/test_model.cc @@ -2,6 +2,8 @@ #include #include "model.h" +#include "symmetri/utilities.hpp" + using namespace symmetri; using namespace moodycamel; diff --git a/symmetri/tests/test_parser.cc b/symmetri/tests/test_parser.cc index ffe789e9..9b2590b3 100644 --- a/symmetri/tests/test_parser.cc +++ b/symmetri/tests/test_parser.cc @@ -3,6 +3,8 @@ #include #include "symmetri/parsers.h" +#include "symmetri/utilities.hpp" + using namespace symmetri; TEST_CASE("Load p1.pnml net") { diff --git a/symmetri/tests/test_priorities.cc b/symmetri/tests/test_priorities.cc index a9cfb7d6..5b9709bd 100644 --- a/symmetri/tests/test_priorities.cc +++ b/symmetri/tests/test_priorities.cc @@ -3,6 +3,8 @@ #include #include "model.h" +#include "symmetri/utilities.hpp" + using namespace symmetri; using namespace moodycamel; diff --git a/symmetri/tests/test_types.cc b/symmetri/tests/test_types.cc index 8cf34c7b..a5c7c251 100644 --- a/symmetri/tests/test_types.cc +++ b/symmetri/tests/test_types.cc @@ -1,6 +1,7 @@ #include #include "symmetri/types.h" +#include "symmetri/utilities.hpp" using namespace symmetri; diff --git a/symmetri/types.cpp b/symmetri/types.cpp index 01cc1f72..9ac7dad7 100644 --- a/symmetri/types.cpp +++ b/symmetri/types.cpp @@ -4,59 +4,6 @@ #include namespace symmetri { -template <> -bool MarkingEquality(const std::vector& m1, - const std::vector& m2) { - auto m1_sorted = m1; - auto m2_sorted = m2; - std::sort(m1_sorted.begin(), m1_sorted.end()); - std::sort(m2_sorted.begin(), m2_sorted.end()); - return m1_sorted == m2_sorted; -} -template <> -bool MarkingReached(const std::vector& marking, - const std::vector& final_marking) { - if (final_marking.empty()) { - return false; - } - auto unique = final_marking; - std::sort(unique.begin(), unique.end()); - auto last = std::unique(unique.begin(), unique.end()); - unique.erase(last, unique.end()); - - return std::all_of(std::begin(unique), std::end(unique), [&](const auto& p) { - return std::count(marking.begin(), marking.end(), p) == - std::count(final_marking.begin(), final_marking.end(), p); - }); -} - -template <> -bool MarkingEquality(const std::vector& m1, - const std::vector& m2) { - auto m1_sorted = m1; - auto m2_sorted = m2; - std::sort(m1_sorted.begin(), m1_sorted.end()); - std::sort(m2_sorted.begin(), m2_sorted.end()); - return m1_sorted == m2_sorted; -} -template <> -bool MarkingReached( - const std::vector& marking, - const std::vector& final_marking) { - if (final_marking.empty()) { - return false; - } - auto unique = final_marking; - std::sort(unique.begin(), unique.end()); - auto last = std::unique(unique.begin(), unique.end()); - unique.erase(last, unique.end()); - - return std::all_of(std::begin(unique), std::end(unique), [&](const auto& p) { - return std::count(marking.begin(), marking.end(), p) == - std::count(final_marking.begin(), final_marking.end(), p); - }); -} - bool stateNetEquality(const Net& net1, const Net& net2) { if (net1.size() != net2.size()) { return false;