diff --git a/include/aidge/aidge.hpp b/include/aidge/aidge.hpp index bf8bcbca0fc0fe079b2d359c50e5f94f1f515977..3031fc19b335f6e77bb7999f8b3a2b107e3f5323 100644 --- a/include/aidge/aidge.hpp +++ b/include/aidge/aidge.hpp @@ -32,8 +32,6 @@ #include "aidge/graph/Node.hpp" #include "aidge/graph/OpArgs.hpp" -#include "aidge/graphRegex/GraphRegex.hpp" - #include "aidge/filler/Filler.hpp" #include "aidge/nodeTester/ConditionalInterpreter.hpp" diff --git a/include/aidge/graphRegex/GraphFsmInterpreter.hpp b/include/aidge/graphRegex/GraphFsmInterpreter.hpp deleted file mode 100644 index a3336850ef889d079317151aca2cb223f0023dd8..0000000000000000000000000000000000000000 --- a/include/aidge/graphRegex/GraphFsmInterpreter.hpp +++ /dev/null @@ -1,87 +0,0 @@ -/******************************************************************************** - * 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_GRAPH_FSM_INTERPRETER_H_ -#define AIDGE_CORE_GRAPH_FSM_INTERPRETER_H_ - -#include <string> -#include <memory> - -#include "aidge/utilsParsing/AstNode.hpp" -#include "aidge/graphRegex/GraphRegexTypes.hpp" -#include "aidge/graphRegex/GraphParser.hpp" -#include "aidge/graphRegex/matchFsm/FsmGraph.hpp" - -namespace Aidge { - - class GraphFsmInterpreter - { - private: - /* data */ - GraphParser mParser; - std::size_t mActGroupe; - std::map<std::string,std::shared_ptr<ConditionalInterpreter>> mNodesCondition; - - const std::string mGraphMatchExpr; - public: - GraphFsmInterpreter(const std::string graphMatchExpr,std::vector<std::shared_ptr<ConditionalInterpreter>> & nodesCondition); - virtual ~GraphFsmInterpreter() =default; - - - std::shared_ptr<FsmGraph> interpret(void); - - - - private: - - - std::shared_ptr<FsmGraph> visit(std::shared_ptr<AstNode<gRegexTokenTypes>> AstTree); - - /** - * @defgroup graphFsmInterpreterF Functions for interpreting AST nodes - * @brief For each node type in the AST, define how build the FsmGraph - */ - - - /** - * @ingroup graphFsmInterpreterF - * @brief leaf of fsm make the fsm for test one transition - */ - std::shared_ptr<FsmGraph> keyF(std::shared_ptr<AstNode<gRegexTokenTypes>> AstNode); - /** - * @ingroup graphFsmInterpreterF - * @brief combine two fsm of two expression. - */ - std::shared_ptr<FsmGraph> sepF(std::shared_ptr<FsmGraph> leftFsm,std::shared_ptr<FsmGraph> rigthFsm); - /** - * @ingroup graphFsmInterpreterF - * @brief combine two to make a new that match leftFsm next rigthFsm - */ - std::shared_ptr<FsmGraph> nextF(std::shared_ptr<FsmGraph> leftFsm,std::shared_ptr<FsmGraph> rigthFsm); - /** - * @ingroup graphFsmInterpreterF - * @brief make the fsm match + - */ - std::shared_ptr<FsmGraph> qomF(std::shared_ptr<FsmGraph> fsm); - /** - * @ingroup graphFsmInterpreterF - * @brief make the fsm match * - */ - std::shared_ptr<FsmGraph> qzmF(std::shared_ptr<FsmGraph> fsm); - - }; - - - -} - - -#endif // AIDGE_CORE_GRAPH_FSM_INTERPRETER_H_ diff --git a/include/aidge/graphRegex/GraphLexer.hpp b/include/aidge/graphRegex/GraphLexer.hpp deleted file mode 100644 index 8bd534591bc7be98c898f3f486b6df13df840cd9..0000000000000000000000000000000000000000 --- a/include/aidge/graphRegex/GraphLexer.hpp +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef AIDGE_CORE_GRAPH_LEXER_H_ -#define AIDGE_CORE_GRAPH_LEXER_H_ - -#include <string> -#include <memory> -#include <regex> -#include <stdexcept> //error - -#include "aidge/utilsParsing/ParsingToken.hpp" -#include "aidge/graphRegex/GraphRegexTypes.hpp" - -namespace Aidge { - - class GraphLexer - { - - public: - GraphLexer( const std::string gRegexExpressions ); - - /** - * @brief Get the next token on the gRegexExpressions - * @return ConditionalToken - */ - std::shared_ptr<ParsingToken<gRegexTokenTypes>> getNextToken(void); - /** - * @brief Restart at the start of the gRegexExpressions - * - */ - void rstPosition(void); - - /** - * @brief Test if the string is completely read - * @return bool - */ - bool isEnd(void); - - - const std::string getQuery(); - - - /** - * @brief Get the representation of the class - * @return string - */ - const std::string rep(); - - private: - - /** - * @brief Constructs an error message to display the character not understood by the lexer - * @return error message - */ - std::runtime_error badTokenError(const std::string& currentChars,std::size_t position); - - /** - * @brief The expression of the test to be performed on the nodes - */ - const std::string mRegularExpressions; - /** - * @brief The lexer's current position in mConditionalExpressions - */ - std::size_t mPosition; - - }; -} - - - - -#endif //AIDGE_CORE_GRAPH_LEXER_H_ diff --git a/include/aidge/graphRegex/GraphParser.hpp b/include/aidge/graphRegex/GraphParser.hpp deleted file mode 100644 index b165891ff1c8a55e565e3520813b707303ddfd1f..0000000000000000000000000000000000000000 --- a/include/aidge/graphRegex/GraphParser.hpp +++ /dev/null @@ -1,105 +0,0 @@ -#ifndef AIDGE_CORE_GRAPH_PARSER_H_ -#define AIDGE_CORE_GRAPH_PARSER_H_ - - -#include <memory> // for shared_ptr -#include "aidge/graphRegex/GraphLexer.hpp" -#include "aidge/utilsParsing/AstNode.hpp" -#include "aidge/graphRegex/GraphRegexTypes.hpp" - -namespace Aidge{ - -/** - * @brief this class uses the lexer to create an AST according to a set of gramer rules - */ -class GraphParser { - -public: - /** - * @brief AST graph creation function - * @param gRegexExpressions String representing the logical function to be performed - */ - GraphParser(const std::string gRegexExpressions); - - ~GraphParser() noexcept; - - /** - * @brief AST graph creation function - * @return The AST tree - */ - std::shared_ptr<AstNode<gRegexTokenTypes>> parse(void); - - - /** - * @brief get the query that be use in the parsing - * @return query - */ - const std::string getQuery(); - - -private: - /** - * @brief restart at the start of the ConditionalExpressions for LEXER and restart mCurrentToken - */ - void rstParser(void); - - ////////////////// - - /** - * @defgroup ParsingFunctions Function for creating AST - * @brief Functions for recursive construction of the AST representing grammar rules - */ - - /** - * @ingroup ParsingFunctions - * @brief Token reading and verification function - * - */ - void ackToken(gRegexTokenTypes tokenType); - - //TODO TODO - /** - * @ingroup ParsingFunctions - * @brief Function of grammar rules for key : KEY(QOM | QZM)? | CKEY - * @return AST node - */ - std::shared_ptr<AstNode<gRegexTokenTypes>> constructAstExp(void); - - /** - * @ingroup ParsingFunctions - * @brief Function of grammar rules for sequence : seq :exp (NEXT seq)* - * @return AST node - */ - std::shared_ptr<AstNode<gRegexTokenTypes>> constructAstSeq(void); - - /** - * @ingroup ParsingFunctions - * @brief Function of grammar rules for domain : (seq NEXT domain)? | LPAREN domain RPAREN (QOM | QZM) (NEXT domain)? - * @return AST node - */ - std::shared_ptr<AstNode<gRegexTokenTypes>> constructAstDomain(void); - - /** - * @ingroup ParsingFunctions - * @brief Function of grammar rules for multiple exepresion : allExpr: domain (SEP allExpr)* - * @return AST node - */ - std::shared_ptr<AstNode<gRegexTokenTypes>> constructAstAllExpr(void); - - - /** - * @brief The actual token in the parce - */ - std::shared_ptr<ParsingToken<gRegexTokenTypes>> mCurrentToken; - - /** - * @brief The lexem use - */ - GraphLexer mLexer; - -}; - - -} - -#endif //AIDGE_CORE_GRAPH_PARSER_H_ diff --git a/include/aidge/graphRegex/GraphRegex.hpp b/include/aidge/graphRegex/GraphRegex.hpp deleted file mode 100644 index f0f8e68e41a09cb54fb7528cb7f6ce065674af02..0000000000000000000000000000000000000000 --- a/include/aidge/graphRegex/GraphRegex.hpp +++ /dev/null @@ -1,106 +0,0 @@ -#ifndef AIDGE_CORE_GRAPH_REGEX_H_ -#define AIDGE_CORE_GRAPH_REGEX_H_ - -#include <string> - -#include "aidge/graphRegex/matchFsm/MatchResult.hpp" -#include "aidge/graphRegex/matchFsm/FsmGraph.hpp" -#include "aidge/graphRegex/GraphFsmInterpreter.hpp" -#include "aidge/graph/GraphView.hpp" -#include "aidge/graph/Node.hpp" - -namespace Aidge{ - -/** - * @brief type for recipes function use in query and resolve - */ -using RecipesFunctionType = std::function<void(std::shared_ptr<MatchSolution>)>; - -/** - * @brief high level interface for graph matching, used to simplify match definition - */ -class GraphRegex{ - - private: - - //std::vector<std::string> mQuery; - std::vector<std::shared_ptr<ConditionalInterpreter>> mAllTest; - std::map<std::string, std::function<bool(NodePtr)>> mAllLambda; - std::map<std::string,RecipesFunctionType> mQueryRecipe; - - public: - GraphRegex(){}; - virtual ~GraphRegex() = default; - - /** - * @brief add a topology query to the match - * @param query the topology query to find - **/ - //void addQuery(const std::string query); - - /** - * @brief add a topology query to the match and a function for recipe - * @param query the topology query to find - * @param f the funct - **/ - void addQuery(const std::string query,RecipesFunctionType f = nullptr); - - - /** - * @brief get all the types of a graph and set it as type key in the query - * @param Reference graph use to get all the node types - **/ - void setKeyFromGraph(std::shared_ptr<GraphView> ref); - - /** - * @brief set a node test manually - * @param key the ref of this test used in the query - * @param ConditionalExpressions expression to test the node - **/ - void setNodeKey(const std::string key, const std::string conditionalExpressions ); - - /** - * @brief set a specific lambda that can be used in setQueryKey - * @param key ref to the lambda to use in the - * @param f expression to test the node ConditionalExpressions - **/ - void setNodeKey(const std::string key,std::function<bool(NodePtr)> f); - - /** - * @brief brief match the queries in the graph - * @param ref the graph were the queries in search - * @return the result - */ - std::set<std::shared_ptr<MatchSolution>> match(std::shared_ptr<GraphView> ref); - - /*** - * @brief match the queries in the graph and applied the recipes function - * @param ref the graph were the queries in search - */ - void appliedRecipes(std::shared_ptr<GraphView> ref); - - private: - - void _generateCombinationsStart(const std::set<NodePtr>& elements, std::size_t n, std::size_t index, - std::vector<NodePtr>& current, std::set<std::vector<NodePtr>>& combinations); - - - - void _findLargestCompatibleSet( - const std::vector<std::shared_ptr<MatchSolution>>& solutions, - std::set<std::shared_ptr<MatchSolution>>& currentSet, - std::set<std::shared_ptr<MatchSolution>>& largestSet, - size_t currentIndex - ); - - std::set<std::shared_ptr<MatchSolution>> _findLargestCompatibleSet( - const std::vector<std::shared_ptr<MatchSolution>>& solutions - ); - - void _majConditionalInterpreterLambda(); - -}; -} - - -#endif //AIDGE_CORE_GRAPH_REGEX_H_ \ No newline at end of file diff --git a/include/aidge/graphRegex/GraphRegexTypes.hpp b/include/aidge/graphRegex/GraphRegexTypes.hpp deleted file mode 100644 index 9e35f8f027eb363b71358922ffe0caa4a55fff1d..0000000000000000000000000000000000000000 --- a/include/aidge/graphRegex/GraphRegexTypes.hpp +++ /dev/null @@ -1,29 +0,0 @@ - -#ifndef AIDGE_CORE_GREGEX_TOKEN_TYPES_H_ -#define AIDGE_CORE_GREGEX_TOKEN_TYPES_H_ - - -namespace Aidge { - /** - * @brief enum for all types of token use in the of the regex - * 7-5 type - * 4-0 id - */ - enum class gRegexTokenTypes - { - STOP, - NEXT, /**< -> */ - - QOM, /**< + */ - QZM, /**< * */ - - KEY, /**< [A-Za-z_0-9]+ */ - CKEY, /**< [A-Za-z_0-9]+#[0-9]* */ - - SEP, /**< \( */ - LPAREN, /**< \( */ - RPAREN, /**< \) */ - }; - -} -#endif //AIDGE_CORE_GREGEX_TOKEN_TYPES_H_ diff --git a/include/aidge/graphRegex/GraphStrInterpreter.hpp b/include/aidge/graphRegex/GraphStrInterpreter.hpp deleted file mode 100644 index 4c7be546ef9c47619600fcb849e6bed99835991d..0000000000000000000000000000000000000000 --- a/include/aidge/graphRegex/GraphStrInterpreter.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef AIDGE_CORE_GRAPH_FSM_INTERPRETER_H_ -#define AIDGE_CORE_GRAPH_FSM_INTERPRETER_H_ - -#include <memory> -#include <algorithm> - -#include "aidge/utilsParsing/AstNode.hpp" -#include "aidge/graphRegex/GraphRegexTypes.hpp" -#include "aidge/graphRegex/GraphParser.hpp" -#include "aidge/graphRegex/matchFsm/FsmGraph.hpp" - -namespace Aidge { - - class GraphStrInterpreter - { - private: - /* data */ - GraphParser mParser; - std::string mToTest; - public: - GraphStrInterpreter(const std::string graphMatchExpr); - virtual ~GraphStrInterpreter() =default; - - - std::string interpret(void); - - private: - - - std::string visit(std::shared_ptr<AstNode<gRegexTokenTypes>> AstTree); - }; - - - -} - - -#endif //AIDGE_CORE_GRAPH_FSM_INTERPRETER_H_ diff --git a/include/aidge/graphRegex/matchFsm/FsmEdge.hpp b/include/aidge/graphRegex/matchFsm/FsmEdge.hpp deleted file mode 100644 index 2eadd27e86507311837a9eb5f3c4dc0cfe46e296..0000000000000000000000000000000000000000 --- a/include/aidge/graphRegex/matchFsm/FsmEdge.hpp +++ /dev/null @@ -1,253 +0,0 @@ -/******************************************************************************** - * 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_FSM_EDGE_H_ -#define AIDGE_CORE_FSM_EDGE_H_ - -#include <memory> -#include <set> -#include <string> - -#include "aidge/nodeTester/ConditionalInterpreter.hpp" - - -namespace Aidge{ - - class FsmNode; - class FsmRunTimeContext; - - struct EdgeTestResult { - bool success; - std::set<NodePtr> node; - }; - - /** - * @brief virtual class use test the node on the node to validate - */ - class FsmEdge: public std::enable_shared_from_this<FsmEdge> - { - private: - - /** - * @brief the relative position to this test relative to all the const key - * first is common id, second is the relative position - */ - std::map<size_t,int> mRelativePos; - /** - * @brief the ptr on the source node - */ - std::shared_ptr<FsmNode> mNodeSource; - /** - * @brief the ptr on the dest node - */ - std::shared_ptr<FsmNode> mNodeDest; - /** - * @brief the weak ptr - */ - std::weak_ptr<FsmEdge> weakPtr; - - public: - FsmEdge(std::shared_ptr<FsmNode>& source,std::shared_ptr<FsmNode>& dest, const std::shared_ptr<ConditionalInterpreter> toTest); - - virtual ~FsmEdge(){}; - - FsmEdge() : weakPtr(shared_from_this()) {} - - - /** - * @brief test is the validation of the node, it must be defined for all types of edge - * it takes as argument an FSM traversal context and returns a set of next nodes - * @return set of next node or nullptr if not next - */ - - virtual const EdgeTestResult test(const std::shared_ptr<FsmRunTimeContext> stmContext) =0; - - /** - * @brief test is the edge test a common node - * @return true if is a common - */ - virtual bool isCommon(void); - /** - * @brief get the Common idx of the common test in this edge (if is a common edge) - * @return idx of the common - */ - virtual size_t getCommonIdx(void); - /** - * @brief get the relative position to the common node define in this edge - * @return map - */ - const std::map<size_t,int>& getRelative(void); - /** - * @brief add new relative position - */ - void updateRelative( const std::map<size_t,int>& relativePos ); - /** - * @brief get source FsmNode - * @return FsmNode - */ - std::shared_ptr<FsmNode> getSourceNode(void); - /** - * @brief set a new source to the edge - * @return FsmNode - */ - void reSetSourceNode(const std::shared_ptr<FsmNode>& newSource); - /** - * @brief get dest FsmNode - * @return FsmNode - */ - std::shared_ptr<FsmNode> getDestNode(void); - /** - * @brief set a new dest to the edge - * @return FsmNode - */ - void reSetDestNode(const std::shared_ptr<FsmNode>& newDest); - /** - * @brief propagate the edge mRelativePos to the others Edge and recalcul the relative position - */ - void propagateRelativePos(void); - - /** - * @brief test to make on the node to validate - * @see ConditionalInterpreter - */ - const std::shared_ptr<ConditionalInterpreter> mToTest; - - /** - * @brief update week ptr for the node, TODO best - */ - void updateWeak(void); - }; - - /** - * @brief class specialization for not common node (node that must be match one Unique) transition - */ - class FsmEdgeUnique:public FsmEdge - { - - public: - FsmEdgeUnique(std::shared_ptr<FsmNode>& source,std::shared_ptr<FsmNode>& dest, const std::shared_ptr<ConditionalInterpreter> toTest); - const EdgeTestResult test(const std::shared_ptr<FsmRunTimeContext> stmContext) override; - }; - - /** - * @brief class specialization for common node transition - * @see FsmEdge - */ - class FsmEdgeCommon:public FsmEdge - { - - private: - /** - * @brief the map that define the relation between the commonKey find by the lexer and a unique id use to refer to the common node - */ - static std::map<std::string,int> mCommonIdxMap; - /** - * @brief the common id test in this transition - */ - int mCommonIdx; - public: - - /** - * @brief constructor common node , - * @details during construction, - * the node key found by the lexer is converted to a unique id and the relative positions are updated. - */ - FsmEdgeCommon(std::shared_ptr<FsmNode>& source,std::shared_ptr<FsmNode>& dest, const std::shared_ptr<ConditionalInterpreter> toTest, const std::string commonKey); - // ~FsmEdgeCommon() override {} - const EdgeTestResult test(const std::shared_ptr<FsmRunTimeContext> stmContext) override; - bool isCommon(void) override; - - }; - - - - /** - * @brief class specialization for ref transition - * @see FsmEdge - */ - class FsmEdgeRef:public FsmEdge - { - private: - /** - * @brief the id of one common node that we use as an anchor - */ - const int mRefCommonIdx; - /** - * @brief the delta in terme of child or parent refer to the anchor - */ - const int mdeltaCommonIdx; - public: - FsmEdgeRef(std::shared_ptr<FsmNode>& source,std::shared_ptr<FsmNode>& dest, const size_t refCommonIdx,const int deltaCommonIdx); - //~FsmEdgeRef() override {} - const EdgeTestResult test(const std::shared_ptr<FsmRunTimeContext> stmContext) override; - - }; - - /** - * @brief class specialization for ref empty transition - * @see FsmEdge - */ - class FsmEdgeEmpty:public FsmEdge - { - - public: - FsmEdgeEmpty(std::shared_ptr<FsmNode> source,std::shared_ptr<FsmNode> dest); - //~FsmEdgeEmpty() override {} - const EdgeTestResult test(const std::shared_ptr<FsmRunTimeContext> stmContext) override; - - }; - - - /** - * @brief class specialization for ref empty transition - * @see FsmEdge - */ - class FsmEdgeNone:public FsmEdge - { - - public: - FsmEdgeNone(std::shared_ptr<FsmNode> source,std::shared_ptr<FsmNode> dest); - const EdgeTestResult test(const std::shared_ptr<FsmRunTimeContext> /*stmContext*/) override; - - }; - - - -//////////////////////// -// FACTORY -//////////////////////// - -enum class FsmEdgeTypes { - EMPTY = 0, - REF, - COMMON, - UNIQUE -}; - - -class FsmEdgeFactory { - public: - /** - * @brief factory for making edge and read the info in the lexeme of the token - * @param source source node of the edge - * @param dest Dest node of the edge - * @param type type of the edge - * @param lexeme the additional information to build the edge - * @return s prt of the edge - */ - static std::shared_ptr<FsmEdge> make(std::shared_ptr<FsmNode> source, std::shared_ptr<FsmNode> dest, - FsmEdgeTypes type,std::map<std::string, std::shared_ptr<ConditionalInterpreter>> allTest, - const std::string lexeme = ""); - }; - -} - -#endif //AIDGE_CORE_FSM_EDGE_H_ diff --git a/include/aidge/graphRegex/matchFsm/FsmGraph.hpp b/include/aidge/graphRegex/matchFsm/FsmGraph.hpp deleted file mode 100644 index e7402b3f0973e4b9e7053b4d59c9ff63ca6dd496..0000000000000000000000000000000000000000 --- a/include/aidge/graphRegex/matchFsm/FsmGraph.hpp +++ /dev/null @@ -1,109 +0,0 @@ - -#ifndef AIDGE_CORE_FSM_GRAPH_H_ -#define AIDGE_CORE_FSM_GRAPH_H_ - -#include <set> -#include <vector> -#include <memory> -#include <stdexcept> //error - -#include "aidge/graphRegex/matchFsm/FsmNode.hpp" -#include "aidge/graphRegex/matchFsm/FsmEdge.hpp" -#include "aidge/graphRegex/matchFsm/MatchResult.hpp" -namespace Aidge{ - - - -class FsmGraph -{ -private: - /** - * @brief all node Origin - */ - std::set<std::size_t> mAllOrigin; - std::set<std::shared_ptr<FsmEdge>> mEdges; - - - const std::string mQuery; - -public: - - FsmGraph(const std::string query); - virtual ~FsmGraph() = default; - - std::vector<std::shared_ptr<MatchSolution>> test(const std::vector<NodePtr>& StartNodes); - - - - const std::set<std::shared_ptr<FsmEdge>>& getEdge(void); - /** - * @brief add edge in the graph, as FsmEdge know the source and dest FsmNode these nodes are also add to the graph - */ - void addEdge(std::shared_ptr<FsmEdge>& edge); - - /** - * @brief get the list of the starting states - * @details we need to use a vector because the order of the nodes is important for start node initialization \ref test() - */ - const std::vector<std::shared_ptr<FsmNode>> getStartNodes(void); - - /** - * @brief get the set of the valid states - * @return set of valid state - */ - const std::set<std::shared_ptr<FsmNode>> getValidNodes(void); - - /** - * @brief get the set of all the node in the graph - * @return set of all nodes - */ - const std::set<std::shared_ptr<FsmNode>> getNodes(void); - - /** - * @brief set a group idx for all the nodes in the graph - */ - void setGroupe(std::size_t groupeIdx); - - /** - * @brief make the union between this graph and an input graph - * @param fsmGraph graph to union - */ - void unionG(const std::shared_ptr<FsmGraph> fsmGraph); - - - /** - * @brief make the union between this graph and an input graph and merge the valid state to the start state - * @param fsmGraph graph to merge - */ - void mergeOneStartOneValid(const std::shared_ptr< FsmGraph> fsmGraph); - /** - * @brief get the number of sub FSM - * @return number of sub Fsm - */ - std::size_t getNbSubFsm(void); - - /** - * @brief get the number of start state - * @return number of start state - */ - std::size_t getNbStart(void); - - /** - * @brief increment the origin of all nodes in the graph - * @param incr value - */ - void incOriginAllNodeBy(std::size_t incr); - - private: - - /** - * @brief merge tow node of the graph - * @param node - */ - void _mergeNode(std::shared_ptr<FsmNode> source,std::shared_ptr<FsmNode> dest); - -}; - - -} -#endif //AIDGE_CORE_FSM_GRAPH_H_ diff --git a/include/aidge/graphRegex/matchFsm/FsmNode.hpp b/include/aidge/graphRegex/matchFsm/FsmNode.hpp deleted file mode 100644 index c7a161beebc1d10735e56b491393fd0f8966f3c8..0000000000000000000000000000000000000000 --- a/include/aidge/graphRegex/matchFsm/FsmNode.hpp +++ /dev/null @@ -1,110 +0,0 @@ -/******************************************************************************** - * 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_FSM_NODE_H_ -#define AIDGE_CORE_FSM_NODE_H_ - -#include <set> -#include <vector> -#include <memory> - -//#include "graphRegex/matchFsm/FsmEdge.hpp" -//#include "graphRegex/matchFsm/FsmRunTimeContext.hpp" - -namespace Aidge{ - // Forward declaration of the class defined in graphRegex/matchFsm/FsmEdge.hpp - class FsmEdge; - struct EdgeTestResult; - class FsmRunTimeContext; - - - //------------------------------------------------------------------------------ - - // MAY BE IN UTILE - template <typename T> - struct lex_compare { - bool operator() (const std::weak_ptr<T> &lhs, const std::weak_ptr<T> &rhs)const { - auto lptr = lhs.lock(), rptr = rhs.lock(); - if (!rptr) return false; // nothing after expired pointer - if (!lptr) return true; - return lptr < rptr; - } - }; - - /** - * @brief is a node in the FSM graph, it's a state in the FSM - * @details a state can be and/or : - * - a valid state, the match is valid if it stop on this edge - * - a start state , the match start on this state - * The state is also define by this Origin (is the unique id of it's expretion ) - * and it's group (for inner expression TODO) - */ - class FsmNode : public std::enable_shared_from_this<FsmNode> - { - private: - /** - * @brief the edge of the node - * @details the edge have a shared ref to the node so we use weak ref - */ - std::set<std::weak_ptr<FsmEdge>,lex_compare<FsmEdge>> mEdges; - /** - * @brief the parent of the node - */ - std::set<std::weak_ptr<FsmNode>,lex_compare<FsmNode>> mParents; - - std::size_t mOriginFsm = 0; - std::size_t mGroupeFsm = 0; - - bool mIsAValid; - bool mIsAStart; - - public: - FsmNode(bool isAValid,bool isAStart ); - virtual ~FsmNode() = default; - /** - * @brief use to MAG the actual context , and return all the possible new context - * @details one input context can generate a multitude of contexts because a graph node - * can have more than one child, and each traversal possibility is a new context. - * @param actContext the actual context - * @return A vector of all the new context - */ - const std::vector<std::shared_ptr<FsmRunTimeContext>> test( std::shared_ptr<FsmRunTimeContext>); - - - std::size_t getOrigin(void); - void incOrigin(std::size_t inc); - - - void rmEdge(std::shared_ptr<FsmEdge>); - void addEdge(std::shared_ptr<FsmEdge>); - - //const std::set<std::shared_ptr<FsmNode>> getChildNodes(void); - - const std::set<std::weak_ptr<FsmNode>,lex_compare<FsmNode>>& getParentNodes(void); - const std::set<std::weak_ptr<FsmEdge>,lex_compare<FsmEdge>>& getEdges(void); - - void setGroupe(std::size_t groupeIdx); - - bool isValid(void); - bool isStart(void); - void invalid(void); - void valid(void); - void unStart(void); - void start(void); - - - - void addParent(std::shared_ptr<FsmNode>); - void rmParent(std::shared_ptr<FsmNode>); - }; - -} -#endif //AIDGE_CORE_FSM_NODE_H_ diff --git a/include/aidge/graphRegex/matchFsm/FsmRunTimeContext.hpp b/include/aidge/graphRegex/matchFsm/FsmRunTimeContext.hpp deleted file mode 100644 index 0b44172be0c3b671043fda884efadb84ba46e215..0000000000000000000000000000000000000000 --- a/include/aidge/graphRegex/matchFsm/FsmRunTimeContext.hpp +++ /dev/null @@ -1,171 +0,0 @@ -#ifndef AIDGE_CORE_FSM_RUN_TIME_CONTEXT_H_ -#define AIDGE_CORE_FSM_RUN_TIME_CONTEXT_H_ - -#include <memory> -#include <vector> -#include <set> -#include <algorithm> - -#include "aidge/nodeTester/ConditionalInterpreter.hpp" -#include "aidge/graph/Node.hpp" - - -namespace Aidge{ - -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 valid 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 undefined - */ - 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 - */ - - /** - * @ingroup FsmRunTimeContextTest - * @brief test if the actual state is valid - * @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); - - -}; -} // 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 deleted file mode 100644 index 7954e932a20940946f444cf7277e2bf359f7f15a..0000000000000000000000000000000000000000 --- a/include/aidge/graphRegex/matchFsm/MatchResult.hpp +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef AIDGE_CORE_MATCH_RESULT_H_ -#define AIDGE_CORE_MATCH_RESULT_H_ - -#include <cstddef> -#include <map> -#include <memory> -#include <string> -#include <set> -#include <vector> - -#include "aidge/graphRegex/matchFsm/FsmRunTimeContext.hpp" -#include "aidge/graph/Node.hpp" - -namespace Aidge{ - -/** - * @brief contained the result of one match and the associate key , the query and the start node -*/ - -class MatchSolution{ -private: - std::map<std::string, std::set<NodePtr>> mSolution; - const std::string mQueryFrom; - 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) { - return mSolution[key]; - } - const std::set<NodePtr> getAll(); - bool areCompatible(std::shared_ptr<MatchSolution> solution); - - inline const std::string& getQuery() const noexcept { return mQueryFrom; } - inline const std::vector<NodePtr>& getStartNode() const noexcept { return mStartNode; } -}; - - -/** - * @brief class that old the result of a matching - * give access to all node and there tag in the expression -*/ -class MatchResult -{ -private: - /* data */ - std::vector<std::shared_ptr<FsmRunTimeContext>> mAllValid; - - /* - the Run time of each sub FSM , to have a valid match we need a set of one run time per FSM compatible - the id must be continue - */ - std::vector<std::vector<std::shared_ptr<FsmRunTimeContext>>> mIdToRunTime; - - std::vector<std::shared_ptr<MatchSolution>> mSolve; - - std::size_t mNbSubStm; - - - -public: - 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 - */ - 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; - } - -private: - -/** - * @brief recurrent function use to init mSolve in the constructor - * - **/ -void _generateCombination( std::size_t idxSubStm, std::vector<std::shared_ptr<FsmRunTimeContext>>& precedence,const std::string& query,const std::vector<NodePtr>& startNodes); - -}; - - -} - - -#endif //AIDGE_CORE_MATCH_RESULT_H_ diff --git a/include/aidge/nodeTester/ConditionalData.hpp b/include/aidge/nodeTester/ConditionalData.hpp deleted file mode 100644 index c6c521bd9c3e1a0333bb2a6c38545bb2bf6f3fe6..0000000000000000000000000000000000000000 --- a/include/aidge/nodeTester/ConditionalData.hpp +++ /dev/null @@ -1,98 +0,0 @@ - -#ifndef AIDGE_CORE_CONDITIONAL_DATA_H_ -#define AIDGE_CORE_CONDITIONAL_DATA_H_ - -#include <vector> -#include <string> -#include <stdexcept> //error -#include <memory> -#include <map> -namespace Aidge{ - - - -///////////////////////// -// The data type in AST Interpretation -//////////////////////// - -class BaseConditionalValue { -public: - virtual ~BaseConditionalValue() {} -}; - -template <typename T> -class ConditionalValue : public BaseConditionalValue { -public: - ConditionalValue(const T& data) : value(data) {} - T value; -}; - - -struct ConditionalData { - /** - * @brief generic type to propagate all the different values in the AST interpretation - */ - //void* value; - std::unique_ptr<BaseConditionalValue> value; - const std::type_info* type =nullptr; - - ///////////////////////////////// - // - //////////////////////////////// - /** - * @brief set a value - */ - template <typename T> - void setValue(const T& newValue) { - //make sure that the old value is free - deleteValue(); - value = std::make_unique<ConditionalValue<T>>(newValue); - type = &typeid(T); - } - - /** - * @brief get the actual value - * @details recaste the value to the templaited type and checks that the conversion type is compatible with type - * @tparam the type of the return value - * @return the value - */ - template <typename T> - T getValue() const { - if (type && *type == typeid(T)) { - //const Value<T>* typedValue = dynamic_cast<const Value<T>*>(static_cast<const BaseValue*>(value)); - const ConditionalValue<T>* typedValue = dynamic_cast<const ConditionalValue<T>*>(value.get()); - if (typedValue) { - return typedValue->value; - } - } - throw std::runtime_error(std::string("DATA ERROR ") + type->name() + " != " + typeid(T).name()); - } - /////////////////////////////////// - // - /////////////////////////////////// - std::string getType() const { - return type ? type->name() : "nullptr"; - } - - - template <typename T> - bool isTypeEqualTo() const { - return (type && *type == typeid(T)); - } - - void deleteValue() { - if (type) { - value.reset(); - type = nullptr; - } - } - - ~ConditionalData() { // TODO best can we have a list of type supported ? - deleteValue(); - } -}; - -} - - -#endif //AIDGE_CORE_CONDITIONAL_DATA_H_ diff --git a/include/aidge/nodeTester/ConditionalInterpreter.hpp b/include/aidge/nodeTester/ConditionalInterpreter.hpp deleted file mode 100644 index 8906aa802b337b508c95ab102c716cf08072207a..0000000000000000000000000000000000000000 --- a/include/aidge/nodeTester/ConditionalInterpreter.hpp +++ /dev/null @@ -1,372 +0,0 @@ -/******************************************************************************** - * 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_CONDITIONAL_INTERPRETER_H_ -#define AIDGE_CORE_CONDITIONAL_INTERPRETER_H_ - -#include "aidge/nodeTester/ConditionalParser.hpp" -#include "aidge/nodeTester/ConditionalData.hpp" - -#include <memory> // for shared_ptr -#include <unordered_map> -#include <functional> -#include "aidge/graph/Node.hpp" - - -namespace Aidge{ - - - -////////////////////////////// -// -///////////////////////////// -/** - * @brief class used to register any lambda function without context, - * it encapsulates the source lambda in a lambda which takes as argument std::shared_ptr<ConditionalData> which are any type. - * @see ConditionalData - */ -class ConditionalRegisterFunction { - ////////////////////////// - //Safe recaste - ////////////////////////// - - /** - * @brief recast the std::shared_ptr<ConditionalData> to the argument type of the lambda - * @tparam T type of the lambda argument - * @see ConditionalData - */ - template <typename T> - T safeCastInput( std::shared_ptr<ConditionalData> data) { - //cnvertion and type checking - if (data->isTypeEqualTo<T>()){ - return data->getValue<T>(); - }else{ - throw std::invalid_argument( "incompatible input type " + data->getType() +" "+ typeid(T).name() ); - } - - } - - - /** - * @brief recaste the output of the lambda to a std::shared_ptr<ConditionalData> - * @tparam T type of the lambda return - * @see ConditionalData - */ - template <typename T> - std::shared_ptr<ConditionalData> safeCastOutput(T data) { - - std::shared_ptr<ConditionalData> out = std::make_shared<ConditionalData>(); - out->setValue<T>(data); - - return out; - } - - - - - ////////////////////// - // get all the type of the function - ////////////////////// - - /** - * @brief Retrieves information about a function's return type and argument types. - * @tparam T The function type. - */ - template <typename T> - struct function_traits; - - - /** - * @brief Specialization of function_traits for function pointers. - * @tparam R The return type of the function. - * @tparam Args The argument types of the function. - */ - template <typename R, typename... Args> - struct function_traits<R (*)(Args...)> { - using return_type = R; - static constexpr std::size_t arity = sizeof...(Args); - - template <std::size_t N> - struct argument { - static_assert(N < arity, "Index out of range."); - using type = typename std::tuple_element<N, std::tuple<Args...>>::type; - }; - }; - - /** - * @brief Specialization of function_traits for std::function types. - * @tparam R The return type of the function. - * @tparam Args The argument types of the function. - */ - template <typename R, typename... Args> - struct function_traits<std::function<R(Args...)>> { - using return_type = R; - static constexpr std::size_t arity = sizeof...(Args); - - template <std::size_t N> - struct argument { - static_assert(N < arity, "Index out of range."); - using type = typename std::tuple_element<N, std::tuple<Args...>>::type; - }; - }; - - ///////////////////// - //change the function to std::shared_ptr<ConditionalData>(std::vector< std::shared_ptr<ConditionalData>>) - ///////////////////// - - /** - * @brief Converts a function to a std::shared_ptr<ConditionalData>(std::vector< std::shared_ptr<ConditionalData>>). - * @tparam F The type of the function to convert. - * @tparam ParamsIdx The indices of the function parameters. - * @param f The function to convert. - * @return The pointer to the converted function. - */ - template <class F, std::size_t... ParamsIdx> - auto funcPointer(F f, std::index_sequence<ParamsIdx...>) { - //wrap the lambda in a new one that as ConditionalData as inputs and output - return [this,f](std::vector< std::shared_ptr<ConditionalData>> &args) { - if (args.size() < sizeof...(ParamsIdx)){ - throw std::runtime_error( - fmt::format("bad Number of argument: get {} need {}\n", - args.size(), - sizeof...(ParamsIdx)) - ); - } - //we used std::vector< std::shared_ptr<ConditionalData>> as a fifo - std::size_t offset = args.size()-sizeof...(ParamsIdx); - - using FuncTraits = function_traits<decltype(f)>; - using outType = typename FuncTraits::return_type; - - outType result = f(safeCastInput<typename FuncTraits::template argument<ParamsIdx>::type>(args[offset+ParamsIdx])...); - - //suppress what we used - for (size_t i = 0; i < sizeof...(ParamsIdx); ++i) { - args.pop_back(); - } - //typename - return safeCastOutput<outType>(result); - }; - } - - /** - * @brief Converts a function pointer to a std::shared_ptr<ConditionalData>(std::vector< std::shared_ptr<ConditionalData>>). - * @tparam R The return type of the function. - * @tparam Params The parameter types of the function. - * @param f The function pointer to convert. - * @return The pointer to the converted function. - */ - template <class R,class... Params> - auto funcPointer(R (*f)(Params...)) { - return funcPointer(f, std::index_sequence_for<Params...>{}); - } - - /** - * @brief Converts a std::function to a std::shared_ptr<ConditionalData>(std::vector< std::shared_ptr<ConditionalData>>). - * @tparam R The return type of the function. - * @tparam Params The parameter types of the function. - * @param f The function pointer to convert. - * @return The pointer to the converted function. - */ - template <class R,class... Params> - auto funcPointer(std::function<R(Params...)> f) { - return funcPointer(f, std::index_sequence_for<Params...>{}); - } - - - /////////////////// - // interface - /////////////////// - - public: - - /** - * @brief Default constructor - */ - ConditionalRegisterFunction(){} - - - /** - * @brief Inserts a function into the map with the provided key. - * @tparam T The function type. - * @param key The key to associate with the function. - * @param f The function to insert. - */ - template <class T> - void insert(const std::string key,T f){ - mWlambda.insert({ key, funcPointer(f)}); - } - - - /** - * @brief Runs the function associated with the given key, using the provided vector of input data. - * @param key The key of the function to run. - * @param data The vector of input data. - * @return A pointer to the output ConditionalData object. - */ - std::shared_ptr<ConditionalData> run(const std::string key,std::vector< std::shared_ptr<ConditionalData>> & data); - - bool isLambdaRegister(const std::string &key) { - if(mWlambda.find(key) != mWlambda.end()){ - return true; - } - return false; - } - - private: - /// @brief map of name and the converted function. - std::map<const std::string, std::function< std::shared_ptr<ConditionalData>(std::vector< std::shared_ptr<ConditionalData>> &)>> mWlambda; -}; - -/////////////////// -//AST tree node -// //////////////// -/** - * @brief this class interprets AST to generate a test on a graph node. For each AST node, - * it generates an interpretation and registers lambda functions that can be used in the test expression. - * there are two lambda control mechanisms: - * - A cpp mechanism which allows any lambda to be inserted into the constructor that use templaite - * - A user mechanism limited to lambda bool(NodePtr) - * @see ConditionalParser use to get the AST - */ -class ConditionalInterpreter -{ - private: - - /** - * @brief the AST generate by the Parser - * @see ConditionalParser - */ - std::shared_ptr<AstNode<ConditionalTokenTypes>> mTree; - /** - * @brief the registry for the lambda function - * @see ConditionalRegisterFunction - */ - ConditionalRegisterFunction mLambdaRegister; - - - std::vector< std::shared_ptr<ConditionalData>> mResolution ; - - // void clearRes(){ - - // for (std::size_t i = 0; i < mResolution.size(); ++i) { - // delete mResolution[i]; - // } - // mResolution.clear(); - // } - - public: - - const std::string mKey; - - /** - * @brief Constructor - * @param ConditionalExpressions The expression of the test to be performed on the nodes - */ - - ConditionalInterpreter(const std::string key,const std::string ConditionalExpressions); - - ~ConditionalInterpreter(){} - - /** - * @brief get the condition key - * @return the key - */ - - const std::string& getKey(); - - /** - * @brief Test a node depending of the ConditionalExpressions - * @details the AST is visit using \ref visit() with the $ init with the nodeOp - * @return bool the match node has the initialized expression - * @see visit() This function uses the visit() function to perform the evaluation. - */ - bool test( const NodePtr nodeOp); - - /** - * @brief Interface for inserting custom lambda bool(NodePtr) functions in AST interpretation, - * it will be available in the ConditionalExpressions expretion as : key($) - * @param key The key that will be used to call the function in the expression - * @param f The pointer to function - */ - void insertLambda(const std::string key,std::function<bool(Aidge::NodePtr)> f); - - bool isLambdaRegister(const std::string &key); - ///// - - private: - /** - * @brief Recursive AST traversal function, using the for interpreting AST nodes function, - * using \ref ASTnodeInterpreterF functions - * @param NodeOp The node currently being tested - * @param nodes The AST given by the parsing process - */ - std::vector< std::shared_ptr<ConditionalData>> visit(const ASTNodeCh& nodes, const NodePtr NodeOp ); - - /** - * @defgroup ASTnodeInterpreterF Functions for interpreting AST nodes - * @brief For each node type in the AST, function defines the processing to be performed - * they return a std::vector< std::shared_ptr<ConditionalData>> which corresponds to the value(s) obtained - */ - - /** - * @ingroup ASTnodeInterpreterF - * @brief Function that does something. - */ - void fLambda(const std::shared_ptr<AstNode<ConditionalTokenTypes>>& node); - /** - * @ingroup ASTnodeInterpreterF - * @brief Converted the lexeme to a int and to std::shared_ptr<ConditionalData> - */ - void fStrToInteger(const std::shared_ptr<AstNode<ConditionalTokenTypes>>& node); - /** - * @ingroup ASTnodeInterpreterF - * @brief Converted the lexeme to a float and to std::shared_ptr<ConditionalData> - */ - void fStrToFloat(const std::shared_ptr<AstNode<ConditionalTokenTypes>>& node); - /** - * @ingroup ASTnodeInterpreterF - * @brief Converted the lexeme to a str and to std::shared_ptr<ConditionalData> - */ - void fStrToStr(const std::shared_ptr<AstNode<ConditionalTokenTypes>>& node); - - /** - * @ingroup ASTnodeInterpreterF - * @brief makes the == operation between two previously converted std::shared_ptr<ConditionalData> - */ - void fEq(void); - /** - * @ingroup ASTnodeInterpreterF - * @brief makes the != operation between two previously converted std::shared_ptr<ConditionalData> - */ - void fNeq(void); - /** - * @ingroup ASTnodeInterpreterF - * @brief makes the && operation between two previously converted std::shared_ptr<ConditionalData> in bool - */ - void fAnd(void); - /** - * @ingroup ASTnodeInterpreterF - * @brief makes the || operation between two previously converted std::shared_ptr<ConditionalData> in bool - */ - void fOr(void); - - /** - * @ingroup ASTnodeInterpreterF - * @brief makes the ! operation - */ - void fNot(void); -}; - - -} - -#endif //AIDGE_CORE_CONDITIONAL_INTERPRETER_H_ diff --git a/include/aidge/nodeTester/ConditionalLexer.hpp b/include/aidge/nodeTester/ConditionalLexer.hpp deleted file mode 100644 index 3ac5614813cec4e42c5c3c20736fd0669cc03a9c..0000000000000000000000000000000000000000 --- a/include/aidge/nodeTester/ConditionalLexer.hpp +++ /dev/null @@ -1,84 +0,0 @@ -/** - * @file - * @brief - * @version file 1.0.0 - * @author vl241552 - * @copyright - * Copyright (c) 2023 CEA, LIST, Embedded Artificial Intelligence Laboratory. All - * rights reserved. - */ - - - -#ifndef AIDGE_CORE_CONDITIONAL_LEXER_H_ -#define AIDGE_CORE_CONDITIONAL_LEXER_H_ - -#include <memory> // for shared_ptr -#include <stdexcept> //error -#include <string> - -#include "aidge/nodeTester/ConditionalTypes.hpp" -#include "aidge/utilsParsing/ParsingToken.hpp" - - -namespace Aidge{ - - - -class ConditionalLexer -{ - -public: -ConditionalLexer( const std::string ConditionalExpressions ); - -/** - * @brief Get the next token on the ConditionalExpressions - * @return ParsingToken<ConditionalTokenTypes> - */ -std::shared_ptr<ParsingToken<ConditionalTokenTypes>> getNextToken(void); -/** - * @brief Restart at the start of the ConditionalExpressions - * - */ -void rstPosition(void); - -/** - * @brief Test if the string is completely read - * @return bool - */ -bool isEnd(void); - - -/** - * @brief Get the representation of the class - * @return string - */ -std::string rep() const noexcept { - return mConditionalExpressions; -} - -private: - -/** - * @brief Constructs an error message to display the character not understood by the lexer - * @return error message - */ -std::runtime_error badTokenError(const std::string& currentChars,std::size_t position); - -/** - * @brief The expression of the test to be performed on the nodes - */ -const std::string mConditionalExpressions; -/** - * @brief The lexer's current position in mConditionalExpressions - */ -std::size_t mPosition; - -}; - -///////////////////////////////////// - - -} - -#endif //AIDGE_CORE_CONDITIONAL_LEXER_H_ diff --git a/include/aidge/nodeTester/ConditionalParser.hpp b/include/aidge/nodeTester/ConditionalParser.hpp deleted file mode 100644 index 06b0e112cfe9bba6a4f0bf32eb1b793326a357f8..0000000000000000000000000000000000000000 --- a/include/aidge/nodeTester/ConditionalParser.hpp +++ /dev/null @@ -1,110 +0,0 @@ - - - -#ifndef AIDGE_CORE_CONDITIONAL_PARSER_H_ -#define AIDGE_CORE_CONDITIONAL_PARSER_H_ - - -#include <memory> // for shared_ptr -#include <map> -#include <vector> - -#include "aidge/nodeTester/ConditionalLexer.hpp" -#include "aidge/nodeTester/ConditionalTypes.hpp" -#include "aidge/utilsParsing/ParsingToken.hpp" -#include "aidge/utilsParsing/AstNode.hpp" - -namespace Aidge{ - -const std::map<ConditionalTokenTypes, std::size_t> ConditionalPrec{ - {ConditionalTokenTypes::AND,2}, - {ConditionalTokenTypes::OR,1} -}; - - - - -using ASTNodeCh = std::vector<std::shared_ptr<AstNode<ConditionalTokenTypes>>>; - -/** - * @brief this class uses the lexer to create an AST according to a set of gramer rules - */ -class ConditionalParser { - - public: - /** - * @brief AST graph creation function - * @param ConditionalExpressions String representing the logical function to be performed - */ - ConditionalParser(const std::string ConditionalExpressions); - - ~ConditionalParser() noexcept; - - /** - * @brief AST graph creation function - * @return The AST tree - */ - std::shared_ptr<AstNode<ConditionalTokenTypes>> parse(void); - - - private: - /** - * @brief restart at the start of the ConditionalExpressions for LEXER and restart mCurrentToken - */ - void rstParser(void); - - ////////////////// - - /** - * @defgroup ParsingFunctions Function for creating AST - * @brief Functions for recursive construction of the AST representing grammar rules - */ - - /** - * @ingroup ParsingFunctions - * @brief Token reading and verification function - * - */ - void ackToken(ConditionalTokenTypes tokenType); - - /** - * @ingroup ParsingFunctions - * @brief Function of grammar rules for values : (KEY|INTEGER|FOAT|STRING|LAMBDA lambda) - * @return AST node - */ - std::shared_ptr<AstNode<ConditionalTokenTypes>> constructAstVal(void); - /** - * @ingroup ParsingFunctions - * @brief Function of grammar rules for comparison : val (EQ|NEQ) val | LPAREN expr RPAREN - * @return AST node - */ - std::shared_ptr<AstNode<ConditionalTokenTypes>> constructAstCmpr(void); - /** - * @ingroup ParsingFunctions - * @brief Function of grammar rules for arguments of a lambda : LAMBDA val (ARGSEP val)* RPAREN - * @return AST node - */ - std::shared_ptr<AstNode<ConditionalTokenTypes>> constructAstLambda(void); - /** - * @ingroup ParsingFunctions - * @brief Function of grammar rules for a expression : cmpr ((AND | OR) cmpr)* - * @return AST node - */ - std::shared_ptr<AstNode<ConditionalTokenTypes>> constructAstExpr(std::size_t precLimit = 0); - - - /** - * @brief The actual token in the parce - */ - std::shared_ptr<ParsingToken<ConditionalTokenTypes>> mCurrentToken; - /** - * @brief The lexem use - */ - ConditionalLexer mLexer; - -}; - - -} - -#endif //AIDGE_CORE_CONDITIONAL_PARSER_H_ diff --git a/include/aidge/nodeTester/ConditionalTypes.hpp b/include/aidge/nodeTester/ConditionalTypes.hpp deleted file mode 100644 index 6cb2edfd78e6b43c4f2dbc89c49cdaa9ea79f7d2..0000000000000000000000000000000000000000 --- a/include/aidge/nodeTester/ConditionalTypes.hpp +++ /dev/null @@ -1,36 +0,0 @@ - - -#ifndef AIDGE_CORE_CONDITIONAL_TYPES_H_ -#define AIDGE_CORE_CONDITIONAL_TYPES_H_ -namespace Aidge{ - /** - * @brief enum for all types of token use in the parsing - * 7-5 type - * 4-0 id - */ - enum class ConditionalTokenTypes - { - STOP, - - NOT, /**< ! */ - AND, /**< && */ - OR, /**< || */ - - EQ, /**< == */ - NEQ, /**< != */ - - KEY, /**< [A-Za-z][A-Za-z0-9_]* */ - INTEGER, /**< [0-9]+ */ - FLOAT, /**< [0-9]+\.[0-9]* */ - STRING , /**< \'.*\' */ - BOOL, /**< true|false */ - NODE, /**< \$ */ - LAMBDA , /**< [A-Za-z][A-Za-z0-9_]*\( */ - - ARGSEP, /**< , */ - LPAREN, /**< \( */ - RPAREN, /**< \) */ - - }; -} -#endif // AIDGE_CORE_CONDITIONAL_TYPES_H_ diff --git a/python_binding/graphRegex/pybind_GraphRegex.cpp b/python_binding/graphRegex/pybind_GraphRegex.cpp deleted file mode 100644 index 921f204d017f90823b9c4a1a024efa271a4691e5..0000000000000000000000000000000000000000 --- a/python_binding/graphRegex/pybind_GraphRegex.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/******************************************************************************** - * 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/functional.h> -#include "aidge/graphRegex/GraphRegex.hpp" - -namespace py = pybind11; -namespace Aidge { -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, py::arg("query"), py::arg("f") = nullptr, R"mydelimiter( - :rtype: str - )mydelimiter") - - .def("set_key_from_graph", &GraphRegex::setKeyFromGraph, R"mydelimiter( - :param ref: The graph use to define type of Node. - :type ref: :py:class:`aidge_core.GraphView` - )mydelimiter") - -// void setNodeKey(const std::string key, const std::string conditionalExpressions ); -// void setNodeKey(const std::string key,std::function<bool(NodePtr)> f); - - .def("match", &GraphRegex::match, R"mydelimiter( - :param graphToMatch: The graph to perform the matching algorithm on. - :type graphToMatch: :py:class:`aidge_core.GraphView` - )mydelimiter") - - - - .def("set_node_key", - (void (GraphRegex::*)(const std::string, const std::string )) & - GraphRegex::setNodeKey, - py::arg("key"), py::arg("conditionalExpressions"), - R"mydelimiter( - 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, - py::arg("key"), py::arg("f"), - R"mydelimiter( - 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 deleted file mode 100644 index 81d39f86ed6da5b7b63a2d43b3a4fcbb2f8e9043..0000000000000000000000000000000000000000 --- a/python_binding/graphRegex/pybind_MatchSolution.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/******************************************************************************** - * 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 435badb6cfe3628815d76f0105d8a1680f17a86a..b3b7c64dae8a590392df04d63864580f74f4e330 100644 --- a/python_binding/pybind_core.cpp +++ b/python_binding/pybind_core.cpp @@ -95,9 +95,6 @@ void init_OpArgs(py::module&); void init_Connector(py::module&); void init_SinglePassGraphMatching(py::module&); -void init_GraphRegex(py::module&); -void init_MatchSolution(py::module&); - void init_Recipes(py::module&); void init_GraphViewHelper(py::module&); @@ -190,9 +187,6 @@ void init_Aidge(py::module& m) { init_Producer(m); - init_GraphRegex(m); - init_MatchSolution(m); - init_Recipes(m); init_GraphViewHelper(m); init_Scheduler(m); diff --git a/src/graphRegex/GraphFsmInterpreter.cpp b/src/graphRegex/GraphFsmInterpreter.cpp deleted file mode 100644 index 0c98113892b9759492f0030dc63dfe4fa4b4ec4c..0000000000000000000000000000000000000000 --- a/src/graphRegex/GraphFsmInterpreter.cpp +++ /dev/null @@ -1,208 +0,0 @@ -/******************************************************************************** - * 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 <cmath> // std::abs -#include <memory> -#include <set> -#include <stdexcept> -#include <string> -#include <vector> - -#include "aidge/graphRegex/GraphFsmInterpreter.hpp" - -using namespace Aidge; - - -GraphFsmInterpreter::GraphFsmInterpreter(const std::string graphMatchExpr,std::vector<std::shared_ptr<ConditionalInterpreter>>&nodesCondition):mParser(graphMatchExpr){ - mActGroupe = 0; - - for (const auto &obj : nodesCondition) { - if(mNodesCondition.find(obj->getKey()) ==mNodesCondition.end()){ - mNodesCondition[obj->getKey()] = obj; - }else{ - throw std::logic_error("GraphFsmInterpreter Bad Key" ); - } - } -} -std::shared_ptr<FsmGraph> GraphFsmInterpreter::interpret(void){ - mActGroupe = 0; - std::shared_ptr<AstNode<gRegexTokenTypes>> tree = mParser.parse(); - std::shared_ptr<FsmGraph> out = visit(tree); - return out; -} - -std::shared_ptr<FsmGraph> GraphFsmInterpreter::visit(std::shared_ptr<AstNode<gRegexTokenTypes>> AstTree){ - - std::vector<std::shared_ptr<AstNode<gRegexTokenTypes>>> nextAstNodes = AstTree->getChilds(); - - if(AstTree->getType() == gRegexTokenTypes::SEP){ - return sepF(visit(nextAstNodes[0]),visit(nextAstNodes[1])); - }else if(AstTree->getType() == gRegexTokenTypes::NEXT){ - return nextF(visit(nextAstNodes[0]),visit(nextAstNodes[1])); - }else if(AstTree->getType() == gRegexTokenTypes::QOM){ - return qomF(visit(nextAstNodes[0])); - }else if(AstTree->getType() == gRegexTokenTypes::QZM){ - return qzmF(visit(nextAstNodes[0])); - }else if(AstTree->getType() == gRegexTokenTypes::KEY || AstTree->getType() == gRegexTokenTypes::CKEY){ - return keyF(AstTree); - }else if(AstTree->getType() == gRegexTokenTypes::LPAREN){ - mActGroupe += 1; - std::shared_ptr<FsmGraph> out = visit(nextAstNodes[0]); - mActGroupe -= 1; - return out; - }else{ - throw std::logic_error("visit Bad token type" ); - } -} - - - - -std::shared_ptr<FsmGraph> GraphFsmInterpreter::keyF(std::shared_ptr<AstNode<gRegexTokenTypes>> AstNode){ - - - std::shared_ptr<FsmNode> start = std::make_shared<FsmNode>(false,true); - std::shared_ptr<FsmNode> valid = std::make_shared<FsmNode>(true,false); - std::shared_ptr<FsmGraph> graph = std::make_shared<FsmGraph>(mParser.getQuery()); - std::shared_ptr<FsmEdge> edge; - - - if(AstNode->getType() == gRegexTokenTypes::CKEY){ - edge = FsmEdgeFactory::make(start,valid,FsmEdgeTypes::COMMON,mNodesCondition,AstNode->getValue()); - }else if (AstNode->getType() == gRegexTokenTypes::KEY) - { - edge = FsmEdgeFactory::make(start,valid,FsmEdgeTypes::UNIQUE,mNodesCondition,AstNode->getValue()); - }else{ - - throw std::logic_error("keyF Bad in AST" ); - } - - graph->addEdge(edge); - graph->setGroupe(mActGroupe); - return graph; -} - -std::shared_ptr<FsmGraph> GraphFsmInterpreter::sepF(std::shared_ptr<FsmGraph> leftFsm,std::shared_ptr<FsmGraph> rigthFsm){ - - size_t idxLeft = leftFsm->getNbSubFsm(); - rigthFsm->incOriginAllNodeBy(idxLeft); - leftFsm->unionG(rigthFsm); - //the rigthFsm is no longer usfull - return leftFsm; -} - -std::shared_ptr<FsmGraph> GraphFsmInterpreter::nextF(std::shared_ptr<FsmGraph> leftFsm,std::shared_ptr<FsmGraph> rigthFsm){ - /* - combine the 2 Graph - all valid node of A are merge with Start B, Start B is un Start - update the relative reference - - A B - SA -> VA + SB -> VB - A B - SA -> q -> VB - */ - leftFsm->mergeOneStartOneValid(rigthFsm); - //the rigthFsm is no longer usfull - return leftFsm; -} - -std::shared_ptr<FsmGraph> GraphFsmInterpreter::qomF(std::shared_ptr<FsmGraph> fsm){ - /* - + - valid node is connect to the child of Start with the same edge condition - A - S -> V - - A - S -> V - (E|R) - V -> S - */ - - std::vector<std::shared_ptr<FsmNode>> allStart = fsm->getStartNodes(); - std::set<std::shared_ptr<FsmNode>> allValid = fsm->getValidNodes(); - std::shared_ptr<FsmEdge> edge; - - if(allStart.size() != 1){ - throw std::logic_error("qomF Bad in AST" ); - } - - for(auto start : allStart ){ - for(auto edgeStart :start->getEdges() ){ - if (auto sharedEdge = edgeStart.lock()) { - - const std::map<size_t, int> commonRef = sharedEdge->getRelative(); - bool haveCommon = !commonRef.empty(); - - for(auto valid : allValid){ - if(haveCommon){ - /* - the // quantify case - get the go back and make a lexeme id(number) - we need to go back to the ref delta min #TODO - */ - bool hasMinRef = false; - std::pair<size_t, int> minRef; - for (const auto& entry : commonRef) { - if (!hasMinRef || std::abs(minRef.second) > std::abs(entry.second)) { - hasMinRef = true; - minRef = entry; - } - } - const auto lexem = fmt::format("({}, {})", minRef.first, minRef.second); - edge = FsmEdgeFactory::make(valid,start,FsmEdgeTypes::REF,mNodesCondition, lexem); - }else{ - /* - the sequential quantify case - no reference to common - */ - edge = FsmEdgeFactory::make(valid, start, FsmEdgeTypes::EMPTY, mNodesCondition, ""); - - } - fsm->addEdge(edge); - } - } else { - throw std::runtime_error("edgeStart weak pointer is expired" ); - } - } - - } - return fsm; - -} - -std::shared_ptr<FsmGraph> GraphFsmInterpreter::qzmF(std::shared_ptr<FsmGraph> fsm){ - /* - qomf and a bypass empty start to valid - */ - fsm = qomF(fsm); - - std::vector<std::shared_ptr<FsmNode>> allStart = fsm->getStartNodes(); - std::set<std::shared_ptr<FsmNode>> allValid = fsm->getValidNodes(); - std::shared_ptr<FsmEdge> edge; - - if(allStart.size() != 1){ - throw std::logic_error("qzmF Bad in AST" ); - } - - for(auto start : allStart ){ - - for(auto valid : allValid){ - edge = FsmEdgeFactory::make(start,valid,FsmEdgeTypes::EMPTY,mNodesCondition,""); - fsm->addEdge(edge); - } - } - - return fsm; - - -} \ No newline at end of file diff --git a/src/graphRegex/GraphLexer.cpp b/src/graphRegex/GraphLexer.cpp deleted file mode 100644 index 75181e326c8e6f665407746cd75ccc432964ac7d..0000000000000000000000000000000000000000 --- a/src/graphRegex/GraphLexer.cpp +++ /dev/null @@ -1,159 +0,0 @@ - -#include "aidge/graphRegex/GraphLexer.hpp" - -using namespace Aidge; - - -GraphLexer::GraphLexer( const std::string gRegexExpressions ): -mRegularExpressions(gRegexExpressions){ - mPosition = 0; -} - -std::shared_ptr<ParsingToken<gRegexTokenTypes>> GraphLexer::getNextToken(void){ - std::string currentChars = ""; - while (mPosition < mRegularExpressions.length()) - { - //erase all space - if (mRegularExpressions[mPosition] != ' ') - { - currentChars += mRegularExpressions[mPosition]; - } - else - { - mPosition++; - continue; - } - - ///// - // const lent token - ///// - - if (std::regex_match(currentChars,std::regex("\\->")))// the next TOKEN - { - mPosition++; - return std::make_shared<ParsingToken<gRegexTokenTypes>>(gRegexTokenTypes::NEXT,""); - } - else if (std::regex_match(currentChars,std::regex("\\*")))// the * TOKEN - { - mPosition++; - return std::make_shared<ParsingToken<gRegexTokenTypes>>(gRegexTokenTypes::QZM,""); - } - else if (std::regex_match(currentChars,std::regex("\\+")))// the + TOKEN - { - mPosition++; - return std::make_shared<ParsingToken<gRegexTokenTypes>>(gRegexTokenTypes::QOM,""); - } - else if (std::regex_match(currentChars,std::regex("\\(")))// the LPAREN TOKEN - { - mPosition++; - return std::make_shared<ParsingToken<gRegexTokenTypes>>(gRegexTokenTypes::LPAREN,""); - } - else if (std::regex_match(currentChars,std::regex("\\)")))// the RPAREN TOKEN - { - mPosition++; - return std::make_shared<ParsingToken<gRegexTokenTypes>>(gRegexTokenTypes::RPAREN,""); - } - - // - else if (std::regex_match(currentChars,std::regex(";")))// the SEP TOKEN - { - //test if the last sep - //std::string subStr = mRegularExpressions.substr(mPosition); - mPosition++; - return std::make_shared<ParsingToken<gRegexTokenTypes>>(gRegexTokenTypes::SEP,""); - } - - ///// - //unconst lent token - ///// - - else if (std::regex_match(currentChars,std::regex("[A-Za-z_0-9]")))// the KEY or CKEY - { - - //read all the key - bool isCKey = false; - std::regex keyRegex("[A-Za-z_0-9]+"); - std::regex cKeyRegex("[A-Za-z_0-9]+\\#[0-9]*"); - - while ( mPosition < mRegularExpressions.length()) { - - if(!std::regex_match(currentChars,keyRegex) && !std::regex_match(currentChars,cKeyRegex)) - { - currentChars.pop_back(); //the last char is the problems - break; - } - else if (std::regex_match(currentChars,cKeyRegex)){ - isCKey = true; - } - mPosition++; - if (mPosition < mRegularExpressions.length()) currentChars += mRegularExpressions[mPosition]; - - } - //we end the match 2 possibility - //we are at the end of the mConditionalExpressions and we need to ensure the match - //we are not we can continu - if (mPosition == mRegularExpressions.length()-1) - { - if (!std::regex_match(currentChars,keyRegex) && !std::regex_match(currentChars,cKeyRegex)) - { - throw badTokenError(currentChars,mPosition); - } - } - - - if (isCKey){ - return std::make_shared<ParsingToken<gRegexTokenTypes>>(gRegexTokenTypes::CKEY,currentChars); - } else{ - return std::make_shared<ParsingToken<gRegexTokenTypes>>(gRegexTokenTypes::KEY,currentChars); - } - } - - mPosition++; - } - - - //no more to find no one match the currentChars - if (currentChars.empty()) { - return std::make_shared<ParsingToken<gRegexTokenTypes>>(gRegexTokenTypes::STOP,""); // Null shared pointer ; - }else{ - throw badTokenError(currentChars,mPosition); - } - -} - -void GraphLexer::rstPosition(void){ - if (isEnd()){ - mPosition = 0; - }else{ - throw badTokenError("end rst",mPosition); - } -} - -bool GraphLexer::isEnd(void){ - return mPosition >= mRegularExpressions.length(); -} - - -const std::string GraphLexer::getQuery(){ - return mRegularExpressions; -} - -std::runtime_error GraphLexer::badTokenError(const std::string& currentChars, std::size_t position) { - return std::runtime_error(fmt::format( - "\nBad syntax {}:\n{}\n{:>{}}\n", - currentChars, - mRegularExpressions, - "^", - position + 1 - )); -} - -const std::string GraphLexer::rep(){ - std::string out = mRegularExpressions; - out += "\n"; - for (std::size_t i = 0; i < mPosition; i++) { - out += ' '; - } - out += "^\n"; - return out ; -} \ No newline at end of file diff --git a/src/graphRegex/GraphParser.cpp b/src/graphRegex/GraphParser.cpp deleted file mode 100644 index 382e22a5622c6aac33cbab6b17ed37be14884462..0000000000000000000000000000000000000000 --- a/src/graphRegex/GraphParser.cpp +++ /dev/null @@ -1,174 +0,0 @@ -#include <memory> -#include <string> -#include <vector> - -#include "aidge/graphRegex/GraphParser.hpp" - -Aidge::GraphParser::GraphParser(const std::string gRegexExpressions): -mLexer(gRegexExpressions) -{ - mCurrentToken = mLexer.getNextToken(); -} - -Aidge::GraphParser::~GraphParser() noexcept = default; - - -const std::string Aidge::GraphParser::getQuery(){ - return mLexer.getQuery(); -} - -std::shared_ptr<Aidge::AstNode<Aidge::gRegexTokenTypes>> Aidge::GraphParser::parse(void){ - - std::shared_ptr<AstNode<gRegexTokenTypes>> astTree = constructAstAllExpr(); - rstParser(); - return astTree; -} - - -void Aidge::GraphParser::rstParser(void){ - mLexer.rstPosition(); - mCurrentToken = mLexer.getNextToken(); -} - - -void Aidge::GraphParser::ackToken(gRegexTokenTypes tokenType){ - - if(mCurrentToken->getType() == tokenType ) { - try { - mCurrentToken = mLexer.getNextToken(); - } catch (const std::runtime_error& e) { - throw std::runtime_error(fmt::format("Graph Lexer error in Parser :\n{}\n", e.what())); - } - } else { - throw std::runtime_error(fmt::format("Bad syntax GraphParser {} != {}\n{}\n", static_cast<int>(mCurrentToken->getType()), static_cast<int>(tokenType), mLexer.rep())); - } -} - -/* -exp : KEY(QOM | QZM)? | CKEY | domain -*/ -std::shared_ptr<Aidge::AstNode<Aidge::gRegexTokenTypes>> Aidge::GraphParser::constructAstExp(void) -{ - - try{ - std::shared_ptr<ParsingToken<gRegexTokenTypes>> token = mCurrentToken->copy(); - std::shared_ptr<AstNode<gRegexTokenTypes>> node = std::make_shared<AstNode<gRegexTokenTypes>>(token); - - if (mCurrentToken->getType() == gRegexTokenTypes::KEY ){ - ackToken(gRegexTokenTypes::KEY ); - if (mCurrentToken->getType() == gRegexTokenTypes::QOM ){ - token = mCurrentToken->copy(); - ackToken(gRegexTokenTypes::QOM ); - std::shared_ptr<AstNode<gRegexTokenTypes>> newNode = std::make_shared<AstNode<gRegexTokenTypes>>(token, - std::vector<std::shared_ptr<AstNode<gRegexTokenTypes>>>{node}); - return newNode; - }else if (mCurrentToken->getType() == gRegexTokenTypes::QZM ){ - token = mCurrentToken->copy(); - ackToken(gRegexTokenTypes::QZM ); - std::shared_ptr<AstNode<gRegexTokenTypes>> newNode = std::make_shared<AstNode<gRegexTokenTypes>>(token, - std::vector<std::shared_ptr<AstNode<gRegexTokenTypes>>>{node}); - return newNode; - } - return node; - }else if (mCurrentToken->getType() == gRegexTokenTypes::CKEY){ - ackToken(gRegexTokenTypes::CKEY ); - return node; - }else{ - return constructAstDomain(); - } - - } catch (const std::runtime_error& e) { - throw std::runtime_error(fmt::format("GraphParser constructAstExp :\n{}\n", e.what())); - } -} - -/* -seq :exp (NEXT seq)* -*/ -std::shared_ptr<Aidge::AstNode<Aidge::gRegexTokenTypes>> Aidge::GraphParser::constructAstSeq(void) -{ - - try{ - - std::shared_ptr<AstNode<gRegexTokenTypes>> left = constructAstExp(); - if(mCurrentToken->getType() == gRegexTokenTypes::NEXT ) - { - std::shared_ptr<ParsingToken<gRegexTokenTypes>> token = mCurrentToken->copy(); - ackToken(gRegexTokenTypes::NEXT); - std::shared_ptr<AstNode<gRegexTokenTypes>> newNode = std::make_shared<AstNode<gRegexTokenTypes>>(token, - std::vector<std::shared_ptr<AstNode<gRegexTokenTypes>>>{left,constructAstSeq()}); - left = newNode; - } - return left; - - } catch (const std::runtime_error& e) { - throw std::runtime_error(fmt::format("GraphParser constructAstSeq :\n{}\n", e.what())); - } - -} - - -/* -LPAREN seq RPAREN (QOM | QZM) -*/ -std::shared_ptr<Aidge::AstNode<Aidge::gRegexTokenTypes>> Aidge::GraphParser::constructAstDomain(void) -{ - - try{ - std::shared_ptr<ParsingToken<gRegexTokenTypes>> token ; - std::shared_ptr<AstNode<gRegexTokenTypes>> node ; - - token = mCurrentToken->copy(); - ackToken(gRegexTokenTypes::LPAREN); - node = std::make_shared<AstNode<gRegexTokenTypes>>(token, - std::vector<std::shared_ptr<AstNode<gRegexTokenTypes>>>{constructAstSeq()}); - ackToken(gRegexTokenTypes::RPAREN); - //(QOM | QZM) - - token = mCurrentToken->copy(); - if (mCurrentToken->getType() == gRegexTokenTypes::QOM) { - ackToken(gRegexTokenTypes::QOM); - node = std::make_shared<AstNode<gRegexTokenTypes>>(token, - std::vector<std::shared_ptr<AstNode<gRegexTokenTypes>>>{node}); - } else if (mCurrentToken->getType() == gRegexTokenTypes::QZM) { - ackToken(gRegexTokenTypes::QZM); - node = std::make_shared<AstNode<gRegexTokenTypes>>(token, - std::vector<std::shared_ptr<AstNode<gRegexTokenTypes>>>{node}); - } else { - throw std::runtime_error("Bad syntax constructAstDomain must have quantifier \n"); - } - - return node; - - } catch (const std::runtime_error& e) { - throw std::runtime_error(fmt::format("GraphParser constructAstDomain:\n{}\n", e.what())); - } -} - -/* - allExpr: seq (SEP allExpr)* | STOP -*/ -std::shared_ptr<Aidge::AstNode<Aidge::gRegexTokenTypes>> Aidge::GraphParser::constructAstAllExpr(void) -{ - - try{ - std::shared_ptr<AstNode<gRegexTokenTypes>> left = constructAstSeq(); - if(mCurrentToken->getType() == gRegexTokenTypes::SEP ) - { - std::shared_ptr<ParsingToken<gRegexTokenTypes>> token = mCurrentToken->copy(); - ackToken(gRegexTokenTypes::SEP); - - if(mCurrentToken->getType() == gRegexTokenTypes::STOP ) - { - return left; - } - std::shared_ptr<AstNode<gRegexTokenTypes>> newNode = std::make_shared<AstNode<gRegexTokenTypes>>(token, - std::vector<std::shared_ptr<AstNode<gRegexTokenTypes>>>{left,constructAstAllExpr()}); - left = newNode; - } - return left; - - } catch (const std::runtime_error& e) { - throw std::runtime_error(fmt::format("GraphParser constructAstDomain:\n{}\n", e.what())); - } -} diff --git a/src/graphRegex/GraphRegex.cpp b/src/graphRegex/GraphRegex.cpp deleted file mode 100644 index ca15ff8dec5ff5ebd4ea69141c6e286849162bb5..0000000000000000000000000000000000000000 --- a/src/graphRegex/GraphRegex.cpp +++ /dev/null @@ -1,167 +0,0 @@ -#include "aidge/graphRegex/GraphRegex.hpp" -using namespace Aidge; - - -void GraphRegex::setKeyFromGraph(std::shared_ptr<GraphView> ref){ - - for (const NodePtr& node : ref->getNodes()) { - std::string type = node->type(); - bool isIn = false; - for(const auto &test:mAllTest){ - if(test->getKey() == type){ - isIn = true; - break; - } - } - if(!isIn){ - mAllTest.push_back(std::make_shared<ConditionalInterpreter>(type,"getType($) =='" + type + "'")); - } - // auto it = mAllTest.find(type); - // if (it == mAllTest.end()) { - // mAllTest[type] = std::make_shared<ConditionalInterpreter>(type,"getType($) =='" + type + "'"); - // } - // //if the key exist it's ok, but not make 2 ConditionalInterpreter - } -} - - - -// void GraphRegex::addQuery(const std::string query){ -// //TODO one query only but the same string is a same query but -// //2 different string it's maybe the same query , we need to check the AST -// mQueryRecipe[query] = nullptr; -// } - -void GraphRegex::addQuery(const std::string query,RecipesFunctionType f ){ - - mQueryRecipe[query] = f; - -} - - -// Function to generate all combinations of n elements from a set -void GraphRegex::_generateCombinationsStart(const std::set<NodePtr>& elements, std::size_t n, std::size_t index, std::vector<NodePtr>& current, std::set<std::vector<NodePtr>>& combinations) { - if (n == 0) { - combinations.insert(current); - return; - } - for (auto it = elements.begin(); it != elements.end(); ++it) { - current.push_back(*it); - _generateCombinationsStart(elements, n - 1, index + 1, current, combinations); - current.pop_back(); - } -} - -// factorial(n) tree searched optimized with a stopping condition -void GraphRegex::_findLargestCompatibleSet( - const std::vector<std::shared_ptr<MatchSolution>>& solutions, - std::set<std::shared_ptr<MatchSolution>>& currentSet, - std::set<std::shared_ptr<MatchSolution>>& largestSet, - size_t currentIndex -) { - if (currentIndex >= solutions.size()) { - if (currentSet.size() > largestSet.size()) { - largestSet = currentSet; - } - return; - } - - for (size_t i = currentIndex; i < solutions.size(); ++i) { - if (std::all_of(currentSet.begin(), currentSet.end(), - [&](const std::shared_ptr<MatchSolution>& solution) { - return solution->areCompatible(solutions[i]); - } - )) { - currentSet.insert(solutions[i]); - _findLargestCompatibleSet(solutions, currentSet, largestSet, i + 1); - currentSet.erase(solutions[i]); - // cut the size of the graph of possibilities - if ((currentSet.size() + solutions.size() - currentIndex) <= largestSet.size()) { - return; - } - } - } -} - -std::set<std::shared_ptr<MatchSolution>> GraphRegex::_findLargestCompatibleSet( - const std::vector<std::shared_ptr<MatchSolution>>& solutions -) { - std::set<std::shared_ptr<MatchSolution>> largestSet; - std::set<std::shared_ptr<MatchSolution>> currentSet; - _findLargestCompatibleSet(solutions, currentSet, largestSet, 0); - return largestSet; -} - - - -std::set<std::shared_ptr<MatchSolution>> GraphRegex::match(std::shared_ptr<GraphView> ref){ - - std::vector<std::shared_ptr<MatchSolution>> solutions = {}; - - //for (const std::string& query : mQuery) { - for (auto it = mQueryRecipe.begin(); it != mQueryRecipe.end(); ++it) { - const std::string query = it->first; - - std::shared_ptr<GraphFsmInterpreter> fsmGenerator = std::make_shared<GraphFsmInterpreter>(query,mAllTest); - std::shared_ptr<FsmGraph> fsm = fsmGenerator->interpret(); - - // generate all the start possibility - std::size_t nb_startSt = fsm->getNbStart(); - std::set<std::vector<NodePtr>> combinations; - std::vector<NodePtr> current; - _generateCombinationsStart(ref->getNodes(), nb_startSt, 0, current, combinations); - - - // all start - for (const auto& combination : combinations) { - std::vector<std::shared_ptr<MatchSolution>> solution = fsm->test(combination); - solutions.insert(solutions.end(), solution.begin(), solution.end()); - } - - - } - return _findLargestCompatibleSet(solutions); -} - -void GraphRegex::appliedRecipes(std::shared_ptr<GraphView> ref){ - std::set<std::shared_ptr<MatchSolution>> matchRef = match(ref); - for (const auto& solution : matchRef) { - if(mQueryRecipe[solution->getQuery()] != nullptr){ - mQueryRecipe[solution->getQuery()](solution); - } - } -} - -void GraphRegex::setNodeKey(const std::string key, const std::string conditionalExpressions ){ - mAllTest.push_back(std::make_shared<ConditionalInterpreter>(key,conditionalExpressions)); - _majConditionalInterpreterLambda(); -} - - -void GraphRegex::setNodeKey(const std::string key,std::function<bool(NodePtr)> f){ - //we can applied to all key but it's not efficient - if(mAllLambda.find(key) != mAllLambda.end()){ - throw std::runtime_error(key + " is define"); - } - mAllLambda[key] = f; - - _majConditionalInterpreterLambda(); - //we add the lambda as key by default - setNodeKey(key, key + "($)==true"); -} - -void GraphRegex::_majConditionalInterpreterLambda(){ - - for (const auto& test : mAllTest) { - for (const auto& pair : mAllLambda) { - const std::string& key = pair.first; - const std::function<bool(NodePtr)>& lambda = pair.second; - - if(!test->isLambdaRegister(key)){ - test->insertLambda(key,lambda); - } - - } - } -} - diff --git a/src/graphRegex/GraphStrInterpreter.cpp b/src/graphRegex/GraphStrInterpreter.cpp deleted file mode 100644 index 8ad24b5b9b0fee5fba34dd7397132bec2410fd23..0000000000000000000000000000000000000000 --- a/src/graphRegex/GraphStrInterpreter.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "aidge/graphRegex/GraphStrInterpreter.hpp" - -using namespace Aidge; - -GraphStrInterpreter::GraphStrInterpreter(const std::string graphMatchExpr):mParser(graphMatchExpr){ - mToTest = graphMatchExpr; - mToTest.erase(std::remove_if(mToTest.begin(), mToTest.end(), ::isspace), mToTest.end()); -} - - -std::string GraphStrInterpreter::visit(std::shared_ptr<AstNode<gRegexTokenTypes>> AstTree){ - - std::vector<std::shared_ptr<AstNode<gRegexTokenTypes>>> nextAstNodes = AstTree->getChilds(); - - if(AstTree->getType() == gRegexTokenTypes::SEP){ - return visit(nextAstNodes[0])+";"+visit(nextAstNodes[1]); - }else if(AstTree->getType() == gRegexTokenTypes::NEXT){ - return visit(nextAstNodes[0])+"->"+visit(nextAstNodes[1]); - }else if(AstTree->getType() == gRegexTokenTypes::QOM){ - return visit(nextAstNodes[0])+"+"; - }else if(AstTree->getType() == gRegexTokenTypes::QZM){ - return visit(nextAstNodes[0])+"*"; - }else if(AstTree->getType() == gRegexTokenTypes::KEY || AstTree->getType() == gRegexTokenTypes::CKEY){ - return AstTree->getValue(); - }else if(AstTree->getType() == gRegexTokenTypes::LPAREN){ - return "("+visit(nextAstNodes[0])+")"; - }else{ - throw std::logic_error("visit Bad token type" ); - } - - -} - - -std::string GraphStrInterpreter::interpret(void){ - std::shared_ptr<AstNode<gRegexTokenTypes>> tree = mParser.parse(); - return visit(tree); -} \ No newline at end of file diff --git a/src/graphRegex/matchFsm/FsmEdge.cpp b/src/graphRegex/matchFsm/FsmEdge.cpp deleted file mode 100644 index 78a741d272ea3d092bec02cf55fcd834b4cc56f0..0000000000000000000000000000000000000000 --- a/src/graphRegex/matchFsm/FsmEdge.cpp +++ /dev/null @@ -1,319 +0,0 @@ -/******************************************************************************** - * 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 <cstddef> // std::size_t -#include <map> -#include <regex> -#include <string> - - -#include "aidge/graphRegex/matchFsm/FsmEdge.hpp" -#include "aidge/graphRegex/matchFsm/FsmNode.hpp" -#include "aidge/graphRegex/matchFsm/FsmRunTimeContext.hpp" - -using namespace Aidge; - -std::map<std::string,int> FsmEdgeCommon::mCommonIdxMap; - -bool FsmEdge::isCommon(void){ - return false; -} - -size_t FsmEdge::getCommonIdx(void){ - return std::numeric_limits<std::size_t>::max(); -} -const std::map<size_t,int>& FsmEdge::getRelative(void){ - return mRelativePos; -} -void FsmEdge::updateRelative( const std::map<std::size_t,int>& relativePos ){ - for (const auto& kvp : relativePos) { - mRelativePos.insert(kvp); - } -} -std::shared_ptr<FsmNode> FsmEdge::getSourceNode(void){ - return mNodeSource; -} -void FsmEdge::reSetSourceNode(const std::shared_ptr<FsmNode>& newSource){ - mNodeSource->rmEdge(shared_from_this()); - mNodeSource = newSource; - mNodeSource->addEdge(shared_from_this()); - propagateRelativePos(); - -} -std::shared_ptr<FsmNode> FsmEdge::getDestNode(void){ - return mNodeDest; -} -void FsmEdge::reSetDestNode(const std::shared_ptr<FsmNode>& newDest){ - mNodeDest->rmParent(mNodeSource); - mNodeDest = newDest; - mNodeDest->addParent(mNodeSource); - propagateRelativePos(); -} -void FsmEdge::propagateRelativePos(void){ - - std::set<std::size_t> myRelativeID; - for (const auto& kvp : mRelativePos) { - myRelativeID.insert(kvp.first); - } - - for (const auto& nextWeakEdge : mNodeDest->getEdges()){ - - if (auto nextEdge = nextWeakEdge.lock()) { - - if(this == nextEdge.get()){ - continue; - } - - - std::set<std::size_t> nextRelativeID; - for (const auto& kvp : nextEdge->getRelative()) { - nextRelativeID.insert(kvp.first); - } - - // Find elements in myRelativeID but not in nextRelativeID - std::set<std::size_t> idxsToPush; - std::set_difference(myRelativeID.begin(), myRelativeID.end(), - nextRelativeID.begin(), nextRelativeID.end(), - std::inserter(idxsToPush, idxsToPush.begin())); - - // Find elements in nextRelativeID but not in myRelativeID - std::set<std::size_t> idxsToGet; - std::set_difference(nextRelativeID.begin(), nextRelativeID.end(), - myRelativeID.begin(), myRelativeID.end(), - std::inserter(idxsToGet, idxsToGet.begin())); - - // test for integrity we look if 2 edge refer to the same - // ref and are link the ref dif is one - // not working for common node - // we can go deeper by find the all pass to a ref and see if the delta is good - - // Find elements present in both myRelativeID and nextRelativeID - std::set<std::size_t> idxsTotest; - for (auto idx : nextRelativeID){ - if (myRelativeID.find(idx) != myRelativeID.end()){ - if (std::abs(getRelative().at(idx) - nextEdge->getRelative().at(idx)) != 1) { - throw std::runtime_error("Bad relative"); - } - } - } - - - - // this edge have more relative info than the next - std::map<size_t,int> tmpRelative; - // we push this info to the next - for(auto idxToPush :idxsToPush ){ - tmpRelative.insert( std::make_pair(idxToPush, getRelative().at(idxToPush) +1)); - } - if(tmpRelative.size() != 0){ - nextEdge->updateRelative(tmpRelative); - nextEdge->propagateRelativePos(); - } - tmpRelative.clear(); - - - // the next node have more info than me i need to get it - for(auto idxToGet :idxsToGet ){ - tmpRelative.insert( std::make_pair(idxToGet, nextEdge->getRelative().at(idxToGet) -1)); - } - if(tmpRelative.size() != 0){ - updateRelative(tmpRelative); - - for(auto weakParent : getSourceNode()->getParentNodes()){ - if (auto parent = weakParent.lock()) { - for(auto weakPEdge : parent->getEdges()){ - if (auto pEdge = weakPEdge.lock()) { - pEdge->propagateRelativePos(); - }else{ - throw std::runtime_error("propagateRelativePos parent edge weak pointer is expired" ); - } - } - }else{ - throw std::runtime_error("propagateRelativePos parent weak pointer is expired" ); - } - } - } - tmpRelative.clear(); - }else{ - throw std::runtime_error("propagateRelativePos edge weak pointer is expired" ); - } - } -} - -void FsmEdge::updateWeak(void){ - mNodeSource->addEdge(shared_from_this()); - mNodeDest->addParent(mNodeSource); -} - -FsmEdge::FsmEdge(std::shared_ptr<FsmNode>& source,std::shared_ptr<FsmNode>& dest, const std::shared_ptr<ConditionalInterpreter> toTest) -:mToTest(toTest) -{ - mNodeSource = source; - mNodeDest = dest; - // when i make the edge I init the nodes - // mNodeSource->addEdge(shared_from_this()); - // mNodeDest->addParent(mNodeSource); -} - - -/////surchage - -FsmEdgeUnique::FsmEdgeUnique(std::shared_ptr<FsmNode>& source,std::shared_ptr<FsmNode>& dest, const std::shared_ptr<ConditionalInterpreter> toTest) -:FsmEdge(source,dest,toTest) -{ -} -const EdgeTestResult FsmEdgeUnique::test(const std::shared_ptr<FsmRunTimeContext> stmContext){ - auto opNode = stmContext->getActNode(); - - if(opNode == nullptr){ - return {false,std::set<NodePtr>()};//none - } - - if(mToTest->test(opNode) && opNode->getChildren().size() <= 1){ - stmContext->setValid(opNode,mToTest); - return {true,opNode->getChildren()} ; - }else{ - stmContext->addRejectedNode(opNode); - return {false,std::set<NodePtr>()}; - } -} -///////////////////// -FsmEdgeCommon::FsmEdgeCommon(std::shared_ptr<FsmNode>& source,std::shared_ptr<FsmNode>& dest, const std::shared_ptr<ConditionalInterpreter> toTest, const std::string commonKey) -:FsmEdge(source,dest,toTest) -{ - //make a uid for common node - if(mCommonIdxMap.find(commonKey) == mCommonIdxMap.end()){ - mCommonIdxMap.insert(std::make_pair(commonKey, mCommonIdxMap.size())); - } - mCommonIdx = mCommonIdxMap[commonKey]; - propagateRelativePos(); -} - - -const EdgeTestResult FsmEdgeCommon::test(const std::shared_ptr<FsmRunTimeContext> stmContext){ - - auto opNode = stmContext->getActNode(); - - if(opNode == nullptr){ - return {false,std::set<NodePtr>()};//none - } - if(mToTest->test(opNode)){ - stmContext->setCommon(opNode,mCommonIdx); - stmContext->setValid(opNode,mToTest); - return {true,opNode->getChildren()} ; - }else{ - stmContext->addRejectedNode(opNode); - return {false,std::set<NodePtr>()}; - } -} -bool FsmEdgeCommon::isCommon(void){ - return true; - } -//////////////////// TODO FsmEdgeEmpty must be size_t -FsmEdgeRef::FsmEdgeRef(std::shared_ptr<FsmNode>& source,std::shared_ptr<FsmNode>& dest, const size_t refCommonIdx,const int deltaCommonIdx) -:FsmEdge(source,dest,nullptr),mRefCommonIdx(refCommonIdx),mdeltaCommonIdx(deltaCommonIdx) -{ - -} -const EdgeTestResult FsmEdgeRef::test(const std::shared_ptr<FsmRunTimeContext> stmContext){ - - NodePtr refNode = stmContext->getCommonNodeFromIdx(mRefCommonIdx); - if (refNode){ - std::set<std::shared_ptr<Node>> see; - return {true,refNode->getNodeDelta(mdeltaCommonIdx,see)}; - } - return {false,std::set<NodePtr>()}; -} -//////////////////// -FsmEdgeEmpty::FsmEdgeEmpty(std::shared_ptr<FsmNode> source,std::shared_ptr<FsmNode> dest) -:FsmEdge(source,dest,nullptr) -{} -const EdgeTestResult FsmEdgeEmpty::test(const std::shared_ptr<FsmRunTimeContext> stmContext){ - auto opNode = stmContext->getActNode(); - if(opNode == nullptr){ - return {false,std::set<NodePtr>()}; - } - return {true,std::set<NodePtr>({opNode})};//none -} -////////////// - -FsmEdgeNone::FsmEdgeNone(std::shared_ptr<FsmNode> source,std::shared_ptr<FsmNode> dest) -:FsmEdge(source,dest,nullptr) -{} - const EdgeTestResult FsmEdgeNone::test(const std::shared_ptr<FsmRunTimeContext> /*stmContext*/){ - return {false,std::set<NodePtr>()}; - } - -/// factory -std::shared_ptr<FsmEdge> FsmEdgeFactory::make( -std::shared_ptr<FsmNode> source, -std::shared_ptr<FsmNode> dest, FsmEdgeTypes type, -std::map<std::string, std::shared_ptr<ConditionalInterpreter>> allTest, -const std::string lexeme) -{ - if (type == FsmEdgeTypes::EMPTY) { - if (lexeme.empty()) { - return std::make_shared<FsmEdgeEmpty>(source, dest); - } else { - throw std::invalid_argument("error lexem EMPTY"); - } - } else if (type == FsmEdgeTypes::REF) { - std::smatch m; - std::regex refRegex("\\s*\\(\\s*(\\d+)\\s*,\\s*(-?\\d+)\\s*\\)\\s*"); - if (std::regex_match(lexeme, m, refRegex)) { - int refCommonIdx = std::stoi(m[1]); - int deltaCommonIdx = std::stoi(m[2]); - return std::make_shared<FsmEdgeRef>(source, dest, refCommonIdx, deltaCommonIdx); - } else { - throw std::invalid_argument("error lexem REF " + lexeme); - } - } else if (type == FsmEdgeTypes::COMMON) { - std::smatch m; - std::regex commonRegex("\\s*(\\w+)#(\\d*)"); - if (std::regex_match(lexeme, m, commonRegex)) { - std::string edgeType = m[1]; - std::string commonId = m[2]; - size_t commonIdx = commonId.empty() ? 0 : std::stoi(commonId) + 1; - std::string commonKey = edgeType + std::to_string(commonIdx); - - if(allTest.find(edgeType) == allTest.end()){ - //if the key is not linked to a condition - //by default, it is initialized by a edge that is always false - return std::make_shared<FsmEdgeNone>(source, dest); - //throw std::invalid_argument("Bad Node Test " + edgeType ); - } - - return std::make_shared<FsmEdgeCommon> (source, dest, allTest.at(edgeType), commonKey); - } else { - throw std::invalid_argument("error lexem COMMON " + lexeme); - } - } else if (type == FsmEdgeTypes::UNIQUE) { - std::regex uniqueRegex("\\s*(\\w+)"); - std::smatch m; - if (std::regex_match(lexeme, m, uniqueRegex)) { - std::string edgeType = m[1]; - - if(allTest.find(edgeType) == allTest.end()){ - - //if the key is not linked to a condition - //by default, it is initialized by a edge that is always false - return std::make_shared<FsmEdgeNone>(source, dest); - //throw std::invalid_argument("Bad Node Test " + edgeType ); - } - - return std::make_shared<FsmEdgeUnique>(source, dest, allTest.at(edgeType)); - } else { - throw std::invalid_argument("error lexem UNIQUE \"" + std::string(lexeme) +" eee\""); - } - } else { - throw std::invalid_argument("Bad edge Type"); - } - } \ No newline at end of file diff --git a/src/graphRegex/matchFsm/FsmGraph.cpp b/src/graphRegex/matchFsm/FsmGraph.cpp deleted file mode 100644 index 6bec61664e8c13601795f6c4f5fae9364ddce5c8..0000000000000000000000000000000000000000 --- a/src/graphRegex/matchFsm/FsmGraph.cpp +++ /dev/null @@ -1,225 +0,0 @@ -/******************************************************************************** - * 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 "aidge/graphRegex/matchFsm/FsmGraph.hpp" - -#include <memory> -#include <string> -#include <vector> - -#include <fmt/format.h> - -using namespace Aidge; - - - -FsmGraph::FsmGraph(const std::string query):mQuery(query){ - -} - -//TODO - std::vector<std::shared_ptr<MatchSolution>> FsmGraph::test(const std::vector<NodePtr>& startNodes){ - - std::vector<std::shared_ptr<Aidge::FsmNode>> startNodesFsm = getStartNodes(); - if(startNodes.size() != startNodesFsm.size()){ - throw std::runtime_error("bad number of Start nodes"); - } - - std::vector<std::shared_ptr<FsmRunTimeContext>> walks; - for(std::size_t i = 0; i < startNodes.size(); i++){ - walks.push_back(std::make_shared<FsmRunTimeContext>(startNodesFsm[i],startNodes[i])); - } - std::vector<std::shared_ptr<FsmRunTimeContext>> nextWalks; - - std::vector<std::shared_ptr<FsmRunTimeContext>> allValidContext; - std::vector<std::shared_ptr<FsmRunTimeContext>> allContextSee; - - - - - while (!walks.empty()) - { - for(auto fsmContext : walks){ - allContextSee.push_back(fsmContext); - //if we are in a valid st we save it - //it's one solution of the possible solution of the matching - if(fsmContext->isOnValidState()){ - //not save 2 time the same end point - if(!std::any_of(allValidContext.begin(), allValidContext.end(), - [&](std::shared_ptr<Aidge::FsmRunTimeContext> oldValid) { - return fsmContext->areEqual(oldValid); - })){ - allValidContext.push_back(fsmContext); - } - - } - - //don't test 2 time a fsmContext - std::vector<std::shared_ptr<FsmRunTimeContext>> tmpNextWalks = fsmContext->getActState()->test(fsmContext); - for(auto PotentialFsmContext : tmpNextWalks){ - - if(!std::any_of(allContextSee.begin(), allContextSee.end(), - [&](std::shared_ptr<Aidge::FsmRunTimeContext> oldSee) { - return PotentialFsmContext->areEqual(oldSee); - })){ - nextWalks.push_back(PotentialFsmContext); - } - } - - } - walks.swap(nextWalks); - nextWalks.clear(); - } - - MatchResult allMatch(allValidContext,getNbSubFsm(),mQuery,startNodes); - return allMatch.getSolutions(); - -} - - -/////////////// -// FSM construction -/////////////// -const std::set<std::shared_ptr<FsmEdge>>& FsmGraph::getEdge(void){ - return mEdges; -} - -void FsmGraph::addEdge(std::shared_ptr<FsmEdge>& edge){ - edge->updateWeak(); - mEdges.insert(edge); - mAllOrigin.insert(edge->getDestNode()->getOrigin()); - mAllOrigin.insert(edge->getSourceNode()->getOrigin()); -} - -const std::vector<std::shared_ptr<FsmNode>> FsmGraph::getStartNodes(void){ - std::set<std::shared_ptr<FsmNode>> nodes = getNodes(); - std::vector<std::shared_ptr<FsmNode>> startNodes; - for(auto node :nodes){ - if(node->isStart()){ - startNodes.push_back(node); - } - } - return startNodes; -} - -const std::set<std::shared_ptr<FsmNode>> FsmGraph::getValidNodes(void){ - std::set<std::shared_ptr<FsmNode>> nodes = getNodes(); - std::set<std::shared_ptr<FsmNode>> ValidNodes; - for(auto node :nodes){ - if(node->isValid()){ - ValidNodes.insert(node); - } - } - //may short - return ValidNodes; -} - -const std::set<std::shared_ptr<FsmNode>> FsmGraph::getNodes(void){ - std::set<std::shared_ptr<FsmNode>> nodes; - for(auto edge : mEdges){ - nodes.insert(edge->getDestNode()); - nodes.insert(edge->getSourceNode()); - } - return nodes; -} - -void FsmGraph::setGroupe(std::size_t groupeIdx){ - std::set<std::shared_ptr<FsmNode>> nodes = getNodes(); - for(auto node :nodes){ - node->setGroupe(groupeIdx); - } -} - -void FsmGraph::unionG(const std::shared_ptr<FsmGraph> fsmGraph){ - - for(auto edge : fsmGraph->getEdge()){ - addEdge(edge); - } -} - -void FsmGraph::mergeOneStartOneValid(const std::shared_ptr<FsmGraph> fsmGraph){ - std::set<std::shared_ptr<FsmNode>> validNodes = getValidNodes(); - std::vector<std::shared_ptr<FsmNode>> startNodes = fsmGraph->getStartNodes(); - - if (startNodes.size() != 1 || validNodes.size() != 1){ - throw std::runtime_error( - fmt::format("mergeOneStartOneValid start size: {} valid size: {} \ - can only merge FSM 1 start 1 valid", - startNodes.size(), - validNodes.size() - ) - ); - } - - unionG(fsmGraph); - //for loop useless but for future merge it's could be used - for(auto valid : validNodes){ - valid->invalid(); - for(auto start : startNodes){ - start->unStart(); - _mergeNode(start,valid); - } - } -} - -std::size_t FsmGraph::getNbSubFsm(void){ - return mAllOrigin.size(); -} - -std::size_t FsmGraph::getNbStart(void){ - return getStartNodes().size(); -} - -void FsmGraph::incOriginAllNodeBy(std::size_t incr){ - std::set<std::shared_ptr<FsmNode>> nodes = getNodes(); - for(auto node :nodes){ - node->incOrigin(incr); - } - std::set<std::size_t> updatedOrigin; - for(auto origin : mAllOrigin){ - updatedOrigin.insert(origin + incr); - } - mAllOrigin.swap(updatedOrigin); -} - -void FsmGraph::_mergeNode(std::shared_ptr<FsmNode> source,std::shared_ptr<FsmNode> dest){ - std::set<std::shared_ptr<FsmNode>> nodes = getNodes(); - - if(nodes.find(source) == nodes.end() || nodes.find(dest) == nodes.end()){ - throw std::runtime_error("FsmGraph can not merge node not in the graph"); - } - nodes.clear(); - - //probagate source attribute - if(source->isValid()){ - dest->valid(); - } - if(source->isStart()){ - dest->start(); - } - - //merge source to dest by replace source by dest in all EDGE - for(auto edge : mEdges){ - if(edge->getDestNode() == source ){ - edge->reSetDestNode(dest); - }else if(edge->getSourceNode() == source ){ - edge->reSetSourceNode(dest); - } - - } - //check is source is not in graph - nodes = getNodes(); - if(nodes.find(source) != nodes.end() ){ - throw std::runtime_error("FsmGraph merge node not effective"); - } - nodes.clear(); - -} diff --git a/src/graphRegex/matchFsm/FsmNode.cpp b/src/graphRegex/matchFsm/FsmNode.cpp deleted file mode 100644 index 6666d1a72a298f20bdae0eb1c51805e5ae133ba4..0000000000000000000000000000000000000000 --- a/src/graphRegex/matchFsm/FsmNode.cpp +++ /dev/null @@ -1,132 +0,0 @@ -#include "aidge/graphRegex/matchFsm/FsmNode.hpp" -#include "aidge/graphRegex/matchFsm/FsmEdge.hpp" -#include "aidge/graphRegex/matchFsm/FsmRunTimeContext.hpp" - -using namespace Aidge; - - - -FsmNode::FsmNode(bool isAValid,bool isAStart ){ - mIsAStart =isAStart; - mIsAValid =isAValid; - -} -const std::vector<std::shared_ptr<FsmRunTimeContext>> FsmNode::test( std::shared_ptr<FsmRunTimeContext> fsmContext){ - - - std::vector<std::shared_ptr<FsmRunTimeContext>> out; - - for(auto edge : mEdges){ - if (auto sharedEdge = edge.lock()) { - - std::shared_ptr<FsmNode> nextState = sharedEdge->getDestNode(); - - //make copy of the fsmContext - std::shared_ptr<FsmRunTimeContext> newFsmContext = std::make_shared<FsmRunTimeContext>(fsmContext); - - EdgeTestResult edgeRes = sharedEdge->test(newFsmContext); - - if(edgeRes.success){ - if(edgeRes.node.size() != 0){ - for(auto nextNode :edgeRes.node ){ - if(!newFsmContext->isAlreadyValid(nextNode)|| newFsmContext->isCommonDefined(nextNode) ){ - out.push_back( std::make_shared<FsmRunTimeContext>(newFsmContext,nextState,nextNode)); - - }else{ - out.push_back( std::make_shared<FsmRunTimeContext>(newFsmContext,nextState,nullptr)); - } - - } - }else{ - out.push_back( std::make_shared<FsmRunTimeContext>(newFsmContext,nextState,nullptr)); - } - } - newFsmContext.reset(); - - }else{ - throw std::runtime_error("test FsmNode weak pointer is expired" ); - } - - } - return out; -} - - - -std::size_t FsmNode::getOrigin(void){ - return mOriginFsm; -} -void FsmNode::incOrigin(std::size_t inc){ - mOriginFsm += inc; -} -void FsmNode::rmEdge(std::shared_ptr<FsmEdge> edge){ - mEdges.erase(edge); -} - -void FsmNode::addEdge(std::shared_ptr<FsmEdge> edge){ - std::weak_ptr<FsmEdge> edgeW(edge); - if (!edgeW.expired()) { - mEdges.insert(edgeW); - }else{ - throw std::runtime_error("addEdge FsmNode weak pointer is expired" ); - } -} - -// const std::set<std::shared_ptr<FsmNode>> FsmNode::getChildNodes(void){ -// std::set<std::shared_ptr<FsmNode>> children; -// for(auto edge : mEdges){ -// if (auto sharedEdge = edge.lock()) { -// children.insert(sharedEdge->getDestNode()); -// }else{ -// throw std::runtime_error("getChildNodes FsmNode weak pointer is expired" ); -// } -// } -// return children; -// } - - -const std::set<std::weak_ptr<FsmNode>,lex_compare<FsmNode>>& FsmNode::getParentNodes(void){ - return mParents; -} -const std::set<std::weak_ptr<FsmEdge>,lex_compare<FsmEdge>>& FsmNode::getEdges(void){ - return mEdges; -} - -void FsmNode::setGroupe(std::size_t groupeIdx){ - mGroupeFsm = groupeIdx; - -} - -bool FsmNode::isValid(void){ - return mIsAValid; -} -bool FsmNode::isStart(void){ - return mIsAStart; -} -void FsmNode::invalid(void){ - mIsAValid =false; -} -void FsmNode::valid(void){ - mIsAValid =true; -} -void FsmNode::unStart(void){ - mIsAStart =false; -} -void FsmNode::start(void){ - mIsAStart =true; -} - - - -void FsmNode::addParent(std::shared_ptr<FsmNode> node){ - - std::weak_ptr<FsmNode> nodeW(node); - if (!nodeW.expired()) { - mParents.insert(nodeW); - }else{ - throw std::runtime_error("addParent FsmNode weak pointer is expired" ); - } -} -void FsmNode::rmParent(std::shared_ptr<FsmNode> node){ - mParents.erase(node); -} \ No newline at end of file diff --git a/src/graphRegex/matchFsm/FsmRunTimeContext.cpp b/src/graphRegex/matchFsm/FsmRunTimeContext.cpp deleted file mode 100644 index 89e7faf205ef515049de415a5f057db8a13105e9..0000000000000000000000000000000000000000 --- a/src/graphRegex/matchFsm/FsmRunTimeContext.cpp +++ /dev/null @@ -1,217 +0,0 @@ -#include "aidge/graphRegex/matchFsm/FsmRunTimeContext.hpp" -#include "aidge/graphRegex/matchFsm/FsmNode.hpp" - -using namespace Aidge; - -std::vector<std::set<NodePtr>> FsmRunTimeContext::mRejectedNodes; - -FsmRunTimeContext::FsmRunTimeContext(std::shared_ptr<FsmNode> actState ,NodePtr actOpNode ,std::size_t idxRejeced ){ - mActOpNode = actOpNode; - mActState = actState; - - //not define case - if(idxRejeced == std::numeric_limits<std::size_t>::max()){ - mLocalIdxRejeced = mRejectedNodes.size(); - mRejectedNodes.push_back(std::set<NodePtr>()); - }else{ - if(idxRejeced > mRejectedNodes.size()-1 ){ - throw std::runtime_error("FsmRunTimeContext idxRejeced"); - } - mLocalIdxRejeced =idxRejeced; - } -} - - - -FsmRunTimeContext::FsmRunTimeContext(std::shared_ptr<FsmRunTimeContext> fsmRunTime){ - mActOpNode = fsmRunTime->mActOpNode; - mActState = fsmRunTime->mActState; - mCommonNodes = fsmRunTime->mCommonNodes; - mValidNodes = fsmRunTime->mValidNodes; - mLocalIdxRejeced = fsmRunTime->mLocalIdxRejeced; -} -FsmRunTimeContext::FsmRunTimeContext(std::shared_ptr<FsmRunTimeContext> fsmRunTime,std::shared_ptr<FsmNode> actState ,NodePtr actOpNode ){ - mActOpNode = actOpNode; - mActState = actState; - mCommonNodes = fsmRunTime->mCommonNodes; - mValidNodes = fsmRunTime->mValidNodes; - mLocalIdxRejeced = fsmRunTime->mLocalIdxRejeced; -} - -void FsmRunTimeContext::addRejectedNode(NodePtr node){ - mRejectedNodes[mLocalIdxRejeced].insert(node); -} - -bool FsmRunTimeContext::isOnValidState(void){ - return mActState->isValid(); -} - -bool FsmRunTimeContext::isCommonDefined(NodePtr node){ - //return mCommonNodes.find(node) != mCommonNodes.end(); - - std::set<NodePtr> nodes = getCommonNodes(); - for(const auto& nodeC : nodes){ - if(nodeC.get() == node.get()){ - return true; - } - } - return false; -} - -bool FsmRunTimeContext::isAlreadyValid(NodePtr node){ - - std::set<NodePtr> nodes = getValidNodes(); - for(const auto& nodeV : nodes){ - if(nodeV.get() == node.get()){ - return true; - } - } - return false; - - //return getValidNodes().find(node) != getValidNodes().end(); -} - -bool FsmRunTimeContext::areCompatible(std::shared_ptr<FsmRunTimeContext> fsmContext){ - /* - see if 2 context can be merge - it need to have different mValidNodes except for common - and the same idx for the common - */ - - //common node - - for (const auto& ref : getCommon()) { - for (const auto& test : fsmContext->getCommon()) { - //same index - if(ref.second == test.second){ - if(ref.first != test.first){ - return false; - } - } - } - } - - //valid nodes - std::set<NodePtr> commonElements; - 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()) - ); - - return (commonElements.empty()) ? true : false; -} - -bool FsmRunTimeContext::areEqual(std::shared_ptr<FsmRunTimeContext> fsmContext){ - if(getActNode() != fsmContext->getActNode()){ - return false; - } - if (getActState() != fsmContext->getActState()){ - return false; - } - if (getValidNodes() != fsmContext->getValidNodes()){ - return false; - } - if (getCommon() != fsmContext->getCommon()){ - return false; - } - - - return true; -} - -void FsmRunTimeContext::setCommon(NodePtr node,std::size_t commonIdx){ - if(isCommonDefined(node)){ - if (mCommonNodes.at(node) != commonIdx){ - throw std::runtime_error("conflict idx in the Common node"); - } - }else{ - mCommonNodes[node] = commonIdx; - } -} - -void FsmRunTimeContext::setValid(NodePtr node,std::shared_ptr<ConditionalInterpreter> tag){ - //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"); - } - mValidNodes[tag].insert(node); - }else{ - mValidNodes[tag] = {node}; - } - -} - -std::size_t FsmRunTimeContext::getSubStmId(void){ - return mActState->getOrigin(); -} - -NodePtr FsmRunTimeContext::getCommonNodeFromIdx(std::size_t commonIdx){ - for (const auto& pair : mCommonNodes) { - if (pair.second == commonIdx) { - return pair.first; // Return the key when the value is found - } - } - throw std::runtime_error("getCommonNodeFromIdx Value not found in the map"); -} - -std::size_t FsmRunTimeContext::getCommonNodeIdx(NodePtr node){ - if(isCommonDefined(node)){ - return mCommonNodes.at(node); - } - throw std::runtime_error("getCommonNodeIdx node not found"); -} - -std::set<NodePtr> FsmRunTimeContext::getCommonNodes(void){ - std::set<NodePtr> nodes; - // Iterate over the map and insert values into the set - for (const auto& pair : mCommonNodes) { - nodes.insert(pair.first); - } - return nodes; -} - -std::map<NodePtr,std::size_t> FsmRunTimeContext::getCommon(void){ - return mCommonNodes; -} - -std::set<NodePtr> FsmRunTimeContext::getValidNodes(void){ - - auto sharedSet = std::make_shared<std::set<NodePtr>>(); - // Create a set to store the values from the map - std::set<NodePtr> nodes; - // Iterate over the map and insert values into the set - for (const auto& pair : mValidNodes) { - nodes.insert(pair.second.begin(),pair.second.end()); - } - return nodes; -} - -std::set<NodePtr> FsmRunTimeContext::getValidNodesNoCommon(void){ - std::set<NodePtr> differenceSet; - std::set<NodePtr> valid = getValidNodes(); - std::set<NodePtr> common = getCommonNodes(); - std::set_difference(valid.begin(), valid.end(), common.begin(), common.end(),std::inserter(differenceSet, differenceSet.end())); - return differenceSet; -} - -std::map<std::shared_ptr<ConditionalInterpreter>,std::set<NodePtr>>& FsmRunTimeContext::getValid(void){ - return mValidNodes; -} - -NodePtr FsmRunTimeContext::getActNode(void){ - return mActOpNode; -} - -std::shared_ptr<FsmNode> FsmRunTimeContext::getActState(){ - return mActState; -} - - -void FsmRunTimeContext::rst(void){ - mRejectedNodes.clear(); -} - diff --git a/src/graphRegex/matchFsm/MatchResult.cpp b/src/graphRegex/matchFsm/MatchResult.cpp deleted file mode 100644 index 99df00e198a9a30be21e0ad18b4933a40b9b7a06..0000000000000000000000000000000000000000 --- a/src/graphRegex/matchFsm/MatchResult.cpp +++ /dev/null @@ -1,135 +0,0 @@ -#include <algorithm> // set_intersection, std::sort -#include <memory> -#include <set> -#include <string> -#include <vector> - -#include "aidge/graphRegex/matchFsm/MatchResult.hpp" - -Aidge::MatchSolution::MatchSolution(std::vector<std::shared_ptr<FsmRunTimeContext>>& precedence,const std::string query,const std::vector<NodePtr> startNode):mQueryFrom(query),mStartNode(startNode){ - //reformat the solution - for (const auto& context : precedence) { - for (const auto& pair : context->getValid()) { - - if(mSolution.find(pair.first->getKey()) == mSolution.end()){ - mSolution[pair.first->getKey()] = pair.second; - }else{ - mSolution[pair.first->getKey()].insert(pair.second.begin(), pair.second.end()); - } - } - } -} - -const std::set<Aidge::NodePtr> Aidge::MatchSolution::getAll(){ - - // Create a unique set to store all the elements - std::set<NodePtr> uniqueSet; - - // Iterate through the map and insert elements from each set into the unique set - for (const auto& pair : mSolution) { - const std::set<NodePtr>& nodeSet = pair.second; - - // Insert elements from the current set into the unique set - uniqueSet.insert(nodeSet.begin(), nodeSet.end()); - } - - return uniqueSet; -} - -bool Aidge::MatchSolution::areCompatible(std::shared_ptr<Aidge::MatchSolution> solution){ - std::set<NodePtr> set1 = solution->getAll(); - std::set<NodePtr> set2 = getAll(); - std::set<NodePtr> intersection ; - std::set_intersection(set1.begin(), set1.end(), set2.begin(), set2.end(), std::inserter(intersection, intersection.begin())); - return intersection.empty(); -} - - -//////////////////////////////// -// -//////////////////////////////// -Aidge::MatchResult::MatchResult(std::vector<std::shared_ptr<Aidge::FsmRunTimeContext>> allValid, - std::size_t nbSubStm, - const std::string& query, - const std::vector<Aidge::NodePtr>& startNodes) - : mIdToRunTime(nbSubStm), - mNbSubStm(nbSubStm) -{ - mAllValid = allValid; - - //mIdToRunTimm - for (const auto& contextPtr : allValid) { - mIdToRunTime[contextPtr->getSubStmId()].push_back(contextPtr); - } - - std::vector<std::shared_ptr<FsmRunTimeContext>> precedence; - //make all solution possible - _generateCombination(0,precedence,query,startNodes); - //sort by solution number of elements - std::sort(mSolve.begin(), mSolve.end(), [](std::shared_ptr<MatchSolution>& set1, std::shared_ptr<MatchSolution>& set2) { - return set1->getAll().size() < set2->getAll().size(); - }); -} - -void Aidge::MatchResult::_generateCombination( std::size_t idxSubStm, - std::vector<std::shared_ptr<Aidge::FsmRunTimeContext>>& precedence, - const std::string& query, - const std::vector<Aidge::NodePtr>& startNodes) -{ - //it's end , we are below the number of stm - if (idxSubStm == mNbSubStm) - { - //precedence contain a list of FSM compatible, we just need to - //check if all the nodes have been validated by at least one context - - //1) make the set of all node for the compute graph that are valid in all the FsmRunTimeContext - std::set<NodePtr> validNode; - std::set<NodePtr> rejectNode; - for (const auto& contextPtr : precedence) { - std::set<NodePtr> tmpV = contextPtr->getValidNodes(); - validNode.insert(tmpV.begin(), tmpV.end()); - std::set<NodePtr> tmpR = contextPtr->getRejectedNodes(); - rejectNode.insert(tmpR.begin(),tmpR.end()); - } - // 2) all RejectedNodes need to be valid by an others stm - // if it's not the case the match is not valid - if(std::includes(validNode.begin(), validNode.end(), rejectNode.begin(), rejectNode.end())){ - //we can save the solution - mSolve.push_back(std::make_shared<MatchSolution>(precedence,query,startNodes)); - } - precedence.pop_back(); - return; - } - - - for (const auto& contextPtrOneFsm : mIdToRunTime[idxSubStm]) - { - if(idxSubStm == 0){ - precedence.push_back(contextPtrOneFsm); - _generateCombination(idxSubStm+1,precedence,query,startNodes); - - }else{ - //test if the new context is compatible with all the context in the precedence - // - bool compatibleSolutionFsm = true; - for (const auto& contextPtrOfOtherFsm : precedence) { - if(!(contextPtrOneFsm->areCompatible(contextPtrOfOtherFsm))){ - compatibleSolutionFsm = false; - break; - } - } - - if(compatibleSolutionFsm){ - precedence.push_back(contextPtrOneFsm); - _generateCombination(idxSubStm+1,precedence,query,startNodes); - } - - } - } - - if(idxSubStm != 0){ - precedence.pop_back(); - } - return; - -} \ No newline at end of file diff --git a/src/nodeTester/ConditionalInterpreter.cpp b/src/nodeTester/ConditionalInterpreter.cpp deleted file mode 100644 index 8144237c3c1357829df4d357538f7d57a5c82a81..0000000000000000000000000000000000000000 --- a/src/nodeTester/ConditionalInterpreter.cpp +++ /dev/null @@ -1,376 +0,0 @@ -/******************************************************************************** - * 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 "aidge/nodeTester/ConditionalInterpreter.hpp" - -#include <memory> -#include <string> -#include <vector> - -#include <fmt/format.h> - -#include "aidge/graph/Node.hpp" - -using namespace Aidge; - - -/////////////////////////////// -//ConditionalRegisterFunction -/////////////////////////////// - - std::shared_ptr<ConditionalData> ConditionalRegisterFunction::run(const std::string key,std::vector< std::shared_ptr<ConditionalData>> & data){ - - auto lambdaIt = mWlambda.find(key); - if (lambdaIt != mWlambda.end()) { - return lambdaIt->second(data); - }else { - throw std::runtime_error("can not run Lambda due to invalid key: " + key); - } - } - - -////////////////////// -//ConditionalInterpreter -/////////////////////// - ConditionalInterpreter::ConditionalInterpreter(const std::string key,const std::string ConditionalExpressions) - :mLambdaRegister(),mKey(key) - { - - ConditionalParser conditionalParser = ConditionalParser(ConditionalExpressions); - mTree = conditionalParser.parse(); - - ///lambda by default - mLambdaRegister.insert("getType",+[](std::shared_ptr<Node> NodeOp){return NodeOp->type();}); - - } - - bool ConditionalInterpreter::isLambdaRegister(const std::string &key){ - return mLambdaRegister.isLambdaRegister(key); - } - - const std::string& ConditionalInterpreter::getKey(){ - return mKey; - } - - - bool ConditionalInterpreter::test( const std::shared_ptr<Node> nodeOp) - { - mResolution.clear(); - try{ - std::vector< std::shared_ptr<ConditionalData>> r = visit({mTree},nodeOp); - - if (mResolution.size() != 1){ - throw std::runtime_error("Multi output interpretation output"); - }else{ - if (!mResolution[0]->isTypeEqualTo<bool>()){ - throw std::runtime_error("TEST OUT MUST BE A BOOL "); - }else{ - return mResolution[0]->getValue<bool>(); - } - } - - } catch(const std::exception& e) { - throw std::runtime_error(fmt::format("Error in test\n\t{}\n", e.what())); - } - } - - void ConditionalInterpreter::insertLambda(const std::string key,std::function<bool(std::shared_ptr<Node>)> f){ - mLambdaRegister.insert<std::function<bool(std::shared_ptr<Node>)> >(key, f); - } - - ///// - std::vector< std::shared_ptr<ConditionalData>> ConditionalInterpreter::visit(const ASTNodeCh& nodes, const std::shared_ptr<Node> nodeOp ){ - std::vector< std::shared_ptr<ConditionalData>> dataVector; - - for ( std::shared_ptr<AstNode<ConditionalTokenTypes>> node : nodes) { - try{ - switch (node->getType()){ - /////////////////////////////////// - //OPERATOR - /////////////////////////////////// - case ConditionalTokenTypes::NOT: - { - visit(node->getChilds(),nodeOp); - fNot(); - } - break; - case ConditionalTokenTypes::AND: - { - visit(node->getChilds(),nodeOp); - fAnd(); - } - break; - case ConditionalTokenTypes::OR: - { - visit(node->getChilds(),nodeOp); - fOr(); - } - break; - case ConditionalTokenTypes::EQ: - { - visit(node->getChilds(),nodeOp); - fEq(); - //dataVector.insert(dataVector.end(), tmp.begin(), tmp.end()); - } - break; - case ConditionalTokenTypes::NEQ: - { - visit(node->getChilds(),nodeOp); - fNeq(); - } - break; - - /////////////////////////////////// - //VALUE - /////////////////////////////////// - - case ConditionalTokenTypes::KEY: - - break; - case ConditionalTokenTypes::INTEGER: - { - fStrToInteger(node); - } - break; - case ConditionalTokenTypes::FLOAT: - { - fStrToFloat(node); - - } - break; - case ConditionalTokenTypes::STRING: - { - fStrToStr(node); - } - break; - - case ConditionalTokenTypes::NODE: //TODO - { - - std::shared_ptr<ConditionalData> data = std::make_shared<ConditionalData>(); - data->setValue<std::shared_ptr<Node>>(nodeOp); - mResolution.push_back(data); - - } - break; - - case ConditionalTokenTypes::LAMBDA: - { - visit(node->getChilds(),nodeOp); - fLambda(node); - - } - break; - - case ConditionalTokenTypes::BOOL: //TODO - { - std::shared_ptr<ConditionalData> data = std::make_shared<ConditionalData>(); - - if(node->getValue() == "true"){ - data->setValue<bool>(true); - }else{ - data->setValue<bool>(false); - } - - mResolution.push_back(data); - - } - break; - - case ConditionalTokenTypes::ARGSEP: - case ConditionalTokenTypes::LPAREN: - case ConditionalTokenTypes::RPAREN: - case ConditionalTokenTypes::STOP: - default: - throw std::runtime_error("NODE TYPE NOT SUPPORTED IN ConditionalInterpreter"); - } - } catch(const std::exception& e) { - throw std::runtime_error(fmt::format("Error in visiting AST for node {}\n\t{}\n", nodeOp->name(), e.what())); - } - } - - return dataVector; - } - - - ////////////////////// - //value converter - ///////////////////// - - - void ConditionalInterpreter::fStrToInteger(const std::shared_ptr<AstNode<ConditionalTokenTypes>>& node) - { - std::shared_ptr<ConditionalData> data = std::make_shared<ConditionalData>(); - - data->setValue<int>(std::stoi(node->getValue())); - mResolution.push_back(data); - } - - void ConditionalInterpreter::fStrToFloat(const std::shared_ptr<AstNode<ConditionalTokenTypes>>& node) - { - - std::shared_ptr<ConditionalData> data = std::make_shared<ConditionalData>(); - data->setValue<float>(std::stof(node->getValue())); - mResolution.push_back(data); - } - - void ConditionalInterpreter::fStrToStr(const std::shared_ptr<AstNode<ConditionalTokenTypes>>& node) - { - std::shared_ptr<ConditionalData> data = std::make_shared<ConditionalData>(); - data->setValue<std::string>(node->getValue()); - mResolution.push_back(data); - } - - void ConditionalInterpreter::fLambda(const std::shared_ptr<AstNode<ConditionalTokenTypes>>& node) - { - //if the lambda have input - std::shared_ptr<ConditionalData> data; - try { - data = mLambdaRegister.run(node->getValue(),mResolution); - } catch (const std::exception& e) { - throw std::runtime_error(fmt::format("Error in conditional interpretation when run the {} Lambda {}\n", node->getValue(), e.what())); - } - - //clearRes(); - mResolution.push_back(data); - } - - void ConditionalInterpreter::fEq(void) - { - if (mResolution.size() < 2){ - throw std::runtime_error("EQ need 2 arg and get :" + std::to_string(mResolution.size())); - } - auto a = mResolution.back(); - mResolution.pop_back(); - auto b = mResolution.back(); - mResolution.pop_back(); - - - if (a->getType() != b->getType()){ - throw std::runtime_error("EQ Unsupported between type :" + a->getType() +" "+ b->getType()); - } - - - - std::shared_ptr<ConditionalData> data = std::make_shared<ConditionalData>(); - - if (a->isTypeEqualTo<int>()) { - data->setValue<bool>( a->getValue<int>() == b->getValue<int>()); - }else if (a->isTypeEqualTo<float>()){ - data->setValue<bool>( a->getValue<float>() == b->getValue<float>()); - }else if (a->isTypeEqualTo<std::string>()){ - data->setValue<bool>( a->getValue<std::string>() == b->getValue<std::string>()); - }else if (a->isTypeEqualTo<bool>()){ - data->setValue<bool>( a->getValue<bool>() == b->getValue<bool>()); - }else{ - throw std::runtime_error("EQ Unknown type encountered :" + a->getType() ); - } - - - mResolution.push_back(data); - } - - void ConditionalInterpreter::fNeq(void) - { - if (mResolution.size() < 2){ - throw std::runtime_error("NEQ need 2 arg and get :" + std::to_string(mResolution.size())); - } - auto a = mResolution.back(); - mResolution.pop_back(); - auto b = mResolution.back(); - mResolution.pop_back(); - - if (a->getType() != b->getType()){ - throw std::runtime_error("NEQ Unsupported between type :" + a->getType() +" "+ b->getType()); - } - - std::shared_ptr<ConditionalData> data = std::make_shared<ConditionalData>(); - - if (a->isTypeEqualTo<int>()) { - data->setValue<bool>( a->getValue<int>() != b->getValue<int>()); - }else if (a->isTypeEqualTo<float>()){ - data->setValue<bool>( a->getValue<float>() != b->getValue<float>()); - }else if (a->isTypeEqualTo<std::string>()){ - data->setValue<bool>( a->getValue<std::string>() != b->getValue<std::string>()); - }else - { - throw std::runtime_error("NEQ Unknown type encountered :" + a->getType() ); - } - - - mResolution.push_back(data); - } - - void ConditionalInterpreter::fAnd(void) - { - if (mResolution.size() < 2){ - throw std::runtime_error("AND need 2 arg and get :" + std::to_string(mResolution.size())); - } - auto a = mResolution.back(); - mResolution.pop_back(); - auto b = mResolution.back(); - mResolution.pop_back(); - - - if (a->getType() != typeid(bool).name() || b->getType() != typeid(bool).name()){ - throw std::runtime_error("AND Unknown type encountered need bool get :" + a->getType() ); - } - - std::shared_ptr<ConditionalData> data = std::make_shared<ConditionalData>(); - data->setValue<bool>( a->getValue<bool>() && b->getValue<bool>()); - - - - mResolution.push_back(data); - } - - void ConditionalInterpreter::fOr(void) - { - if (mResolution.size() < 2){ - throw std::runtime_error("OR need 2 arg and get :" + std::to_string(mResolution.size())); - } - auto a = mResolution.back(); - mResolution.pop_back(); - auto b = mResolution.back(); - mResolution.pop_back(); - - - if (a->getType() != typeid(bool).name() || b->getType() != typeid(bool).name()){ - throw std::runtime_error("OR Unknown type encountered need bool get :" + a->getType() ); - } - - std::shared_ptr<ConditionalData> data = std::make_shared<ConditionalData>(); - data->setValue<bool>( a->getValue<bool>() || b->getValue<bool>()); - - - - mResolution.push_back(data); - } - - void ConditionalInterpreter::fNot() - { - if (mResolution.size() < 1){ - throw std::runtime_error("NOT need 1 arg and get :" + std::to_string(mResolution.size())); - } - auto a = mResolution.back(); - mResolution.pop_back(); - - if (a->getType() != typeid(bool).name()){ - throw std::runtime_error("NOT Unknown type encountered need bool get :" + a->getType() ); - } - - std::shared_ptr<ConditionalData> data = std::make_shared<ConditionalData>(); - data->setValue<bool>( !a->getValue<bool>() ); - - - mResolution.push_back(data); - - } diff --git a/src/nodeTester/ConditionalLexer.cpp b/src/nodeTester/ConditionalLexer.cpp deleted file mode 100644 index a44ca2bd9080131da65b10b5c48a9cf30384ef68..0000000000000000000000000000000000000000 --- a/src/nodeTester/ConditionalLexer.cpp +++ /dev/null @@ -1,256 +0,0 @@ -/******************************************************************************** - * 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 "aidge/nodeTester/ConditionalLexer.hpp" - -#include <memory> -#include <regex> -#include <string> - -using namespace Aidge; - -////////////////// -//ConditionalLexer -////////////////// - - -ConditionalLexer::ConditionalLexer( const std::string ConditionalExpressions): -mConditionalExpressions(ConditionalExpressions) -{ - mPosition = 0; -} - -std::shared_ptr<ParsingToken<ConditionalTokenTypes>> ConditionalLexer::getNextToken(void){ - std::string currentChars = ""; - - while (mPosition < mConditionalExpressions.length()) - { - //erase all space - if (mConditionalExpressions[mPosition] != ' ') - { - currentChars += mConditionalExpressions[mPosition]; - } - else - { - mPosition++; - continue; - } - //perform tokenisation, find a regex and make a new token - - if (std::regex_match(currentChars,std::regex("\\&\\&")))// the AND TOKEN - { - mPosition++; - return std::make_shared<ParsingToken<ConditionalTokenTypes>>(ConditionalTokenTypes::AND,""); - } - else if (std::regex_match(currentChars,std::regex("\\|\\|")))// the OR TOKEN - { - mPosition++; - return std::make_shared<ParsingToken<ConditionalTokenTypes>>(ConditionalTokenTypes::OR,""); - } - else if (std::regex_match(currentChars,std::regex("\\!")))// the Not and not equ - { - mPosition++; - if ( mPosition < mConditionalExpressions.length()){ - currentChars += mConditionalExpressions[mPosition]; - if(std::regex_match(currentChars,std::regex("!="))){ - mPosition++; - return std::make_shared<ParsingToken<ConditionalTokenTypes>>(ConditionalTokenTypes::NEQ,""); - }else{ - return std::make_shared<ParsingToken<ConditionalTokenTypes>>(ConditionalTokenTypes::NOT,""); - } - } - //a not at the end not ok but it's the parseur work - return std::make_shared<ParsingToken<ConditionalTokenTypes>>(ConditionalTokenTypes::NOT,""); - } - else if (std::regex_match(currentChars,std::regex("==")))// the EQ TOKEN - { - mPosition++; - return std::make_shared<ParsingToken<ConditionalTokenTypes>>(ConditionalTokenTypes::EQ,""); - } - else if (std::regex_match(currentChars,std::regex("\\(")))// the LPAREN TOKEN - { - mPosition++; - return std::make_shared<ParsingToken<ConditionalTokenTypes>>(ConditionalTokenTypes::LPAREN,""); - } - else if (std::regex_match(currentChars,std::regex("\\)")))// the RPAREN TOKEN - { - mPosition++; - return std::make_shared<ParsingToken<ConditionalTokenTypes>>(ConditionalTokenTypes::RPAREN,""); - } - else if (std::regex_match(currentChars,std::regex(",")))// the RPAREN TOKEN - { - mPosition++; - return std::make_shared<ParsingToken<ConditionalTokenTypes>>(ConditionalTokenTypes::ARGSEP,""); - } - else if (std::regex_match(currentChars,std::regex("\\$")))// the ACTNode TOKEN - { - mPosition++; - return std::make_shared<ParsingToken<ConditionalTokenTypes>>(ConditionalTokenTypes::NODE,""); - } - - - ///// - //non const lent token - ///// - - //LAMBDA, KEY , bool //the function TAG - else if (std::regex_match(currentChars,std::regex("[A-Za-z_]")))// the KEY TOKEN (a char next ) - { - //read all the key - bool isLambda = false; - std::regex keyRegex("[A-Za-z_0-9]+"); - std::regex LambdaRegex("[A-Za-z_0-9]+\\("); - - while ( mPosition < mConditionalExpressions.length()) { - if(!std::regex_match(currentChars,keyRegex) && !std::regex_match(currentChars,LambdaRegex)) - { - currentChars.pop_back(); //the last char is the problems - break; - } - else if (std::regex_match(currentChars,LambdaRegex)){ - isLambda = true; - } - mPosition++; - if (mPosition < mConditionalExpressions.length()) currentChars += mConditionalExpressions[mPosition]; - //currentChars += mConditionalExpressions[mPosition]; - } - //we end the match 2 possibility - //we are at the end of the mConditionalExpressions and we need to ensure the match - //we are not we can continu - if (mPosition == mConditionalExpressions.length()-1) - { - if (!std::regex_match(currentChars,keyRegex) && !std::regex_match(currentChars,LambdaRegex)) - { - throw badTokenError(currentChars,mPosition); - } - //mPosition++; // we stop all by going pos > length - } - - - if (std::regex_match(currentChars,std::regex("(true|false|True|False)"))){ - return std::make_shared<ParsingToken<ConditionalTokenTypes>>(ConditionalTokenTypes::BOOL,currentChars); - - } else if (isLambda){ - currentChars.pop_back();//pop the ( of the lambda - return std::make_shared<ParsingToken<ConditionalTokenTypes>>(ConditionalTokenTypes::LAMBDA,currentChars); - } else{ - return std::make_shared<ParsingToken<ConditionalTokenTypes>>(ConditionalTokenTypes::KEY,currentChars); - } - - } - //numeric value - else if (std::regex_match(currentChars,std::regex("[0-9]")))// the KEY TOKEN (a char next ) - { - //read all the key - bool isFloat = false; - std::regex integerRegex("[0-9]+$"); - std::regex floatRegex("[0-9]+\\.[0-9]*$"); - - while ( mPosition < mConditionalExpressions.length()) { - - if(!std::regex_match(currentChars,integerRegex) && !std::regex_match(currentChars,floatRegex)) - { - currentChars.pop_back(); // the last char match is not a good one - break; - } - else if (std::regex_match(currentChars,floatRegex)){ - isFloat = true; - } - mPosition++; - if (mPosition < mConditionalExpressions.length()) currentChars += mConditionalExpressions[mPosition]; - //currentChars += mConditionalExpressions[mPosition]; - } - //we end the match 2 possibility - //we are at the end of the mConditionalExpressions and we need to ensure the match - //we are not we can continu - if (mPosition == mConditionalExpressions.length()-1) - { - if (!std::regex_match(currentChars,integerRegex) && !std::regex_match(currentChars,floatRegex)) - { - throw badTokenError(currentChars,mPosition); - } - } - - if(isFloat){ - return std::make_shared<ParsingToken<ConditionalTokenTypes>>(ConditionalTokenTypes::FLOAT,currentChars); - }else{ - return std::make_shared<ParsingToken<ConditionalTokenTypes>>(ConditionalTokenTypes::INTEGER,currentChars); - } - - } - //string TODO - else if (std::regex_match(currentChars,std::regex("\'"))) // TODO ' or \' - { - std::regex strRegex("\'[A-Za-z_0-9\\s]*\'$"); - while ( mPosition < mConditionalExpressions.length()) { - if(std::regex_match(currentChars,strRegex)){ - break; - } - mPosition++; - if (mPosition < mConditionalExpressions.length()) currentChars += mConditionalExpressions[mPosition]; - //currentChars += mConditionalExpressions[mPosition]; - } - - //test the end condition - if (mPosition == mConditionalExpressions.length()-1 ){ - if (!std::regex_match(currentChars,strRegex)){ - throw badTokenError(currentChars,mPosition); - } - //mPosition++; // we stop all by going pos > length - } - - mPosition++; // go after the last " - //erase the " char - currentChars.pop_back(); - currentChars.erase(0,1); - - return std::make_shared<ParsingToken<ConditionalTokenTypes>>(ConditionalTokenTypes::STRING,currentChars); - - } - - //Array TODO - - mPosition++; - } - - //no more to find no one match the currentChars - if (currentChars.empty()) { - return std::make_shared<ParsingToken<ConditionalTokenTypes>>(ConditionalTokenTypes::STOP,""); // Null shared pointer ; - } else { - //std::ostringstream errorMessage; - //errorMessage << "\nBad syntax " << currentChars << " :\n" << mConditionalExpressions; - throw badTokenError(currentChars,mPosition); - } - -} - -void ConditionalLexer::rstPosition(void){ - if (isEnd()){ - mPosition = 0; - }else{ - throw badTokenError("end rst",mPosition); - } - -} - -bool ConditionalLexer::isEnd(void){ - return mPosition >= mConditionalExpressions.length(); -} - -std::runtime_error ConditionalLexer::badTokenError(const std::string& currentChars, std::size_t position) { - return std::runtime_error(fmt::format( - "\nBad syntax {}:\n{}\n{:>{}}\n", - currentChars, - mConditionalExpressions, - "^", - position + 1 - )); -} \ No newline at end of file diff --git a/src/nodeTester/ConditionalParser.cpp b/src/nodeTester/ConditionalParser.cpp deleted file mode 100644 index cd7877a139a59a3e26b81cfbfdbd3e528f5478de..0000000000000000000000000000000000000000 --- a/src/nodeTester/ConditionalParser.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/******************************************************************************** - * 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 "aidge/nodeTester/ConditionalParser.hpp" - -#include <memory> -#include <stdexcept> -#include <vector> - -#include <fmt/format.h> - -////////////////////////////// -//ConditionalParser -////////////////////////////// - -Aidge::ConditionalParser::ConditionalParser(const std::string ConditionalExpressions) - : mLexer(ConditionalExpressions) -{ - mCurrentToken = mLexer.getNextToken(); -} - -Aidge::ConditionalParser::~ConditionalParser() noexcept = default; - -void Aidge::ConditionalParser::rstParser(void) { - mLexer.rstPosition(); - mCurrentToken = mLexer.getNextToken(); -} - -void Aidge::ConditionalParser::ackToken(ConditionalTokenTypes tokenType) { - if(mCurrentToken->getType() == tokenType ){ - try { - mCurrentToken = mLexer.getNextToken(); - } catch (const std::runtime_error& e) { - throw std::runtime_error(fmt::format("Conditional Lexer error in Parser :\n{}\n", e.what())); - } - } else { - throw std::runtime_error( - fmt::format("Bad syntax ConditionalParser {} != {}\n", - static_cast<int>(mCurrentToken->getType()), - static_cast<int>(tokenType), - mLexer.rep() - ) - ); - } -} - - - -std::shared_ptr<Aidge::AstNode<Aidge::ConditionalTokenTypes>> Aidge::ConditionalParser::constructAstVal(void) { - /* - val : (KEY|INTEGER|FOAT|STRING|LAMBDA) - */ - std::shared_ptr<ParsingToken<ConditionalTokenTypes>> token = mCurrentToken->copy(); - - if (token->getType() == ConditionalTokenTypes::KEY){ - ackToken(ConditionalTokenTypes::KEY); - return std::make_shared<AstNode<ConditionalTokenTypes>>(token); - } - else if(token->getType() == ConditionalTokenTypes::INTEGER){ - ackToken(ConditionalTokenTypes::INTEGER); - return std::make_shared<AstNode<ConditionalTokenTypes>>(token); - } - else if(token->getType() == ConditionalTokenTypes::FLOAT){ - ackToken(ConditionalTokenTypes::FLOAT); - return std::make_shared<AstNode<ConditionalTokenTypes>>(token); - } - else if(token->getType() == ConditionalTokenTypes::BOOL){ - ackToken(ConditionalTokenTypes::BOOL); - return std::make_shared<AstNode<ConditionalTokenTypes>>(token); - } - else if(token->getType() == ConditionalTokenTypes::STRING){ - ackToken(ConditionalTokenTypes::STRING); - return std::make_shared<AstNode<ConditionalTokenTypes>>(token); - - }else if(token->getType() == ConditionalTokenTypes::NODE){ - ackToken(ConditionalTokenTypes::NODE); - return std::make_shared<AstNode<ConditionalTokenTypes>>(token); - - }else if(token->getType() == ConditionalTokenTypes::LAMBDA){ - return constructAstLambda(); - } - - throw std::runtime_error(fmt::format("ConditionalParser unknown val type {}\n{}"+ token->rep(), mLexer.rep())); - -} - -std::shared_ptr<Aidge::AstNode<Aidge::ConditionalTokenTypes>> Aidge::ConditionalParser::constructAstLambda(void){ - /* - AstLambda : LAMBDA val (ARGSEP val)* RPAREN - */ - std::shared_ptr<ParsingToken<ConditionalTokenTypes>> tokenLdb = mCurrentToken->copy(); - ackToken(ConditionalTokenTypes::LAMBDA); - ASTNodeCh paramLambda; - //AT LEAST ONE VALUE AS INPUT OF A LAMBDA - paramLambda.push_back(constructAstVal()); - while (mCurrentToken->getType() != ConditionalTokenTypes::RPAREN) - { - ackToken(ConditionalTokenTypes::ARGSEP); - paramLambda.push_back(constructAstVal()); - } - ackToken(ConditionalTokenTypes::RPAREN); - return std::make_shared<AstNode<ConditionalTokenTypes>>(tokenLdb,paramLambda); -} - -std::shared_ptr<Aidge::AstNode<Aidge::ConditionalTokenTypes>> Aidge::ConditionalParser::constructAstCmpr(void){ - /* - cmpr : val (EQ|NEQ) val | LPAREN expr RPAREN - NOT ir ? - */ - std::shared_ptr<ParsingToken<ConditionalTokenTypes>> token = mCurrentToken->copy(); - //we can check the type relation ir key (EQ|NEQ) val | val (EQ|NEQ) key , but val (EQ|NEQ) val is valid ? - if (token->getType() == ConditionalTokenTypes::LPAREN) - { - ackToken(ConditionalTokenTypes::LPAREN); - std::shared_ptr<AstNode<ConditionalTokenTypes>> node = constructAstExpr(); - ackToken(ConditionalTokenTypes::RPAREN); - return node; - }else{ - - std::shared_ptr<AstNode<ConditionalTokenTypes>> node = constructAstVal(); - token = mCurrentToken->copy(); - if (token->getType() == ConditionalTokenTypes::EQ){ - ackToken(ConditionalTokenTypes::EQ); - return std::make_shared<AstNode<ConditionalTokenTypes>>(token,ASTNodeCh{node,constructAstVal()}); - }else if(token->getType() == ConditionalTokenTypes::NEQ){ - ackToken(ConditionalTokenTypes::NEQ); - return std::make_shared<AstNode<ConditionalTokenTypes>>(token,ASTNodeCh{node,constructAstVal()}); - }else{ - - throw std::runtime_error(fmt::format("constructAstCmpr {}\n{}", token->rep(), mLexer.rep())); - } - - } -} - -std::shared_ptr<Aidge::AstNode<Aidge::ConditionalTokenTypes>> Aidge::ConditionalParser::constructAstExpr(std::size_t precLimit /*= 0*/){ - /* - expr : cmpr ((AND | OR) cmpr)* - the NOT is not binary OP can be use in pratt - precedence H to L: TODO - AND - OR - */ - - //the not - std::shared_ptr<AstNode<ConditionalTokenTypes>> left; - std::shared_ptr<ParsingToken<ConditionalTokenTypes>> token = mCurrentToken->copy(); - - if (mCurrentToken->getType() == ConditionalTokenTypes::NOT ){ - ackToken(ConditionalTokenTypes::NOT ); - left= std::make_shared<AstNode<ConditionalTokenTypes>>(token,ASTNodeCh{constructAstCmpr()}); - }else{ - left= constructAstCmpr(); - } - - //pratt - while (mCurrentToken->getType() != ConditionalTokenTypes::STOP ) //security - { - token = mCurrentToken->copy(); - //if the token is not in the map is not a operator so we consider a prec of 0 - if (ConditionalPrec.find(token->getType()) ==ConditionalPrec.end() ){ - return left; - } - - //if my actual operator have a prec <= of the last operator - std::size_t prec = ConditionalPrec.at(token->getType()); - if (prec <= precLimit){ - return left; - } - - //Act all AND and OR - ackToken(token->getType()); - - std::shared_ptr<AstNode<ConditionalTokenTypes>> right = constructAstExpr(prec); - - //i'm not sure what append to newNode - //std::shared_ptr<AstNode<ConditionalTokenTypes>> newNode = std::make_shared<AstNode<ConditionalTokenTypes>>(token,ASTNodeCh{left,constructAstCmpr()}); - std::shared_ptr<AstNode<ConditionalTokenTypes>> newNode = std::make_shared<AstNode<ConditionalTokenTypes>>(token,ASTNodeCh{left,right}); - left = newNode; - } - return left; -} - - -std::shared_ptr<Aidge::AstNode<Aidge::ConditionalTokenTypes>> Aidge::ConditionalParser::parse(void){ - /* - expr : cmpr ((AND | OR) cmpr)* - cmpr : val (EQ|NEQ) val | LPAREN expr RPAREN | BOOL | LAMBDA - val : (KEY|INTEGER|FOAT|STRING|LAMBDA) - lambda : LAMBDA val (ARGSEP val)* RPAREN - */ - std::shared_ptr<AstNode<ConditionalTokenTypes>> astTree = constructAstExpr(); - - rstParser(); - return astTree; -} \ No newline at end of file diff --git a/src/recipes/RemoveFlatten.cpp b/src/recipes/RemoveFlatten.cpp index bf80ab51749953a5b72d0e01f186265fdbb72e81..5a04746e19f18e65ea601d823cbc9f0e7de7199c 100644 --- a/src/recipes/RemoveFlatten.cpp +++ b/src/recipes/RemoveFlatten.cpp @@ -14,13 +14,8 @@ #include "aidge/graph/Node.hpp" #include "aidge/graph/GraphView.hpp" #include "aidge/recipes/Recipes.hpp" - - -//Graph Regex -// #include "aidge/graphRegex/GraphRegex.hpp" #include "aidge/graph/Matching.hpp" - namespace Aidge { void removeFlatten(std::shared_ptr<GraphView> graphView){ const auto matches = SinglePassGraphMatching(graphView).match( diff --git a/src/recipes/removeConstantOfShape.cpp b/src/recipes/removeConstantOfShape.cpp index 5e84f7b494815ecb5a8937bb6f76ba1de80ad3f9..e743050c2c0f13513f639a0690943e0d934f947d 100644 --- a/src/recipes/removeConstantOfShape.cpp +++ b/src/recipes/removeConstantOfShape.cpp @@ -34,9 +34,6 @@ #include "aidge/utils/ErrorHandling.hpp" #include "aidge/utils/Types.h" -// Graph Regex -#include "aidge/graphRegex/GraphRegex.hpp" - namespace Aidge { size_t removeConstantOfShape(std::shared_ptr<GraphView> graph_view) { diff --git a/unit_tests/CMakeLists.txt b/unit_tests/CMakeLists.txt index f8e8097470423b4eee64e7d8dc87bf88218f3264..8c9a6ad8d38f301ce638ce2e808a88c534c09ca0 100644 --- a/unit_tests/CMakeLists.txt +++ b/unit_tests/CMakeLists.txt @@ -17,8 +17,6 @@ endif() file(GLOB_RECURSE src_files "*.cpp") -#file(GLOB_RECURSE src_files "graphRegex/Test_GraphRegex.cpp") - add_executable(tests${module_name} ${src_files}) target_compile_features(tests${module_name} PRIVATE cxx_std_14) diff --git a/unit_tests/graphRegex/Test_Fsm.cpp b/unit_tests/graphRegex/Test_Fsm.cpp deleted file mode 100644 index c011a50455e9e21f3df66c3ed46a835bed5346b3..0000000000000000000000000000000000000000 --- a/unit_tests/graphRegex/Test_Fsm.cpp +++ /dev/null @@ -1,195 +0,0 @@ -#include <memory> - -#include <catch2/catch_test_macros.hpp> - -#include "aidge/nodeTester/ConditionalInterpreter.hpp" - -#include "aidge/graphRegex/matchFsm/FsmNode.hpp" -#include "aidge/graphRegex/matchFsm/FsmEdge.hpp" -#include "aidge/graphRegex/matchFsm/FsmGraph.hpp" -#include "aidge/graphRegex/matchFsm/FsmRunTimeContext.hpp" - -using namespace Aidge; - -TEST_CASE("matchFSM", "FsmEdge") { - - - std::shared_ptr<FsmNode> nodeA = std::make_shared<FsmNode>(true,false); - std::shared_ptr<FsmNode> nodeB = std::make_shared<FsmNode>(false,true); - std::shared_ptr<ConditionalInterpreter> toTest = std::make_shared<ConditionalInterpreter>("A","true==true"); - FsmEdgeUnique EdgeToTest(nodeA,nodeB,toTest); - - SECTION("FsmEdgeUnique constructor") { - REQUIRE(EdgeToTest.getSourceNode() == nodeA); - REQUIRE(EdgeToTest.getDestNode() == nodeB); - REQUIRE(EdgeToTest.isCommon() == false); - } - - SECTION("FsmEdgeCommon constructor") { - std::shared_ptr<FsmNode> nodeA = std::make_shared<FsmNode>(true,false); - std::shared_ptr<FsmNode> nodeB = std::make_shared<FsmNode>(false,true); - std::shared_ptr<ConditionalInterpreter> toTest = std::make_shared<ConditionalInterpreter>("A","true==true"); - - FsmEdgeCommon EdgeToTest(nodeA,nodeB,toTest,"A"); - - REQUIRE(EdgeToTest.getSourceNode() == nodeA); - REQUIRE(EdgeToTest.getDestNode() == nodeB); - REQUIRE(EdgeToTest.isCommon() == true); - } - - SECTION("FsmEdgeRef constructor") { - std::shared_ptr<FsmNode> nodeA = std::make_shared<FsmNode>(true,false); - std::shared_ptr<FsmNode> nodeB = std::make_shared<FsmNode>(false,true); - std::shared_ptr<ConditionalInterpreter> toTest = std::make_shared<ConditionalInterpreter>("A","true==true"); - - FsmEdgeRef EdgeToTest(nodeA,nodeB,0,-1); - - REQUIRE(EdgeToTest.getSourceNode() == nodeA); - REQUIRE(EdgeToTest.getDestNode() == nodeB); - REQUIRE(EdgeToTest.isCommon() == false); - } - - SECTION("FsmEdgeEmpty constructor") { - std::shared_ptr<FsmNode> nodeA = std::make_shared<FsmNode>(true,false); - std::shared_ptr<FsmNode> nodeB = std::make_shared<FsmNode>(false,true); - std::shared_ptr<ConditionalInterpreter> toTest = std::make_shared<ConditionalInterpreter>("A","true==true"); - - FsmEdgeEmpty EdgeToTest(nodeA,nodeB); - - REQUIRE(EdgeToTest.getSourceNode() == nodeA); - REQUIRE(EdgeToTest.getDestNode() == nodeB); - REQUIRE(EdgeToTest.isCommon() == false); - } - - - SECTION("FsmEdgeFactory"){ - - std::map<std::string, std::shared_ptr<ConditionalInterpreter>> allTest = { - {"A",std::make_shared<ConditionalInterpreter>("A","true==true")}, - {"B",std::make_shared<ConditionalInterpreter>("B","true==true")}, - {"C",std::make_shared<ConditionalInterpreter>("C","true==true")} - }; - -// make(std::shared_ptr<FsmNode> source, std::shared_ptr<FsmNode> dest, -// FsmEdgeTypes type,std::map<std::string, const std::shared_ptr<ConditionalInterpreter>> allTest, -// const std::string& lexeme = ""); - - std::shared_ptr<FsmNode> nodeA = std::make_shared<FsmNode>(false,true); - std::shared_ptr<FsmNode> nodeB = std::make_shared<FsmNode>(true,false); -// EMPTY = 0, -// REF, -// COMMON, -// UNIQUE - - std::shared_ptr<FsmEdge> edgeE = FsmEdgeFactory::make(nodeA,nodeB,FsmEdgeTypes::EMPTY,allTest,""); - std::shared_ptr<FsmEdge> edgeU = FsmEdgeFactory::make(nodeA,nodeB,FsmEdgeTypes::UNIQUE,allTest,"A"); - std::shared_ptr<FsmEdge> edgeC = FsmEdgeFactory::make(nodeA,nodeB,FsmEdgeTypes::COMMON,allTest,"A#"); - std::shared_ptr<FsmEdge> edgeR = FsmEdgeFactory::make(nodeA,nodeB,FsmEdgeTypes::REF,allTest,"(0,1)"); - - //test detection of bad syntax lexem - REQUIRE_THROWS(FsmEdgeFactory::make(nodeA,nodeB,FsmEdgeTypes::EMPTY,allTest,"A")); - REQUIRE_THROWS(FsmEdgeFactory::make(nodeA,nodeB,FsmEdgeTypes::UNIQUE,allTest,"A#")); - REQUIRE_THROWS(FsmEdgeFactory::make(nodeA,nodeB,FsmEdgeTypes::COMMON,allTest,"A")); - REQUIRE_THROWS(FsmEdgeFactory::make(nodeA,nodeB,FsmEdgeTypes::REF,allTest,"A")); - - REQUIRE(edgeE->getSourceNode() == nodeA); - REQUIRE(edgeE->getDestNode() == nodeB); - } - - SECTION("graph constructor") { - //make the nodes - std::shared_ptr<FsmNode> nodeA = std::make_shared<FsmNode>(true,false); - std::shared_ptr<FsmNode> nodeB = std::make_shared<FsmNode>(false,false); - std::shared_ptr<FsmNode> nodeC = std::make_shared<FsmNode>(false,true); - - //make the edges - std::shared_ptr<ConditionalInterpreter> toTest = std::make_shared<ConditionalInterpreter>("A","true==true"); - std::shared_ptr<FsmEdge> edgeAB = std::make_shared<FsmEdgeUnique>(nodeA,nodeB,toTest); - std::shared_ptr<FsmEdge> edgeBC = std::make_shared<FsmEdgeUnique>(nodeB,nodeC,toTest); - - std::shared_ptr<FsmGraph> graph = std::make_shared<FsmGraph>(""); - - graph->addEdge(edgeAB); - graph->addEdge(edgeBC); - - - REQUIRE(graph->getValidNodes() == std::set<std::shared_ptr<FsmNode>>{nodeA}); - REQUIRE(graph->getStartNodes() == std::vector<std::shared_ptr<FsmNode>>{nodeC}); - } - - - SECTION("graph merge") { - - std::shared_ptr<ConditionalInterpreter> toTest = std::make_shared<ConditionalInterpreter>("A","true==true"); - - //make the nodes - std::shared_ptr<FsmNode> nodeA = std::make_shared<FsmNode>(false,true); - std::shared_ptr<FsmNode> nodeB = std::make_shared<FsmNode>(false,false); - std::shared_ptr<FsmNode> nodeC = std::make_shared<FsmNode>(true,false); - - //make the edges - - std::shared_ptr<FsmEdge> edgeAB = std::make_shared<FsmEdgeUnique>(nodeA,nodeB,toTest); - std::shared_ptr<FsmEdge> edgeBC = std::make_shared<FsmEdgeUnique>(nodeB,nodeC,toTest); - - std::shared_ptr<FsmGraph> graph = std::make_shared<FsmGraph>(""); - graph->addEdge(edgeAB); - graph->addEdge(edgeBC); - - REQUIRE(graph->getValidNodes() == std::set<std::shared_ptr<FsmNode>>{nodeC}); - REQUIRE(graph->getStartNodes() == std::vector<std::shared_ptr<FsmNode>>{nodeA}); - REQUIRE(graph->getNodes() == std::set<std::shared_ptr<FsmNode>>{nodeA,nodeB,nodeC}); - - //make the nodes - std::shared_ptr<FsmNode> node2A = std::make_shared<FsmNode>(false,true); - std::shared_ptr<FsmNode> node2B = std::make_shared<FsmNode>(false,false); - std::shared_ptr<FsmNode> node2C = std::make_shared<FsmNode>(true,false); - - - std::shared_ptr<FsmEdge> edge2AB = std::make_shared<FsmEdgeUnique>(node2A,node2B,toTest); - std::shared_ptr<FsmEdge> edge2BC = std::make_shared<FsmEdgeUnique>(node2B,node2C,toTest); - - std::shared_ptr<FsmGraph> graph2 = std::make_shared<FsmGraph>(""); - - - graph2->addEdge(edge2AB); - graph2->addEdge(edge2BC); - - - REQUIRE(graph2->getValidNodes() == std::set<std::shared_ptr<FsmNode>>{node2C}); - REQUIRE(graph2->getStartNodes() == std::vector<std::shared_ptr<FsmNode>>{node2A}); - REQUIRE(graph2->getNodes() == std::set<std::shared_ptr<FsmNode>>{node2A,node2B,node2C}); - - - graph->mergeOneStartOneValid(graph2); - - REQUIRE(graph->getValidNodes() == std::set<std::shared_ptr<FsmNode>>{node2C}); - REQUIRE(graph->getStartNodes() == std::vector<std::shared_ptr<FsmNode>>{nodeA}); - REQUIRE(graph->getNodes() == std::set<std::shared_ptr<FsmNode>>{nodeA,nodeB,nodeC,node2B,node2C}); - } - - - - -} - -// TEST_CASE("matchFSM", "FsmGraph") { - -// SECTION("FsmEdgeUnique constructor") { -// //make the nodes -// std::shared_ptr<FsmNode> nodeA = std::make_shared<FsmNode>(true,false); -// std::shared_ptr<FsmNode> nodeB = std::make_shared<FsmNode>(false,true); - -// //make the edges -// std::shared_ptr<ConditionalInterpreter> toTest = std::make_shared<ConditionalInterpreter>("true==true"); -// std::shared_ptr<FsmEdgeUnique> edge = std::make_shared<FsmEdgeUnique>(nodeA,nodeB,toTest); - -// std::shared_ptr<FsmGraph> graph = std::make_shared<FsmGraph>(""); - -// graph->addEdge(edge); - - - -// } - -// } \ No newline at end of file diff --git a/unit_tests/graphRegex/Test_FsmMatch.cpp b/unit_tests/graphRegex/Test_FsmMatch.cpp deleted file mode 100644 index 6229ec62af96802ebdfe871e6058ab1791cf80fd..0000000000000000000000000000000000000000 --- a/unit_tests/graphRegex/Test_FsmMatch.cpp +++ /dev/null @@ -1,90 +0,0 @@ - -#include <catch2/catch_test_macros.hpp> - -#include "aidge/graph/GraphView.hpp" -#include "aidge/operator/Conv.hpp" -#include "aidge/operator/GenericOperator.hpp" -#include "aidge/operator/Producer.hpp" - - -#include "aidge/graphRegex/GraphFsmInterpreter.hpp" - - -using namespace Aidge; -TEST_CASE("FsmMatch") { - - SECTION("Construction") { - std::vector<std::shared_ptr<ConditionalInterpreter>> allTest = { - std::make_shared<ConditionalInterpreter>("A","isConv($)==true"), - std::make_shared<ConditionalInterpreter>("B","isConv($)==true"), - std::make_shared<ConditionalInterpreter>("C","true==true") - }; - - allTest[0]->insertLambda("isConv",+[](NodePtr NodeOp){return NodeOp->type() == "Conv";}); - allTest[1]->insertLambda("isConv",+[](NodePtr NodeOp){return NodeOp->type() == "Conv";}); - - std::shared_ptr<GraphFsmInterpreter> fsmGenerator = std::make_shared<GraphFsmInterpreter>("A->A",allTest); - std::shared_ptr<FsmGraph> fsm = fsmGenerator->interpret(); - - - - //REQUIRE(fsm->getNodes().size() == 3); - //REQUIRE(fsm->getStartNodes().size() == 1); - - - - std::shared_ptr<GraphView> g1 = std::make_shared<GraphView>("TestGraph"); - std::shared_ptr<Node> conv = GenericOperator("Conv", 1, 0, 1, "c"); - std::shared_ptr<Node> conv1 = GenericOperator("Conv", 1, 0, 1, "c1"); - - g1->add(conv); - g1->addChild(conv1, "c"); - - - REQUIRE(allTest[0]->test(conv) == true); - REQUIRE(allTest[1]->test(conv) == true); - - std::vector<std::shared_ptr<Node>> startNodes = {conv}; - - auto result = fsm->test(startNodes); - - REQUIRE( result[0]->getAll() == std::set<NodePtr>{conv,conv1}); - } - - - SECTION("2 branches graph"){ - - std::shared_ptr<GraphView> g1 = std::make_shared<GraphView>("TestGraph"); - std::shared_ptr<Node> conv = GenericOperator("Conv", 1, 0, 1, "c"); - std::shared_ptr<Node> conv1 = GenericOperator("Conv", 1, 0, 1, "c1"); - std::shared_ptr<Node> conv2 = GenericOperator("Fc", 1, 0, 1, "c2"); - - g1->add(conv); - g1->addChild(conv1,conv); - g1->addChild(conv2,conv); - - REQUIRE(g1->getNodes() == std::set<std::shared_ptr<Node>>({conv,conv1,conv2})); - REQUIRE(g1->inputNodes() == std::set<std::shared_ptr<Node>>({conv})); - REQUIRE(g1->outputNodes() == std::set<std::shared_ptr<Node>>({conv1,conv2})); - - - ///////////// - - std::vector<std::shared_ptr<ConditionalInterpreter>> allTest = { - std::make_shared<ConditionalInterpreter>("A","isConv($)==true"), - std::make_shared<ConditionalInterpreter>("B","isFc($)==true") - }; - allTest[0]->insertLambda("isConv",+[](NodePtr NodeOp){return NodeOp->type() == "Conv";}); - allTest[1]->insertLambda("isFc",+[](NodePtr NodeOp){return NodeOp->type() == "Fc";}); - - std::shared_ptr<GraphFsmInterpreter> fsmGenerator = std::make_shared<GraphFsmInterpreter>("A#->A; A#->B",allTest); - std::shared_ptr<FsmGraph> fsm = fsmGenerator->interpret(); - - std::vector<std::shared_ptr<Node>> startNodes = {conv,conv}; - auto result = fsm->test(startNodes); - - REQUIRE( result[0]->getAll() == std::set<NodePtr>{conv,conv1,conv2}); - - } - -} diff --git a/unit_tests/graphRegex/Test_GraphFsmInterpreter.cpp b/unit_tests/graphRegex/Test_GraphFsmInterpreter.cpp deleted file mode 100644 index e789677d44efa68071017a9832fa01b5ed340f75..0000000000000000000000000000000000000000 --- a/unit_tests/graphRegex/Test_GraphFsmInterpreter.cpp +++ /dev/null @@ -1,42 +0,0 @@ - -#include <catch2/catch_test_macros.hpp> - -#include "aidge/graphRegex/GraphFsmInterpreter.hpp" - - -using namespace Aidge; -TEST_CASE("GraphFsmInterpreter", "GraphFsmInterpreter") { - - SECTION("Construction") { - std::vector<std::shared_ptr<ConditionalInterpreter>> allTest = { - std::make_shared<ConditionalInterpreter>("A","true==true"), - std::make_shared<ConditionalInterpreter>("B","true==true"), - std::make_shared<ConditionalInterpreter>("C","true==true") - }; - - //GraphFsmInterpreter("A->B",allTest); - std::shared_ptr<GraphFsmInterpreter> fsmGenerator = std::make_shared<GraphFsmInterpreter>("A->B",allTest); - std::shared_ptr<FsmGraph> fsm = fsmGenerator->interpret(); - - - REQUIRE(fsm->getNodes().size() == 3); - REQUIRE(fsm->getStartNodes().size() == 1); - REQUIRE(fsm->getEdge().size() == 2); - - for(auto node : fsm->getNodes()){ - if(node->isValid()){ - REQUIRE(node->getEdges().size() == 0); - }else{ - REQUIRE(node->getEdges().size() == 1); - } - - } - - - } - - - - - -} \ No newline at end of file diff --git a/unit_tests/graphRegex/Test_GraphLexer.cpp b/unit_tests/graphRegex/Test_GraphLexer.cpp deleted file mode 100644 index ffb25097855be256817a42f779bd8738150528df..0000000000000000000000000000000000000000 --- a/unit_tests/graphRegex/Test_GraphLexer.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/******************************************************************************** - * 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 "aidge/graphRegex/GraphLexer.hpp" -#include "aidge/graphRegex/GraphRegexTypes.hpp" -#include "aidge/utilsParsing/ParsingToken.hpp" - -#include <catch2/catch_test_macros.hpp> -#include <fmt/format.h> - -#include <map> -#include <functional> - -using namespace Aidge; - -// NEXT -// QOM -// QZM -// KEY -// CKEY -// SEP -// LPAREN -// RPAREN - -TEST_CASE("GraphRegex", "Lexer") { - SECTION("RandomGenerateTest") { - - std::map<gRegexTokenTypes, std::function<std::pair<std::string, std::string>()>> LexerTestMap{ - {gRegexTokenTypes::NEXT, +[](){return std::pair<std::string, std::string>("-> ","");}}, - {gRegexTokenTypes::QOM, +[](){return std::pair<std::string, std::string>("+ ","");}}, - {gRegexTokenTypes::QZM, +[](){return std::pair<std::string, std::string>("* ","");}}, - {gRegexTokenTypes::SEP, +[](){return std::pair<std::string, std::string>("; ","");}}, - - - - {gRegexTokenTypes::KEY, +[](){ - std::size_t keyLen = (std::rand() % 20)+1; - const std::string characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_"; - std::size_t randomIndex = std::rand() % characters.size(); - std::string key; - for (std::size_t i = 0; i < keyLen; ++i) { - key += characters[randomIndex]; - randomIndex = std::rand() % characters.size(); - } - - return std::pair<std::string, std::string>(key+" ",key);} - }, - - {gRegexTokenTypes::CKEY, +[](){ - std::size_t keyLen = (std::rand() % 20)+1; - const std::string characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_"; - const std::string num = "1234567890"; - - std::size_t randomIndex = std::rand() % characters.size(); - std::size_t randomNum = std::rand() % num.size(); - std::string key; - std::string idx; - - for (std::size_t i = 0; i < keyLen; ++i) { - key += characters[randomIndex]; - idx += num[randomNum]; - randomIndex = std::rand() % characters.size(); - randomNum = std::rand() % num.size(); - } - - return std::pair<std::string, std::string>(key+"#"+idx+" ",key+"#"+idx);} - }, - - {gRegexTokenTypes::LPAREN, +[](){return std::pair<std::string, std::string>("( ","");}}, - {gRegexTokenTypes::RPAREN, +[](){return std::pair<std::string, std::string>(") ","");}} - //{gRegexTokenTypes::STOP, +[](){return std::pair<std::string, std::string>("","");}} - }; - - - ////////////////// - //TEST GENERATOR - ////////////////// - const std::size_t numRandomElements = 1000; - std::vector<std::tuple<gRegexTokenTypes, std::string>> testVector; - - std::string testString; - - for (std::size_t i = 0; i < numRandomElements; ++i) { - - int randomIndex = std::rand() % LexerTestMap.size(); - // Get an iterator to the random element in the map - auto it = std::next(LexerTestMap.begin(), randomIndex); - // Access the random key and lambda value separately using structured binding - gRegexTokenTypes randomKey = it->first; - - std::function<std::pair<std::string, std::string>()> randomValue = it->second; - std::pair<std::string, std::string> result = randomValue(); - - testString += result.first; - testVector.emplace_back(randomKey, result.second); - - - } - - GraphLexer graphLexer = GraphLexer(testString); - - for (std::tuple<gRegexTokenTypes, std::string> testToken : testVector) { - gRegexTokenTypes tokenToFind = std::get<0>(testToken); - std::string lexemToFind = std::get<1>(testToken); - std::shared_ptr<ParsingToken<gRegexTokenTypes>> token = graphLexer.getNextToken(); - - CAPTURE(fmt::format("\nWe want: {}\nWe get: {}\nOn:\n{}\n", lexemToFind, token->getLexeme(), testString)); - REQUIRE(token->getLexeme() == lexemToFind); - REQUIRE(token->getType() == tokenToFind); - } - std::shared_ptr<ParsingToken<gRegexTokenTypes>> token = graphLexer.getNextToken(); - REQUIRE(token->getType() == gRegexTokenTypes::STOP); - } - - -} \ No newline at end of file diff --git a/unit_tests/graphRegex/Test_GraphParser.cpp b/unit_tests/graphRegex/Test_GraphParser.cpp deleted file mode 100644 index c4f17494f815ceea6cbb6da1626ec94fe0b9099b..0000000000000000000000000000000000000000 --- a/unit_tests/graphRegex/Test_GraphParser.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/******************************************************************************** - * 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 <cstdlib> // std::rand -#include <memory> -#include <string> - -#include <catch2/catch_test_macros.hpp> -#include <fmt/core.h> - -#include "aidge/graphRegex/GraphParser.hpp" -#include "aidge/utilsParsing/AstNode.hpp" - -using namespace Aidge; - - //generative function , - std::string domain(); - std::string exp() { - int randomValue = std::rand() % 3; - switch (randomValue) { - case 0: - return "A"; - case 1 : - return "A#"; - default: - return domain(); - - } - } - - std::string seq() { - return exp() + (((std::rand() & 0x1) == 0x0) ? "" : ("->" + seq())); - } - - std::string domain() { - return "("+ seq() +")" + (((std::rand() & 0x1) == 0x0) ? "*" : "+"); - } - - std::string allExpr() { - return seq() + (((std::rand() & 0x1) == 0x0) ? "" : (";" + allExpr())); - } - -/* -exp : KEY(QOM | QZM)? | CKEY | domain -seq :exp (NEXT seq)* -domain : LPAREN seq RPAREN (QOM | QZM) -allExpr: seq (SEP allExpr)* -*/ -TEST_CASE("GraphParser", "Test_GraphParser") { - - SECTION("Empty") { - for (int i = 0; i < 100; ++i) { - const std::string test = allExpr(); - fmt::print("test\n"); - GraphParser graphParser = GraphParser(test); - std::shared_ptr<AstNode<gRegexTokenTypes>> tree = graphParser.parse(); - } - } -} \ No newline at end of file diff --git a/unit_tests/graphRegex/Test_GraphRegex.cpp b/unit_tests/graphRegex/Test_GraphRegex.cpp deleted file mode 100644 index 79e471d44a49dfb52fd5eb4aa1ed2dc4ab8dc0bb..0000000000000000000000000000000000000000 --- a/unit_tests/graphRegex/Test_GraphRegex.cpp +++ /dev/null @@ -1,194 +0,0 @@ - -#include <catch2/catch_test_macros.hpp> -#include "aidge/graphRegex/GraphRegex.hpp" - - -#include "aidge/data/Tensor.hpp" -#include "aidge/graph/GraphView.hpp" -#include "aidge/operator/Add.hpp" -#include "aidge/operator/FC.hpp" -#include "aidge/operator/MatMul.hpp" -#include "aidge/operator/Producer.hpp" -#include "aidge/recipes/Recipes.hpp" - -#include "aidge/operator/Conv.hpp" -#include "aidge/operator/GenericOperator.hpp" - -using namespace Aidge; - -TEST_CASE("GraphRegexUser") { - - - SECTION("Match using custom lambda") { - - std::shared_ptr<GraphView> g1 = std::make_shared<GraphView>("TestGraph"); - std::shared_ptr<Node> conv = GenericOperator("Conv", 1, 0, 1, "c"); - std::shared_ptr<Node> fc = GenericOperator("FC", 1, 0, 1, "c1"); - std::shared_ptr<Node> conv2 = GenericOperator("Conv", 1, 0, 1, "c2"); - std::shared_ptr<Node> fc2 = GenericOperator("FC", 1, 0, 1, "c3"); - - g1->add(conv); - g1->addChild(fc, "c"); - g1->addChild(conv2, "c1"); - g1->addChild(fc2, "c2"); - - /// - std::shared_ptr<GraphRegex> sut = std::make_shared<GraphRegex>(); - sut->setNodeKey("C",+[](NodePtr NodeOp){return NodeOp->type() == "FC";}); - - sut->setNodeKey("A","C($)==True"); - sut->addQuery("A"); - auto match = sut->match(g1); - REQUIRE(match.size() == 2); - - } - - - SECTION("INIT") { - - const std::string query = "Conv->FC"; - - std::shared_ptr<GraphRegex> sut = std::make_shared<GraphRegex>(); - - std::shared_ptr<GraphView> g1 = std::make_shared<GraphView>("TestGraph"); - std::shared_ptr<Node> conv = GenericOperator("Conv", 1, 0, 1, "c"); - std::shared_ptr<Node> fc = GenericOperator("FC", 1, 0, 1, "c1"); - std::shared_ptr<Node> conv2 = GenericOperator("Conv", 1, 0, 1, "c2"); - std::shared_ptr<Node> fc2 = GenericOperator("FC", 1, 0, 1, "c3"); - - g1->add(conv); - g1->addChild(fc, "c"); - g1->addChild(conv2, "c1"); - g1->addChild(fc2, "c2"); - - - sut->setKeyFromGraph(g1); - sut->addQuery(query); - - for (const auto& solution : sut->match(g1)) { - - REQUIRE(solution->getQuery() == query); - if(solution->getStartNode() == std::vector<NodePtr>{conv}){ - REQUIRE(solution->at("Conv") == std::set<NodePtr>{conv} ); - REQUIRE(solution->at("FC") == std::set<NodePtr>{fc} ); - }else if (solution->getStartNode() == std::vector<NodePtr>{conv2}) - { - REQUIRE(solution->at("Conv") == std::set<NodePtr>{conv2} ); - REQUIRE(solution->at("FC") == std::set<NodePtr>{fc2} ); - } - } - //REQUIRE( sut->match(g1)[1]->getAll() == std::set<NodePtr>{conv,fc}); - - } - - SECTION("2 query") { - std::shared_ptr<GraphRegex> sut = std::make_shared<GraphRegex>(); - - std::shared_ptr<GraphView> g1 = std::make_shared<GraphView>("TestGraph"); - std::shared_ptr<Node> conv = GenericOperator("Conv", 1, 0, 1, "c"); - std::shared_ptr<Node> conv1 = GenericOperator("Conv", 1, 0, 1, "c1"); - std::shared_ptr<Node> conv2 = GenericOperator("Conv", 1, 0, 1, "c2"); - std::shared_ptr<Node> conv3 = GenericOperator("Conv", 1, 0, 1, "c3"); - - g1->add(conv); - g1->addChild(conv1, "c"); - g1->addChild(conv2, "c1"); - g1->addChild(conv3, "c2"); - - - sut->setKeyFromGraph(g1); - - const std::string query = "Conv->Conv"; - const std::string query2 = "Conv->FC"; - - sut->setNodeKey("FC","getType($) =='FC'"); - - sut->addQuery(query); - sut->addQuery(query2); - - - for (const auto& solution : sut->match(g1)) { - REQUIRE(solution->getQuery() == query); - } - - } - - - SECTION("Not define node Test") { - - //test if the FC is not define only match query not query2 - std::shared_ptr<GraphRegex> sut = std::make_shared<GraphRegex>(); - - std::shared_ptr<GraphView> g1 = std::make_shared<GraphView>("TestGraph"); - std::shared_ptr<Node> conv = GenericOperator("Conv", 1, 0, 1, "c"); - std::shared_ptr<Node> conv1 = GenericOperator("Conv", 1, 0, 1, "c1"); - std::shared_ptr<Node> conv2 = GenericOperator("Conv", 1, 0, 1, "c2"); - std::shared_ptr<Node> conv3 = GenericOperator("FC", 1, 0, 1, "c3"); - - g1->add(conv); - g1->addChild(conv1, "c"); - g1->addChild(conv2, "c1"); - g1->addChild(conv3, "c2"); - - - //sut->setKeyFromGraph(g1); - - const std::string query = "Conv->Conv"; - const std::string query2 = "Conv->FC"; - - sut->setNodeKey("Conv","getType($) =='Conv'"); - - sut->addQuery(query); - sut->addQuery(query2); - - - for (const auto& solution : sut->match(g1)) { - REQUIRE(solution->getQuery() == query); - } - - } - - - SECTION("Applied Recipes"){ - - // generate the original GraphView - auto matmul0 = MatMul("matmul0"); - auto add0 = Add("add0"); - auto matmul1 = MatMul("matmul1"); - auto add1 = Add("add1"); - - auto b0 = Producer({5}, "B0"); - auto w0 = Producer({5, 5}, "W0"); - auto b1 = Producer({5}, "B1"); - auto w1 = Producer({5,5},"W1"); - auto input = Producer({2,5}, "input"); - - input->addChild(matmul0, 0, 1); - w0->addChild(matmul0, 0, 0); - - matmul0->addChild(add0, 0, 0); - b0->addChild(add0, 0, 1); - - add0->addChild(matmul1, 0, 1); - w1->addChild(matmul1, 0, 0); - - matmul1->addChild(add1, 0, 0); - b1->addChild(add1, 0, 1); - - auto fc = GenericOperator("FC", 1, 0, 1, "fc1"); - auto fl = GenericOperator("Flatten", 1, 0, 1, "flatten0"); - add1->addChild(fl, 0, 0); - fl->addChild(fc, 0, 0); - auto g = std::make_shared<GraphView>(); - g->add({w0, matmul0, b0, add0, w1, matmul1, b1, add1, fl, fc}); - - matMulToFC(g); - removeFlatten(g); - std::set<std::shared_ptr<Node>> newNodes = g->getNodes(); - REQUIRE(newNodes != std::set<std::shared_ptr<Node>>({w0, matmul0, b0, add0, w1, matmul1, b1, add1,fl,fc})); - //REQUIRE(newNodes.size() == 6); - - - } - -} diff --git a/unit_tests/graphRegex/Test_examples.cpp b/unit_tests/graphRegex/Test_examples.cpp deleted file mode 100644 index 0ccc05b5a957673167a16643b22bf047fc80f43f..0000000000000000000000000000000000000000 --- a/unit_tests/graphRegex/Test_examples.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/******************************************************************************** - * 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 <catch2/catch_test_macros.hpp> -#include <set> - -#include "aidge/data/Tensor.hpp" -#include "aidge/graph/GraphView.hpp" -#include "aidge/graph/OpArgs.hpp" -#include "aidge/operator/ReLU.hpp" -#include "aidge/operator/MetaOperatorDefs.hpp" -#include "aidge/operator/Producer.hpp" -#include "aidge/graphRegex/GraphRegex.hpp" -#include "aidge/recipes/Recipes.hpp" - -namespace Aidge { - - -TEST_CASE("Examples", "[GraphMatching]") { - auto g1 = Sequential({ - Producer({16, 3, 512, 512}, "dataProvider"), - Conv(3, 4, {5, 5}, "conv1"), - ReLU(), - PaddedConv(4, 8, {5, 5}, "conv2", {1, 1}, {2, 2, 2, 2}), - ReLU(), - PaddedConv(8, 16, {5, 5}, "conv3", {1, 1}, {2, 2, 2, 2}), - ReLU() - }); - - expandMetaOps(g1); - g1->save("Test_examples"); - - auto regex = std::make_shared<GraphRegex>(); - regex->setKeyFromGraph(g1); - regex->addQuery("Pad2D->Conv2D->ReLU"); - // Won't work, wrong number of matches: - //regex->addQuery("Pad*->Conv->ReLU*"); - - const auto match = regex->match(g1); - REQUIRE(match.size() == 2); - - for (const auto& solution : match) { - REQUIRE(solution->getAll().size() == 3); - } -} - -} // namespace Aidge diff --git a/unit_tests/graphRegex/Test_graphRegexAST.cpp b/unit_tests/graphRegex/Test_graphRegexAST.cpp deleted file mode 100644 index f9c7a7c5dc8ab103b3b566f2df77883b0b1966f1..0000000000000000000000000000000000000000 --- a/unit_tests/graphRegex/Test_graphRegexAST.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include <catch2/catch_test_macros.hpp> -#include "aidge/graphRegex/GraphStrInterpreter.hpp" - - -using namespace Aidge; -TEST_CASE("GraphStrInterpreter") { - - - - std::vector<std::string> tests = { - - - //sequ - "A;", - "A->B", - "A->B->C", - //seq and common - "A#", - "A#->B", - "A#->B#", - "A#->B#->C", - "A#->B#->C#", - "A->B#->C", - //sequ quantif + - "A+", - "A+->B+", - "A->B+->C", - //sequ quantif * - "A*", - "A*->B*", - "A->B*->C", - - //sequ quantif - "A*", - "A*->B+", - "A+->B*->C", - //others - - "(A#->B->C#)+", - "(A#->B)+;A#->B->C", - "B+->B->B", - "B#->R*", - "(B#->R)*", - "A->C->B#->B;B#->R", - "B#->R", - "A->C#;A->C#;A->C#;A->C#;A->C#;A->C#", - "B#->R;B#->R", - "A# -> C -> B#; B#->A#", - - // Add more test cases here - }; - - SECTION("AST Regex bijection") { - - for (const std::string& test : tests) { - std::shared_ptr<GraphStrInterpreter> strGenerator = std::make_shared<GraphStrInterpreter>(test); - std::string astString = strGenerator->interpret(); - //suppress space in the test because erase in the AST - std::string testNoS = test; - testNoS.erase(std::remove_if(testNoS.begin(), testNoS.end(), ::isspace), testNoS.end()); - //if the last char is ; (SEP) it will not in the AST and it's not a bug erase it - if (!testNoS.empty() && testNoS.back() == ';') { - // Remove the last character - testNoS.pop_back(); - } - //test - REQUIRE(astString == testNoS); - } - - } -} \ No newline at end of file diff --git a/unit_tests/nodeTester/Test_ConditionalInterpreter.cpp b/unit_tests/nodeTester/Test_ConditionalInterpreter.cpp deleted file mode 100644 index ec068358a34567e57c417a664284bd1db76d7a69..0000000000000000000000000000000000000000 --- a/unit_tests/nodeTester/Test_ConditionalInterpreter.cpp +++ /dev/null @@ -1,91 +0,0 @@ - -#include <catch2/catch_test_macros.hpp> -#include "aidge/nodeTester/ConditionalInterpreter.hpp" -#include "aidge/operator/GenericOperator.hpp" - - -using namespace Aidge; - - - -TEST_CASE("ConditionalInterpreter", "ConditionalInterpreter") { - - SECTION("custom Lambda") { - - - ConditionalInterpreter conditionalParserB = ConditionalInterpreter("A"," bad($) == false "); - ConditionalInterpreter conditionalParserG = ConditionalInterpreter("A"," good($) == true "); - - - conditionalParserB.insertLambda("bad",+[](NodePtr NodeOp){return NodeOp->name() == "ZZ";}); - conditionalParserG.insertLambda("good",+[](NodePtr NodeOp){return NodeOp->name() == "Gop1";}); - std::shared_ptr<Node> nodeOp = GenericOperator("conv", 0, 0, 0, "Gop1"); - - REQUIRE(conditionalParserB.test(nodeOp) == true); - REQUIRE(conditionalParserG.test(nodeOp) == true); - } - - - ConditionalInterpreter conditionalParserT = ConditionalInterpreter("A","isConv($)==true"); - conditionalParserT.insertLambda("isConv",+[](NodePtr NodeOp){return NodeOp->type() == "Conv";}); - std::shared_ptr<Node> zz = GenericOperator("conv", 0, 0, 0, "Gop1"); - conditionalParserT.test(zz); - - SECTION("Lambdas") { - ConditionalInterpreter conditionalParser = ConditionalInterpreter("OP_test","getType($) =='Conv' || getType($) =='FC' "); - - std::shared_ptr<Node> A = GenericOperator("Conv", 0, 0, 0, "A"); - REQUIRE(conditionalParser.test(A) == true); - - std::shared_ptr<Node> B = GenericOperator("FC", 0, 0, 0, "B"); - REQUIRE(conditionalParser.test(B) == true); - - - std::shared_ptr<Node> C = GenericOperator("A", 0, 0, 0, "C"); - conditionalParser.test(C); - REQUIRE(conditionalParser.test(C) == false); - } - - SECTION("syntax error") { - - const std::string test = "'A' == 'A' ,&& "; - REQUIRE_THROWS_AS( ConditionalInterpreter("A",test), std::runtime_error); - - } - - - SECTION("test false int ") { - - const std::string test = " 10 == 11 " ; - ConditionalInterpreter conditionalParser = ConditionalInterpreter("A",test); - std::shared_ptr<Node> nodeOp = GenericOperator("conv", 0, 0, 0, "Gop1"); - bool result = conditionalParser.test(nodeOp); - REQUIRE(result == false); - } - - SECTION("test true int ") { - const std::string test = " 42 == 42 " ; - ConditionalInterpreter conditionalParser = ConditionalInterpreter("A",test); - std::shared_ptr<Node> nodeOp = GenericOperator("conv", 0, 0, 0, "Gop1"); - bool result = conditionalParser.test(nodeOp); - REQUIRE(result == true); - } - - SECTION("test false str ") { - const std::string test = " 'toto' == 'Corgi' " ; - ConditionalInterpreter conditionalParser = ConditionalInterpreter("A",test); - std::shared_ptr<Node> nodeOp = GenericOperator("conv", 0, 0, 0, "Gop1"); - bool result = conditionalParser.test(nodeOp); - REQUIRE(result == false); - } - - SECTION("test true str ") { - - const std::string test = " 'Corgi' == 'Corgi' " ; - ConditionalInterpreter conditionalParser = ConditionalInterpreter("A",test); - std::shared_ptr<Node> nodeOp = GenericOperator("conv", 0, 0, 0, "Gop1"); - bool result = conditionalParser.test(nodeOp); - REQUIRE(result == true); - } - -} \ No newline at end of file diff --git a/unit_tests/nodeTester/Test_ConditionalLexer.cpp b/unit_tests/nodeTester/Test_ConditionalLexer.cpp deleted file mode 100644 index e5a7bd831e6cb2ec78a91a2d08e4fa6c53d09848..0000000000000000000000000000000000000000 --- a/unit_tests/nodeTester/Test_ConditionalLexer.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/******************************************************************************** - * 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 <functional> -#include <map> -#include <string> -#include <utility> - -#include <catch2/catch_test_macros.hpp> -#include <fmt/format.h> - -#include "aidge/nodeTester/ConditionalLexer.hpp" -#include "aidge/utilsParsing/ParsingToken.hpp" - -using namespace Aidge; - -TEST_CASE("nodeTester", "Lexer") { - SECTION("RandomGenerateTest") { - - std::map<ConditionalTokenTypes, std::function<std::pair<std::string, std::string>()>> LexerTestMap{ - {ConditionalTokenTypes::AND, +[](){return std::pair<std::string, std::string>("&& ","");}}, - {ConditionalTokenTypes::OR, +[](){return std::pair<std::string, std::string>("|| ","");}}, - {ConditionalTokenTypes::EQ, +[](){return std::pair<std::string, std::string>("== ","");}}, - {ConditionalTokenTypes::NEQ, +[](){return std::pair<std::string, std::string>("!= ","");}}, - - {ConditionalTokenTypes::KEY, +[](){return std::pair<std::string, std::string>("A ","A");}}, - - {ConditionalTokenTypes::BOOL, +[](){ - std::size_t keyLen = (std::rand() % 2); - const std::vector<std::string> characters = {"true","false"}; - - return std::pair<std::string, std::string>(characters[keyLen]+" ",characters[keyLen]);} - }, - - {ConditionalTokenTypes::INTEGER, +[](){ - std::size_t keyLen = (std::rand() % 20)+1; - const std::string characters = "1234567890"; - std::size_t randomIndex = std::rand() % characters.size(); - std::string key; - for (std::size_t i = 0; i < keyLen; ++i) { - key += characters[randomIndex]; - randomIndex = std::rand() % characters.size(); - } - return std::pair<std::string, std::string>(key+" ",key);} - }, - - {ConditionalTokenTypes::FLOAT, +[](){ - std::size_t keyLen = (std::rand() % 20)+2; - const std::string characters = "1234567890"; - std::size_t randomIndex = std::rand() % characters.size(); - std::string key; - for (std::size_t i = 0; i < keyLen/2; ++i) { - key += characters[randomIndex]; - randomIndex = std::rand() % characters.size(); - } - key += "."; - for (std::size_t i = 0; i < keyLen/2; ++i) { - key += characters[randomIndex]; - randomIndex = std::rand() % characters.size(); - } - return std::pair<std::string, std::string>(key+" ",key);} - }, - - {ConditionalTokenTypes::STRING, +[](){ - std::size_t keyLen = (std::rand() % 20)+1; - const std::string characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 "; - std::size_t randomIndex = std::rand() % characters.size(); - std::string key; - for (std::size_t i = 0; i < keyLen; ++i) { - key += characters[randomIndex]; - randomIndex = std::rand() % characters.size(); - } - - return std::pair<std::string, std::string>("'"+key+"' ",key);} - }, - - {ConditionalTokenTypes::LAMBDA, +[](){ - - std::size_t keyLen = (std::rand() % 20)+1; - const std::string characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; - const std::string Startchar = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - - std::size_t randomIndex = std::rand() % characters.size(); - std::size_t randomStartIndex = std::rand() % Startchar.size(); - - std::string key; - key += Startchar[randomStartIndex]; - - for (std::size_t i = 0; i < keyLen; ++i) { - key += characters[randomIndex]; - randomIndex = std::rand() % characters.size(); - } - - return std::pair<std::string, std::string>(key+"( ",key);} - }, - - {ConditionalTokenTypes::ARGSEP, +[](){return std::pair<std::string, std::string>(", ","");}}, - {ConditionalTokenTypes::NODE, +[](){return std::pair<std::string, std::string>("$ ","");}}, - {ConditionalTokenTypes::LPAREN, +[](){return std::pair<std::string, std::string>("( ","");}}, - {ConditionalTokenTypes::RPAREN, +[](){return std::pair<std::string, std::string>(") ","");}} - //{ConditionalTokenTypes::STOP, +[](){return std::pair<std::string, std::string>("","");}} - }; - - - ////////////////// - //TEST GENERATOR - ////////////////// - const std::size_t numRandomElements = 100; - std::vector<std::tuple<ConditionalTokenTypes, std::string>> testVector; - - std::string testString; - - for (std::size_t i = 0; i < numRandomElements; ++i) { - - int randomIndex = std::rand() % LexerTestMap.size(); - // Get an iterator to the random element in the map - auto it = std::next(LexerTestMap.begin(), randomIndex); - // Access the random key and lambda value separately using structured binding - ConditionalTokenTypes randomKey = it->first; - - std::function<std::pair<std::string, std::string>()> randomValue = it->second; - std::pair<std::string, std::string> result = randomValue(); - - testString += result.first; - testVector.emplace_back(randomKey, result.second); - - - } - - ConditionalLexer conditionalLexer = ConditionalLexer(testString); - - for (std::tuple<ConditionalTokenTypes, std::string> testToken : testVector) { - ConditionalTokenTypes tokenToFind = std::get<0>(testToken); - std::string lexemToFind = std::get<1>(testToken); - std::shared_ptr<ParsingToken<ConditionalTokenTypes>> token = conditionalLexer.getNextToken(); - - CAPTURE(fmt::format("\n we want: {}\n we get: {}\non: \n{}\n", lexemToFind, token->getLexeme(), testString)); - REQUIRE(token->getLexeme() == lexemToFind); - REQUIRE(token->getType() == tokenToFind); - } - std::shared_ptr<ParsingToken<ConditionalTokenTypes>> token = conditionalLexer.getNextToken(); - REQUIRE(token->getType() == ConditionalTokenTypes::STOP); - } - - -} \ No newline at end of file diff --git a/unit_tests/nodeTester/Test_ConditionalParser.cpp b/unit_tests/nodeTester/Test_ConditionalParser.cpp deleted file mode 100644 index 56adb92b41745001e1790e087f07369918794c5d..0000000000000000000000000000000000000000 --- a/unit_tests/nodeTester/Test_ConditionalParser.cpp +++ /dev/null @@ -1,75 +0,0 @@ - -#include <catch2/catch_test_macros.hpp> -#include "aidge/nodeTester/ConditionalParser.hpp" -#include "aidge/utilsParsing/AstNode.hpp" - -using namespace Aidge; - - std::string gVal() { - int randomValue = std::rand() % 5; - switch (randomValue) { - case 0: - return std::to_string(std::rand() % 101); - - case 1: - return std::to_string(std::rand() % 101)+"."+std::to_string(std::rand() % 101); - - case 2: - return " 'toto' "; - case 3: - return " A "; - - case 4: - return " A(10) "; - - default: - return " true "; - - } - } - - std::string gExpr() ; - std::string gCmpr() { - int randomValue = std::rand() % 3; - switch (randomValue) { - case 0: - return gVal() + " == " +gVal(); - case 1: - return "("+ gExpr() +")"; - default: - return gVal() + " != " +gVal(); - - } - - - return gVal() + " == " +gVal(); - } - - std::string gExpr() { - std::string out = gCmpr(); - int iterations = std::rand() % 100; - for (int i = 0; i < iterations; ++i) { - int randomValue = std::rand() % 2; - switch (randomValue) { - case 0: - return out +" && " + gCmpr(); - break; - default: - return out +" || " + gCmpr(); - break; - } - } - return out; - } - - -TEST_CASE("ConditionalParser", "ConditionalParser") { - - SECTION("Empty") { - for (int i = 0; i < 100; ++i) { - const std::string test = gExpr(); - ConditionalParser conditionalParser = ConditionalParser(test); - std::shared_ptr<AstNode<ConditionalTokenTypes>> tree = conditionalParser.parse(); - } - } -} \ No newline at end of file diff --git a/unit_tests/recipes/Test_FuseToMetaOps.cpp b/unit_tests/recipes/Test_FuseToMetaOps.cpp index 7bb3ae63add6568f7de08a996b27a495a644cf46..3fe0fee1c8e520c99a3e056c06bc0fa034c6c878 100644 --- a/unit_tests/recipes/Test_FuseToMetaOps.cpp +++ b/unit_tests/recipes/Test_FuseToMetaOps.cpp @@ -34,7 +34,6 @@ TEST_CASE("[cpu/recipes] FuseToMetaOps", "[FuseToMetaOps][recipes]") { }); g1->save("FuseToMetaOps_before"); - // FIXME: GraphRegex also matches the Conv Producers, which are not in the query! const auto nbFused = fuseToMetaOps(g1, "Conv2D->ReLU", "ConvReLU"); g1->save("FuseToMetaOps_after", true);