diff --git a/include/aidge/graphRegex/matchFsm/FsmRunTimeContext.hpp b/include/aidge/graphRegex/matchFsm/FsmRunTimeContext.hpp index 2f6066ba4cd97284c43b509c9d5eb988b65b53a5..36d09db47d23395d649a688252f2af803cb1bc9d 100644 --- a/include/aidge/graphRegex/matchFsm/FsmRunTimeContext.hpp +++ b/include/aidge/graphRegex/matchFsm/FsmRunTimeContext.hpp @@ -10,164 +10,162 @@ #include "aidge/graph/Node.hpp" - namespace Aidge{ - class FsmNode; +class FsmNode; + +/** + * @brief a class used to save the execution context of state machines, that is the actual state in the FSM, the actual node in the graph + * all node that have been Validate,Rejecte or Considered common +*/ +class FsmRunTimeContext +{ +private: + /** + * @brief the list of node rejected for all the context + */ + static std::vector<std::set<NodePtr>> mRejectedNodes; + /** + * @brief the actual state of this Context (where it's in the FSM graph) + */ + std::shared_ptr<FsmNode> mActState; + /** + * @brief the actual node of this Context (where it's in the graph) + */ + NodePtr mActOpNode; + /** + * @brief the map of the node consider as common and the common ID + * @details we need to store what node it's consider as common because of the end + * resolution of the matching, all node consider as common need to be the same in all context + */ + std::map<NodePtr,std::size_t> mCommonNodes; + /** + * @brief the map of the node that as been valid in this context , and the test that valide the node + */ + std::map<std::shared_ptr<ConditionalInterpreter>,std::set<NodePtr>> mValidNodes; + /** + * @brief the index in the rejected node of this context + */ + std::size_t mLocalIdxRejeced; +public: + /** + * @brief constructor + * @param actState the actual state in the FSM + * @param actOpNode the actual node in the graph + * @param idxRejeced the idx in the global regected node vector init max() as sentinel value of undefind + */ + FsmRunTimeContext(std::shared_ptr<FsmNode> actState ,NodePtr actOpNode ,std::size_t idxRejeced =std::numeric_limits<std::size_t>::max() ); + FsmRunTimeContext(std::shared_ptr<FsmRunTimeContext> fsmRunTime); + FsmRunTimeContext(std::shared_ptr<FsmRunTimeContext> fsmRunTime,std::shared_ptr<FsmNode> actState ,NodePtr actOpNode ); + + virtual ~FsmRunTimeContext()=default; + + /** + * @defgroup FsmRunTimeContextRejected Function for managing rejected nodes + */ + + /** + * @ingroup FsmRunTimeContextRejected + * @brief Add a node as rejected in this context + */ + void addRejectedNode(NodePtr node); + + /** + * @ingroup FsmRunTimeContextRejected + * @brief get the rejected nodes of this context + */ + inline std::set<NodePtr> getRejectedNodes(void) const { + return mRejectedNodes[mLocalIdxRejeced]; + } + + + /** + * @defgroup FsmRunTimeContextTest Function for test the context + */ - class FsmNode; + /** + * @ingroup FsmRunTimeContextTest + * @brief test if the actual state is valide + * @return bool + */ + bool isOnValidState(void); + /** + * @ingroup FsmRunTimeContextTest + * @brief test if the node is considered as common in this context + * @param node node to test + * @return bool + */ + bool isCommonDefined(NodePtr node); + /** + * @ingroup FsmRunTimeContextTest + * @brief test if has already validated in this context + * @param node node to test + * @return bool + */ + bool isAlreadyValid(NodePtr node); + /** + * @ingroup FsmRunTimeContextTest + * @brief test if this context is compatible with an others + * @details to say that two contexts are compatible is to check : + * that the contexts do not validate the same nodes (other than the common ones) + * and that the common ones have the same idx + * @param fsmContext the others context + * @return bool + */ + bool areCompatible(std::shared_ptr<FsmRunTimeContext> fsmContext); + /** + * @ingroup FsmRunTimeContextTest + * @brief test if this context is strictly equal with an others + * @param fsmContext the others context + * @return bool + */ + bool areEqual(std::shared_ptr<FsmRunTimeContext> fsmContext); /** - * @brief a class used to save the execution context of state machines, that is the actual state in the FSM, the actual node in the graph - * all node that have been Validate,Rejecte or Considered common + * @defgroup FsmRunTimeContextSet Function set context */ - class FsmRunTimeContext - { - private: - /** - * @brief the list of node rejected for all the context - */ - static std::vector<std::set<NodePtr>> mRejectedNodes; - /** - * @brief the actual state of this Context (where it's in the FSM graph) - */ - std::shared_ptr<FsmNode> mActState; - /** - * @brief the actual node of this Context (where it's in the graph) - */ - NodePtr mActOpNode; - /** - * @brief the map of the node consider as common and the common ID - * @details we need to store what node it's consider as common because of the end - * resolution of the matching, all node consider as common need to be the same in all context - */ - std::map<NodePtr,std::size_t> mCommonNodes; - /** - * @brief the map of the node that as been valid in this context , and the test that valide the node - */ - std::map<std::shared_ptr<ConditionalInterpreter>,std::set<NodePtr>> mValidNodes; - /** - * @brief the index in the rejected node of this context - */ - std::size_t mLocalIdxRejeced; - public: - /** - * @brief constructor - * @param actState the actual state in the FSM - * @param actOpNode the actual node in the graph - * @param idxRejeced the idx in the global regected node vector init max() as sentinel value of undefind - */ - FsmRunTimeContext(std::shared_ptr<FsmNode> actState ,NodePtr actOpNode ,std::size_t idxRejeced =std::numeric_limits<std::size_t>::max() ); - FsmRunTimeContext(std::shared_ptr<FsmRunTimeContext> fsmRunTime); - FsmRunTimeContext(std::shared_ptr<FsmRunTimeContext> fsmRunTime,std::shared_ptr<FsmNode> actState ,NodePtr actOpNode ); - - virtual ~FsmRunTimeContext()=default; - - /** - * @defgroup FsmRunTimeContextRejected Function for managing rejected nodes - */ - - /** - * @ingroup FsmRunTimeContextRejected - * @brief Add a node as rejected in this context - */ - void addRejectedNode(NodePtr node); - - /** - * @ingroup FsmRunTimeContextRejected - * @brief get the rejected nodes of this context - */ - std::set<NodePtr> getRejectedNodes(void); - - - /** - * @defgroup FsmRunTimeContextTest Function for test the context - */ - - /** - * @ingroup FsmRunTimeContextTest - * @brief test if the actual state is valide - * @return bool - */ - bool isOnValidState(void); - /** - * @ingroup FsmRunTimeContextTest - * @brief test if the node is considered as common in this context - * @param node node to test - * @return bool - */ - bool isCommonDefined(NodePtr node); - /** - * @ingroup FsmRunTimeContextTest - * @brief test if has already validated in this context - * @param node node to test - * @return bool - */ - bool isAlreadyValid(NodePtr node); - /** - * @ingroup FsmRunTimeContextTest - * @brief test if this context is compatible with an others - * @details to say that two contexts are compatible is to check : - * that the contexts do not validate the same nodes (other than the common ones) - * and that the common ones have the same idx - * @param fsmContext the others context - * @return bool - */ - bool areCompatible(std::shared_ptr<FsmRunTimeContext> fsmContext); - /** - * @ingroup FsmRunTimeContextTest - * @brief test if this context is strictly equal with an others - * @param fsmContext the others context - * @return bool - */ - bool areEqual(std::shared_ptr<FsmRunTimeContext> fsmContext); - - /** - * @defgroup FsmRunTimeContextSet Function set context - */ - - - void setCommon(NodePtr node,std::size_t commonIdx); - - - void setValid(NodePtr node,std::shared_ptr<ConditionalInterpreter> tag); - - /** - * @defgroup FsmRunTimeContextGet Function get context - */ - - - /** - * @ingroup FsmRunTimeContextGet - * @brief get the sub idx state - * @return bool - */ - std::size_t getSubStmId(void); - - NodePtr getCommonNodeFromIdx(std::size_t commonIdx); - std::size_t getCommonNodeIdx(NodePtr node); - std::set<NodePtr> getCommonNodes(void); - - std::map<NodePtr,std::size_t> getCommon(void); - std::set<NodePtr> getValidNodes(void); - - std::set<NodePtr> getValidNodesNoCommon(void); - std::map<std::shared_ptr<ConditionalInterpreter>,std::set<NodePtr>>& getValid(void); - - - NodePtr getActNode(void); - std::shared_ptr<FsmNode> getActState(void); - - - /** - * @defgroup FsmRunTimeContextMem - */ - - void rst(void); - - - }; - -} - -#endif //AIDGE_CORE_FSM_RUN_TIME_CONTEXT_H_ + + + void setCommon(NodePtr node,std::size_t commonIdx); + + + void setValid(NodePtr node,std::shared_ptr<ConditionalInterpreter> tag); + + /** + * @defgroup FsmRunTimeContextGet Function get context + */ + + + /** + * @ingroup FsmRunTimeContextGet + * @brief get the sub idx state + * @return bool + */ + std::size_t getSubStmId(void); + + NodePtr getCommonNodeFromIdx(std::size_t commonIdx); + std::size_t getCommonNodeIdx(NodePtr node); + std::set<NodePtr> getCommonNodes(void); + + std::map<NodePtr,std::size_t> getCommon(void); + std::set<NodePtr> getValidNodes(void); + + std::set<NodePtr> getValidNodesNoCommon(void); + std::map<std::shared_ptr<ConditionalInterpreter>,std::set<NodePtr>>& getValid(void); + + + NodePtr getActNode(void); + std::shared_ptr<FsmNode> getActState(void); + + + /** + * @defgroup FsmRunTimeContextMem + */ + + void rst(void); + + +}; +} // namespace Aidge + +#endif // AIDGE_CORE_FSM_RUN_TIME_CONTEXT_H_ diff --git a/include/aidge/graphRegex/matchFsm/MatchResult.hpp b/include/aidge/graphRegex/matchFsm/MatchResult.hpp index 4f7f9bf1dd9b0612e71a1f7894bfc382713c0ad0..7954e932a20940946f444cf7277e2bf359f7f15a 100644 --- a/include/aidge/graphRegex/matchFsm/MatchResult.hpp +++ b/include/aidge/graphRegex/matchFsm/MatchResult.hpp @@ -24,8 +24,10 @@ private: const std::vector<NodePtr> mStartNode; public: + MatchSolution() = delete; MatchSolution(std::vector<std::shared_ptr<FsmRunTimeContext>>& precedence,const std::string query,const std::vector<NodePtr> startNode); - inline const std::set<NodePtr>& at(const std::string key) { + + inline const std::set<NodePtr>& at(const std::string& key) { return mSolution[key]; } const std::set<NodePtr> getAll(); @@ -33,7 +35,6 @@ public: inline const std::string& getQuery() const noexcept { return mQueryFrom; } inline const std::vector<NodePtr>& getStartNode() const noexcept { return mStartNode; } - }; @@ -60,14 +61,18 @@ private: public: - MatchResult(std::vector<std::shared_ptr<FsmRunTimeContext>> allValid, std::size_t nbSubStm, - const std::string& query,const std::vector<NodePtr>& startNodes); + MatchResult() = delete; + MatchResult(std::vector<std::shared_ptr<FsmRunTimeContext>> allValid, + std::size_t nbSubStm, + const std::string& query,const std::vector<NodePtr>& startNodes); /** * @brief get the set of the node match for une expression * @return the set of node of the graph that corresponding to an expression */ - std::shared_ptr<MatchSolution> getBiggerSolution(void); + inline std::shared_ptr<MatchSolution> getBiggerSolution(void) const noexcept { + return mSolve.empty() ? nullptr : mSolve[0]; + } inline std::vector<std::shared_ptr<MatchSolution>> getSolutions(void) const noexcept { return mSolve; diff --git a/include/aidge/recipies/GraphViewHelper.hpp b/include/aidge/recipies/GraphViewHelper.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d7bcec713087054640c87c6fd229fee53d1ed4a6 --- /dev/null +++ b/include/aidge/recipies/GraphViewHelper.hpp @@ -0,0 +1,40 @@ +/******************************************************************************** + * Copyright (c) 2023 CEA-List + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + ********************************************************************************/ + +#ifndef AIDGE_CORE_UTILS_RECIPIES_H_ +#define AIDGE_CORE_UTILS_RECIPIES_H_ + +#include <memory> +#include <set> + +#include "aidge/graph/Node.hpp" +#include "aidge/graph/GraphView.hpp" + + +namespace Aidge { + +/** + * @brief Getter for every Producer operator in a GraphView. + * @param graphview GraphView instance where Producers should be searched. + * @return std::set<std::shared_ptr<Node>> + */ +std::set<std::shared_ptr<Aidge::Node>> producers(std::shared_ptr<Aidge::GraphView> graphview) { + std::set<std::shared_ptr<Node>> res; + const std::set<std::shared_ptr<Node>> nodes = graphview->getNodes(); + + std::copy_if(nodes.cbegin(), + nodes.cend(), + std::inserter(res, res.begin()), + [](std::shared_ptr<Node> n){ return n->type() == "Producer"; }); + + return res; +} +} // namespace Aidge \ No newline at end of file diff --git a/python_binding/graphRegex/pybind_GraphRegex.cpp b/python_binding/graphRegex/pybind_GraphRegex.cpp index be3cd9e9124ba1306226dcbdc13ee39748cf0606..921f204d017f90823b9c4a1a024efa271a4691e5 100644 --- a/python_binding/graphRegex/pybind_GraphRegex.cpp +++ b/python_binding/graphRegex/pybind_GraphRegex.cpp @@ -10,6 +10,7 @@ ********************************************************************************/ #include <pybind11/pybind11.h> +#include <pybind11/functional.h> #include "aidge/graphRegex/GraphRegex.hpp" namespace py = pybind11; @@ -20,7 +21,7 @@ void init_GraphRegex(py::module& m){ py::class_<GraphRegex, std::shared_ptr<GraphRegex>>(m, "GraphRegex", "GraphRegex class describes a regex to test a graph.") .def(py::init<>()) - .def("add_query", &GraphRegex::addQuery, R"mydelimiter( + .def("add_query", &GraphRegex::addQuery, py::arg("query"), py::arg("f") = nullptr, R"mydelimiter( :rtype: str )mydelimiter") @@ -47,10 +48,10 @@ void init_GraphRegex(py::module& m){ Add a node test :param key: the key of the node test to use in the query. :param conditionalExpressions: the test to do . - + )mydelimiter") - + .def("set_node_key", (void (GraphRegex::*)(const std::string, std::function<bool(NodePtr)>)) & GraphRegex::setNodeKey, @@ -59,7 +60,7 @@ void init_GraphRegex(py::module& m){ Add a node test :param key: the key of the lambda test to use in the conditional expressions. :param f: bool lambda (nodePtr) . - + )mydelimiter") diff --git a/python_binding/graphRegex/pybind_MatchSolution.cpp b/python_binding/graphRegex/pybind_MatchSolution.cpp new file mode 100644 index 0000000000000000000000000000000000000000..81d39f86ed6da5b7b63a2d43b3a4fcbb2f8e9043 --- /dev/null +++ b/python_binding/graphRegex/pybind_MatchSolution.cpp @@ -0,0 +1,40 @@ +/******************************************************************************** + * Copyright (c) 2023 CEA-List + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + ********************************************************************************/ + +#include <pybind11/pybind11.h> +#include <pybind11/stl.h> +#include "aidge/graphRegex/matchFsm/MatchResult.hpp" + +namespace py = pybind11; +namespace Aidge { +void init_MatchSolution(py::module& m){ + + + py::class_<MatchSolution, std::shared_ptr<MatchSolution>>(m, "MatchSolution", "MatchSolution class contains the result of one match and the associated key, the query and the start node.") + .def("at", &MatchSolution::at, py::arg("key"), + R"mydelimiter( + :rtype: str + )mydelimiter") + + .def("get_all", &MatchSolution::getAll, + R"mydelimiter( + )mydelimiter") + + .def("get_query", &MatchSolution::getQuery, + R"mydelimiter( + )mydelimiter") + + .def("get_start_node", &MatchSolution::getStartNode, + R"mydelimiter( + )mydelimiter") + ; +} +} // namespace Aidge diff --git a/python_binding/pybind_core.cpp b/python_binding/pybind_core.cpp index 0353953fda39cd6dc283d20a0a3e36659dd891a4..be0d357b7f73e26aad44994f407696f70617ad71 100644 --- a/python_binding/pybind_core.cpp +++ b/python_binding/pybind_core.cpp @@ -56,6 +56,7 @@ void init_OpArgs(py::module&); void init_Connector(py::module&); void init_GraphRegex(py::module&); +void init_MatchSolution(py::module&); void init_Recipies(py::module&); @@ -106,7 +107,9 @@ void init_Aidge(py::module& m){ init_Identity(m); init_Producer(m); + init_GraphRegex(m); + init_MatchSolution(m); init_Recipies(m); init_Scheduler(m); diff --git a/src/graphRegex/matchFsm/FsmRunTimeContext.cpp b/src/graphRegex/matchFsm/FsmRunTimeContext.cpp index ddf6a46cc7c75dc853d71ba98b051b4263a31164..7a09908e5629e299b6b264fbfaac97bdaf7fa316 100644 --- a/src/graphRegex/matchFsm/FsmRunTimeContext.cpp +++ b/src/graphRegex/matchFsm/FsmRunTimeContext.cpp @@ -1,7 +1,7 @@ #include "aidge/graphRegex/matchFsm/FsmRunTimeContext.hpp" #include "aidge/graphRegex/matchFsm/FsmNode.hpp" -using namespace Aidge; +using namespace Aidge; std::vector<std::set<NodePtr>> FsmRunTimeContext::mRejectedNodes; @@ -42,10 +42,6 @@ void FsmRunTimeContext::addRejectedNode(NodePtr node){ mRejectedNodes[mLocalIdxRejeced].insert(node); } -std::set<NodePtr> FsmRunTimeContext::getRejectedNodes(void){ - return mRejectedNodes[mLocalIdxRejeced]; -} - bool FsmRunTimeContext::isOnValidState(void){ return mActState->isValid(); } @@ -57,7 +53,7 @@ bool FsmRunTimeContext::isCommonDefined(NodePtr node){ for(const auto& nodeC : nodes){ if(nodeC.get() == node.get()){ return true; - } + } } return false; } @@ -68,7 +64,7 @@ bool FsmRunTimeContext::isAlreadyValid(NodePtr node){ for(const auto& nodeV : nodes){ if(nodeV.get() == node.get()){ return true; - } + } } return false; @@ -82,7 +78,7 @@ bool FsmRunTimeContext::areCompatible(std::shared_ptr<FsmRunTimeContext> fsmCont and the same idx for the common */ - //common node + //common node for (const auto& ref : getCommon()) { for (const auto& test : fsmContext->getCommon()) { @@ -97,20 +93,15 @@ bool FsmRunTimeContext::areCompatible(std::shared_ptr<FsmRunTimeContext> fsmCont //valid nodes std::set<NodePtr> commonElements; - std::set<NodePtr> A = getValidNodesNoCommon(); - std::set<NodePtr> B = fsmContext->getValidNodesNoCommon(); + std::set<NodePtr> A = getValidNodesNoCommon(); + std::set<NodePtr> B = fsmContext->getValidNodesNoCommon(); std::set_intersection( A.begin(),A.end(), B.begin(), B.end(), std::inserter(commonElements, commonElements.end()) ); - - if (!commonElements.empty()) { - return false; - } - - return true; + return (commonElements.empty()) ? true : false; } bool FsmRunTimeContext::areEqual(std::shared_ptr<FsmRunTimeContext> fsmContext){ @@ -142,7 +133,7 @@ void FsmRunTimeContext::setCommon(NodePtr node,std::size_t commonIdx){ } void FsmRunTimeContext::setValid(NodePtr node,std::shared_ptr<ConditionalInterpreter> tag){ - //we already find a node of this type + //we already find a node of this type if(mValidNodes.find(tag) != mValidNodes.end()){ if(isAlreadyValid(node) && !isCommonDefined(node) ){ throw std::runtime_error("setValid you valid tow time"); @@ -151,7 +142,7 @@ void FsmRunTimeContext::setValid(NodePtr node,std::shared_ptr<ConditionalInterpr }else{ mValidNodes[tag] = {node}; } - + } std::size_t FsmRunTimeContext::getSubStmId(void){ diff --git a/src/graphRegex/matchFsm/MatchResult.cpp b/src/graphRegex/matchFsm/MatchResult.cpp index 08be00dea66c66a46dbbf2b225efd0df3f332188..99df00e198a9a30be21e0ad18b4933a40b9b7a06 100644 --- a/src/graphRegex/matchFsm/MatchResult.cpp +++ b/src/graphRegex/matchFsm/MatchResult.cpp @@ -132,8 +132,4 @@ void Aidge::MatchResult::_generateCombination( std::size_t idxSubStm, } return; -} - -std::shared_ptr<Aidge::MatchSolution> Aidge::MatchResult::getBiggerSolution(void){ - return mSolve.empty() ? nullptr : mSolve[0]; } \ No newline at end of file