Skip to content
Snippets Groups Projects
Commit d93381a6 authored by vincent  lorrain's avatar vincent lorrain
Browse files

[GraphRegex] new interface class

parent d06572e2
No related branches found
No related tags found
1 merge request!29GraphRegex interface class
Pipeline #33926 failed
Showing
with 486 additions and 151 deletions
......@@ -19,13 +19,16 @@ namespace Aidge {
std::size_t mActGroupe;
std::map<std::string,std::shared_ptr<ConditionalInterpreter>> mNodesCondition;
const std::string mGraphMatchExpr;
public:
GraphFsmInterpreter(const std::string graphMatchExpr,std::map<std::string,std::shared_ptr<ConditionalInterpreter>> nodesCondition);
GraphFsmInterpreter(const std::string graphMatchExpr,std::vector<std::shared_ptr<ConditionalInterpreter>> & nodesCondition);
virtual ~GraphFsmInterpreter() =default;
std::shared_ptr<FsmGraph> interpret(void);
private:
......
......@@ -36,6 +36,9 @@ namespace Aidge {
bool isEnd(void);
const std::string getQuery();
/**
* @brief Get the representation of the class
* @return string
......@@ -46,7 +49,7 @@ namespace Aidge {
/**
* @brief Constructs an error message to display the character not understood by the lexer
* @return error mesage
* @return error message
*/
std::runtime_error badTokenError(const std::string& currentChars,std::size_t position);
......
......@@ -30,6 +30,13 @@ class GraphParser{
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
......
#ifndef AIDGE_CORE_GRAPH_REGEX_H_
#define AIDGE_CORE_GRAPH_PARSER_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"
......@@ -13,14 +15,17 @@ namespace Aidge{
* @brief class which is the hight level interface for graph matching, used to simplify match definition
*
*/
class GraphParser{
class GraphRegex{
private:
std::vector<std::string> mQuery;
std::vector<std::shared_ptr<ConditionalInterpreter>> mAllTest;
std::map<std::string, std::function<bool(NodePtr)>&> mAllLambda;
public:
GraphParser();
virtual ~GraphParser() = default;
GraphRegex(){};
virtual ~GraphRegex() = default;
/**
* @brief add a topology query to the match
......@@ -32,30 +37,51 @@ class GraphParser{
* @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 setKeyGraphOp(std::shared_ptr<GraphView> Reference);
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 setQueryKey(const std::string key, const std::string ConditionalExpressions );
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 setKeyLambda(const std::string key,std::function<bool(Aidge::NodePtr)> f);
void setNodeKey(const std::string key,std::function<bool(NodePtr)> f);
/***
* @brief brief match the querys in the graph
* @param Reference the graph were the querys in search
* @return the result
*/
std::shared_ptr<MatchResult> match(std::shared_ptr<GraphView> Reference);
std::set<std::shared_ptr<MatchSolution>> match(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_PARSER_H_
\ No newline at end of file
#endif //AIDGE_CORE_GRAPH_REGEX_H_
\ No newline at end of file
......@@ -87,7 +87,7 @@ namespace Aidge{
* @brief set a new source to the edge
* @return FsmNode
*/
void reSetSouceNode(const std::shared_ptr<FsmNode>& newSource);
void reSetSourceNode(const std::shared_ptr<FsmNode>& newSource);
/**
* @brief get dest FsmNode
* @return FsmNode
......
......@@ -18,78 +18,89 @@ class FsmGraph
{
private:
/**
* @brief all node origine
* @brief all node Origin
*/
std::set<std::size_t> mAllOrigine;
std::set<std::size_t> mAllOrigin;
std::set<std::shared_ptr<FsmEdge>> mEdges;
const std::string mQuery;
public:
FsmGraph(/* args */);
FsmGraph(const std::string query);
virtual ~FsmGraph() = default;
std::shared_ptr<MatchResult> test(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 liste 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 valide states
* @return set of valide 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 groupe idx for all the nodes in the graph
*/
void setGroupe(std::size_t groupeIdx);
/**
* @brief make the union beteen this graph and an input graph
* @param fsmGraph graph to union
*/
void unionG(const std::shared_ptr<FsmGraph> fsmGraph);
/**
* @brief make the union beteen this graph and an input graph and merge the valide 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 increment the origine of all node in the graph
* @param incr the incrémentation value
*/
void incOrigineAllNodeBy(std::size_t incr);
std::vector<std::shared_ptr<MatchSolution>> test(const std::vector<NodePtr>& StartNodes);
private:
/**
* @brief merge tow node of the graph
* @param node
*/
void _mergeNode(std::shared_ptr<FsmNode> source,std::shared_ptr<FsmNode> dest);
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 liste 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 valide states
* @return set of valide 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 groupe 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 node 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);
};
......
......@@ -33,7 +33,7 @@ namespace Aidge{
* @details a state can be and/or :
* - a valide state, the match is valide if it stop on this edge
* - a start state , the match start on this state
* The state is also define by this origine (is the unique id of it's expretion )
* The state is also define by this Origin (is the unique id of it's expretion )
* and it's groupe (for inner expression TODO)
*/
class FsmNode : public std::enable_shared_from_this<FsmNode>
......@@ -49,8 +49,8 @@ namespace Aidge{
*/
std::set<std::weak_ptr<FsmNode>,lex_compare<FsmNode>> mParents;
std::size_t mOrigineStm = 0;
std::size_t mGroupeStm = 0;
std::size_t mOriginFsm = 0;
std::size_t mGroupeFsm = 0;
bool mIsAValid;
bool mIsAStart;
......@@ -59,7 +59,7 @@ namespace Aidge{
FsmNode(bool isAValid,bool isAStart );
virtual ~FsmNode() = default;
/**
* @brief use to MAG the actual context , and return all the posible new context
* @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
......@@ -68,8 +68,8 @@ namespace Aidge{
const std::vector<std::shared_ptr<FsmRunTimeContext>> test( std::shared_ptr<FsmRunTimeContext>);
std::size_t getOrigine(void);
void incOrigine(std::size_t inc);
std::size_t getOrigin(void);
void incOrigin(std::size_t inc);
void rmEdge(std::shared_ptr<FsmEdge>);
......
......@@ -152,7 +152,7 @@ namespace Aidge{
std::set<NodePtr> getValidNodes(void);
std::set<NodePtr> getValidNodesNoCommon(void);
std::map<std::shared_ptr<ConditionalInterpreter>,std::set<NodePtr>> getValid(void);
std::map<std::shared_ptr<ConditionalInterpreter>,std::set<NodePtr>>& getValid(void);
NodePtr getActNode(void);
......
......@@ -11,9 +11,31 @@
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(std::vector<std::shared_ptr<FsmRunTimeContext>>& precedence,const std::string query,const std::vector<NodePtr> startNode);
const std::set<NodePtr> & at(const std::string key);
const std::set<NodePtr> getAll();
bool areCompatible(std::shared_ptr<MatchSolution> solution);
const std::string& getQuery(){ return mQueryFrom ;}
const std::vector<NodePtr>& getStartNode(){ return mStartNode ;}
};
/**
* @brief class that old the result of a matching
* give acess to all node ant there tag in the expression
* give access to all node ant there tag in the expression
*/
class MatchResult
{
......@@ -22,17 +44,20 @@ private:
std::vector<std::shared_ptr<FsmRunTimeContext>> mAllValid;
/*
the Run time of eatch sub FSM , to have a valide match we need a set of one run time per FSM compatible
the id must be contigue
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::set<NodePtr>> mSolve;
std::vector<std::shared_ptr<MatchSolution>> mSolve;
std::size_t mNbSubStm;
public:
MatchResult(std::vector<std::shared_ptr<FsmRunTimeContext>> allValid, std::size_t nbSubStm);
MatchResult(std::vector<std::shared_ptr<FsmRunTimeContext>> allValid, std::size_t nbSubStm,
const std::string& query,const std::vector<NodePtr>& startNodes);
virtual ~MatchResult() = default;
......@@ -40,16 +65,18 @@ public:
* @brief get the set of the node match for une expression
* @return the set of node of the graph that corresponding to an expression
*/
std::set<NodePtr> getBiggerSolution(void);
std::shared_ptr<MatchSolution> getBiggerSolution(void);
std::vector<std::shared_ptr<MatchSolution>> getSolutions(void);
private:
/**
* @brief recurent function use to inite mSolve in the constructor
* @brief recurrent function use to init mSolve in the constructor
*
**/
void _generateCombinationd( std::size_t idxSubStm, std::vector<std::shared_ptr<FsmRunTimeContext>>& precedence);
void _generateCombination( std::size_t idxSubStm, std::vector<std::shared_ptr<FsmRunTimeContext>>& precedence,const std::string& query,const std::vector<NodePtr>& startNodes);
};
......
......@@ -198,6 +198,13 @@ class ConditionalRegisterFunction {
*/
ConditionalData* run(const std::string key,std::vector<ConditionalData*> & datas);
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<ConditionalData*(std::vector<ConditionalData*> &)>> mWlambda;
......@@ -227,7 +234,7 @@ class ConditionalInterpreter
* @brief the registery for the lambda fuction
* @see ConditionalRegisterFunction
*/
ConditionalRegisterFunction mLambdaRegiter;
ConditionalRegisterFunction mLambdaRegister;
std::vector<ConditionalData*> mResolution ;
......@@ -241,15 +248,25 @@ class ConditionalInterpreter
}
public:
const std::string mKey;
/**
* @brief Constructor
* @param ConditionalExpressions The expression of the test to be performed on the nodes
*/
ConditionalInterpreter(const std::string ConditionalExpressions);
ConditionalInterpreter(const std::string key,const std::string ConditionalExpressions);
~ConditionalInterpreter(){clearRes();}
/**
* @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() whith the $ init whit the nodeOp
......@@ -266,7 +283,7 @@ class ConditionalInterpreter
*/
void insertLambda(const std::string key,std::function<bool(Aidge::NodePtr)> f);
bool isLambdaRegister(const std::string &key);
/////
private:
......
......@@ -3,15 +3,24 @@
using namespace Aidge;
GraphFsmInterpreter::GraphFsmInterpreter(const std::string graphMatchExpr,std::map<std::string,std::shared_ptr<ConditionalInterpreter>> nodesCondition):mParser(graphMatchExpr){
GraphFsmInterpreter::GraphFsmInterpreter(const std::string graphMatchExpr,std::vector<std::shared_ptr<ConditionalInterpreter>>&nodesCondition):mParser(graphMatchExpr){
mActGroupe = 0;
mNodesCondition = nodesCondition;
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();
return visit(tree);
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();
......@@ -44,7 +53,7 @@ std::shared_ptr<FsmGraph> GraphFsmInterpreter::keyF(std::shared_ptr<AstNode<gReg
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>();
std::shared_ptr<FsmGraph> graph = std::make_shared<FsmGraph>(mParser.getQuery());
std::shared_ptr<FsmEdge> edge;
......@@ -66,7 +75,7 @@ std::shared_ptr<FsmGraph> GraphFsmInterpreter::keyF(std::shared_ptr<AstNode<gReg
std::shared_ptr<FsmGraph> GraphFsmInterpreter::sepF(std::shared_ptr<FsmGraph> leftFsm,std::shared_ptr<FsmGraph> rigthFsm){
size_t idxLeft = leftFsm->getNbSubFsm();
rigthFsm->incOrigineAllNodeBy(idxLeft);
rigthFsm->incOriginAllNodeBy(idxLeft);
leftFsm->unionG(rigthFsm);
//the rigthFsm is no longer usfull
return leftFsm;
......
......@@ -133,6 +133,11 @@ 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){
std::ostringstream errorMessage;
errorMessage << "\nBad syntax " << currentChars << " :\n" << mRegularExpressions << "\n";
......
......@@ -9,6 +9,10 @@ mLexer(gRegexExpressions)
}
const std::string GraphParser::getQuery(){
return mLexer.getQuery();
}
std::shared_ptr<AstNode<gRegexTokenTypes>> GraphParser::parse(void){
std::shared_ptr<AstNode<gRegexTokenTypes>> astTree = constructAstAllExpr();
......
#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){
mQuery.push_back(query);
}
// 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();
}
}
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]);
}
}
}
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) {
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::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");
}
_majConditionalInterpreterLambda();
}
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);
}
}
}
}
......@@ -24,7 +24,7 @@ void FsmEdge::updateRelative( const std::map<size_t,int>& relativePos ){
std::shared_ptr<FsmNode> FsmEdge::getSourceNode(void){
return mNodeSource;
}
void FsmEdge::reSetSouceNode(const std::shared_ptr<FsmNode>& newSource){
void FsmEdge::reSetSourceNode(const std::shared_ptr<FsmNode>& newSource){
mNodeSource->rmEdge(shared_from_this());
mNodeSource = newSource;
mNodeSource->addEdge(shared_from_this());
......@@ -258,6 +258,11 @@ const std::string lexeme)
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()){
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);
......@@ -267,6 +272,11 @@ const std::string lexeme)
std::smatch m;
if (std::regex_match(lexeme, m, uniqueRegex)) {
std::string edgeType = m[1];
if(allTest.find(edgeType) == allTest.end()){
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\"");
......
......@@ -4,12 +4,13 @@ using namespace Aidge;
FsmGraph::FsmGraph(/* args */){
FsmGraph::FsmGraph(const std::string query):mQuery(query){
}
//TODO
std::shared_ptr<MatchResult> FsmGraph::test(std::vector<NodePtr>& startNodes){
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");
......@@ -61,8 +62,8 @@ FsmGraph::FsmGraph(/* args */){
nextWalks.clear();
}
return std::make_shared<MatchResult>(allValidContext,getNbSubFsm());
MatchResult allMatch(allValidContext,getNbSubFsm(),mQuery,startNodes);
return allMatch.getSolutions();
}
......@@ -77,8 +78,8 @@ const std::set<std::shared_ptr<FsmEdge>>& FsmGraph::getEdge(void){
void FsmGraph::addEdge(std::shared_ptr<FsmEdge>& edge){
edge->updateWeak();
mEdges.insert(edge);
mAllOrigine.insert(edge->getDestNode()->getOrigine());
mAllOrigine.insert(edge->getSourceNode()->getOrigine());
mAllOrigin.insert(edge->getDestNode()->getOrigin());
mAllOrigin.insert(edge->getSourceNode()->getOrigin());
}
const std::vector<std::shared_ptr<FsmNode>> FsmGraph::getStartNodes(void){
......@@ -151,15 +152,19 @@ void FsmGraph::mergeOneStartOneValid(const std::shared_ptr<FsmGraph> fsmGraph){
}
std::size_t FsmGraph::getNbSubFsm(void){
return mAllOrigine.size();
return mAllOrigin.size();
}
std::size_t FsmGraph::getNbStart(void){
return getStartNodes().size();
}
void FsmGraph::incOrigineAllNodeBy(std::size_t incr){
void FsmGraph::incOriginAllNodeBy(std::size_t incr){
std::set<std::shared_ptr<FsmNode>> nodes = getNodes();
for(auto node :nodes){
node->incOrigine(incr);
node->incOrigin(incr);
}
for(auto origin : mAllOrigine){
for(auto origin : mAllOrigin){
origin += incr;
}
}
......@@ -185,7 +190,7 @@ void FsmGraph::_mergeNode(std::shared_ptr<FsmNode> source,std::shared_ptr<FsmNod
if(edge->getDestNode() == source ){
edge->reSetDestNode(dest);
}else if(edge->getSourceNode() == source ){
edge->reSetSouceNode(dest);
edge->reSetSourceNode(dest);
}
}
......
......@@ -53,11 +53,11 @@ const std::vector<std::shared_ptr<FsmRunTimeContext>> FsmNode::test( std::shared
std::size_t FsmNode::getOrigine(void){
return mOrigineStm;
std::size_t FsmNode::getOrigin(void){
return mOriginFsm;
}
void FsmNode::incOrigine(std::size_t inc){
mOrigineStm += inc;
void FsmNode::incOrigin(std::size_t inc){
mOriginFsm += inc;
}
void FsmNode::rmEdge(std::shared_ptr<FsmEdge> edge){
mEdges.erase(edge);
......@@ -93,7 +93,7 @@ const std::set<std::weak_ptr<FsmEdge>,lex_compare<FsmEdge>>& FsmNode::getEdges(v
}
void FsmNode::setGroupe(std::size_t groupeIdx){
mGroupeStm = groupeIdx;
mGroupeFsm = groupeIdx;
}
......
......@@ -155,7 +155,7 @@ void FsmRunTimeContext::setValid(NodePtr node,std::shared_ptr<ConditionalInterpr
}
std::size_t FsmRunTimeContext::getSubStmId(void){
return mActState->getOrigine();
return mActState->getOrigin();
}
NodePtr FsmRunTimeContext::getCommonNodeFromIdx(std::size_t commonIdx){
......@@ -207,7 +207,7 @@ std::set<NodePtr> FsmRunTimeContext::getValidNodesNoCommon(void){
return differenceSet;
}
std::map<std::shared_ptr<ConditionalInterpreter>,std::set<NodePtr>> FsmRunTimeContext::getValid(void){
std::map<std::shared_ptr<ConditionalInterpreter>,std::set<NodePtr>>& FsmRunTimeContext::getValid(void){
return mValidNodes;
}
......
......@@ -2,10 +2,63 @@
using namespace 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<NodePtr> & MatchSolution::at(const std::string key){
return mSolution[key];
MatchResult::MatchResult(std::vector<std::shared_ptr<FsmRunTimeContext>> allValid, std::size_t nbSubStm):mIdToRunTime(nbSubStm){
}
const std::set<NodePtr> 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 MatchSolution::areCompatible(std::shared_ptr<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()));
if (intersection.empty()) {
return true;
}
return false;
}
////////////////////////////////
//
////////////////////////////////
MatchResult::MatchResult(std::vector<std::shared_ptr<FsmRunTimeContext>> allValid, std::size_t nbSubStm,
const std::string& query,const std::vector<NodePtr>& startNodes):mIdToRunTime(nbSubStm),mNbSubStm(nbSubStm){
mAllValid = allValid;
mNbSubStm = nbSubStm;
//mIdToRunTimm
for (const auto& contextPtr : allValid) {
......@@ -13,25 +66,26 @@ MatchResult::MatchResult(std::vector<std::shared_ptr<FsmRunTimeContext>> allVali
}
std::vector<std::shared_ptr<FsmRunTimeContext>> precedence;
//make all solution posible
_generateCombinationd(0,precedence);
//make all solution possible
_generateCombination(0,precedence,query,startNodes);
//sort by solution number of elements
std::sort(mSolve.begin(), mSolve.end(), [](const std::set<NodePtr>& set1, const std::set<NodePtr>& set2) {
return set1.size() < set2.size();
std::sort(mSolve.begin(), mSolve.end(), [](std::shared_ptr<MatchSolution>& set1, std::shared_ptr<MatchSolution>& set2) {
return set1->getAll().size() < set2->getAll().size();
});
}
void MatchResult::_generateCombinationd( std::size_t idxSubStm, std::vector<std::shared_ptr<FsmRunTimeContext>>& precedence){
void MatchResult::_generateCombination( std::size_t idxSubStm, std::vector<std::shared_ptr<FsmRunTimeContext>>& precedence,
const std::string& query,const std::vector<NodePtr>& startNodes){
//it's end , we are below the number of stm
if (idxSubStm == mNbSubStm)
{
//precedence containe a liste of FSM compatible, we just need to
//check if all the node have been valide by at least one contetext
//precedence contain a list of FSM compatible, we just need to
//check if all the node have been valid by at least one context
//1) make the set of all node for the comput graph that are valide in all the FsmRunTimeContext
//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) {
......@@ -40,11 +94,11 @@ void MatchResult::_generateCombinationd( std::size_t idxSubStm, std::vector<std:
std::set<NodePtr> tmpR = contextPtr->getRejectedNodes();
rejectNode.insert(tmpR.begin(),tmpR.end());
}
// 2) all RejectedNodes need to be valide by an others stm
// 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(validNode);
mSolve.push_back(std::make_shared<MatchSolution>(precedence,query,startNodes));
}
precedence.pop_back();
return;
......@@ -55,10 +109,10 @@ void MatchResult::_generateCombinationd( std::size_t idxSubStm, std::vector<std:
{
if(idxSubStm == 0){
precedence.push_back(contextPtrOneFsm);
_generateCombinationd(idxSubStm+1,precedence);
_generateCombination(idxSubStm+1,precedence,query,startNodes);
}else{
//test if the new context is compatible whith all the context in the precedence
//test if the new context is compatible with all the context in the precedence
//
bool compatibleSolutionFsm = true;
for (const auto& contextPtrOfOtherFsm : precedence) {
......@@ -70,7 +124,7 @@ void MatchResult::_generateCombinationd( std::size_t idxSubStm, std::vector<std:
if(compatibleSolutionFsm){
precedence.push_back(contextPtrOneFsm);
_generateCombinationd(idxSubStm+1,precedence);
_generateCombination(idxSubStm+1,precedence,query,startNodes);
}
}
......@@ -83,11 +137,16 @@ void MatchResult::_generateCombinationd( std::size_t idxSubStm, std::vector<std:
}
std::set<NodePtr> MatchResult::getBiggerSolution(void){
std::shared_ptr<MatchSolution> MatchResult::getBiggerSolution(void){
if(mSolve.empty()){
return std::set<NodePtr>();
return nullptr;
}else{
return mSolve[0];
}
}
std::vector<std::shared_ptr<MatchSolution>> MatchResult::getSolutions(void){
return mSolve;
}
\ No newline at end of file
......@@ -18,20 +18,30 @@ using namespace Aidge;
}
}
//////////////////////
//ConditionalInterpreter
///////////////////////
ConditionalInterpreter::ConditionalInterpreter(const std::string ConditionalExpressions)
:mLambdaRegiter()
ConditionalInterpreter::ConditionalInterpreter(const std::string key,const std::string ConditionalExpressions)
:mLambdaRegister(),mKey(key)
{
ConditionalParser conditionalParser = ConditionalParser(ConditionalExpressions);
mTree = conditionalParser.parse();
///lambda by default
mLambdaRegiter.insert("getType",+[](NodePtr NodeOp){return NodeOp->type();});
mLambdaRegister.insert("getType",+[](NodePtr 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 NodePtr nodeOp)
{
......@@ -40,15 +50,15 @@ using namespace Aidge;
try{
std::vector<ConditionalData*> r = visit({mTree},nodeOp);
if (mResolution.size() != 1){
throw std::runtime_error("Multy output interpretation output");
}else{
if (!mResolution[0]->isTypeEqualTo<bool>()){
throw std::runtime_error("TEST OUT MUST BE A BOOL ");
if (mResolution.size() != 1){
throw std::runtime_error("Multi output interpretation output");
}else{
return mResolution[0]->getValue<bool>();
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){
std::ostringstream errorMessage;
......@@ -58,7 +68,7 @@ using namespace Aidge;
}
void ConditionalInterpreter::insertLambda(const std::string key,std::function<bool(Aidge::NodePtr)> f){
mLambdaRegiter.insert<std::function<bool(Aidge::NodePtr)> >(key, f);
mLambdaRegister.insert<std::function<bool(Aidge::NodePtr)> >(key, f);
}
/////
......@@ -169,7 +179,7 @@ using namespace Aidge;
}
}catch(const std::exception& e){
std::ostringstream errorMessage;
errorMessage << "Error in visiting AST for node"<< nodeOp->name() << "\n\t" << e.what() << "\n";
errorMessage << "Error in visiting AST for node "<< nodeOp->name() << "\n\t" << e.what() << "\n";
throw std::runtime_error(errorMessage.str());
}
}
......@@ -210,7 +220,7 @@ using namespace Aidge;
//if the lambda have input
ConditionalData* data;
try {
data = mLambdaRegiter.run(node->getValue(),mResolution);
data = mLambdaRegister.run(node->getValue(),mResolution);
} catch (const std::exception& e) {
std::ostringstream errorMessage;
errorMessage << "Error in conditional interpretation when run the "<< node->getValue() <<" Lambda\n\t" << e.what() << "\n";
......@@ -230,7 +240,7 @@ using namespace Aidge;
auto b = mResolution[1];
if (a->getType() != b->getType()){
throw std::runtime_error("EQ Unsuported between type :" + a->getType() +" "+ b->getType());
throw std::runtime_error("EQ Unsupported between type :" + a->getType() +" "+ b->getType());
}
......@@ -262,7 +272,7 @@ using namespace Aidge;
auto b = mResolution[1];
if (a->getType() != b->getType()){
throw std::runtime_error("NEQ Unsuported between type :" + a->getType() +" "+ b->getType());
throw std::runtime_error("NEQ Unsupported between type :" + a->getType() +" "+ b->getType());
}
ConditionalData* data = new ConditionalData;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment