From d5ff51ee2c1480aa8daaab8163df7f4084331b8d Mon Sep 17 00:00:00 2001 From: Olivier BICHLER <olivier.bichler@cea.fr> Date: Sun, 19 May 2024 12:46:00 +0200 Subject: [PATCH] Improved doc --- include/aidge/graph/Matching.hpp | 6 ++--- src/graph/Matching.cpp | 42 +++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/include/aidge/graph/Matching.hpp b/include/aidge/graph/Matching.hpp index 441ae44cf..37bd4cf1b 100644 --- a/include/aidge/graph/Matching.hpp +++ b/include/aidge/graph/Matching.hpp @@ -146,13 +146,13 @@ private: std::map<std::string, bool(*)(const NodePtr&)> mLambda; /** - * NODE_OR_BLOCK = BLOCK | NODE + * QUANTIFIER = '?' | '*' | '+' | ('{' [0-9]+ '}') + * NODE_OR_BLOCK = (BLOCK | NODE) QUANTIFIER? */ bool matchNodeOrBlock(Context& ctx, std::set<MatchingResult>& matches); /** - * QUANTIFIER = '?' | '*' | '+' | ('{' [0-9]+ '}') - * BLOCK = '(' SEQ | PAR | BLOCK | ALT | NODE ')' QUANTIFIER? + * BLOCK = '(' SEQ | PAR | BLOCK | ALT | NODE ')' */ bool matchBlock(Context& ctx, std::set<MatchingResult>& matches); diff --git a/src/graph/Matching.cpp b/src/graph/Matching.cpp index d8f03d942..a840b6ab5 100644 --- a/src/graph/Matching.cpp +++ b/src/graph/Matching.cpp @@ -30,7 +30,9 @@ std::set<Aidge::SinglePassGraphMatching::MatchingResult> Aidge::SinglePassGraphM } std::set<Aidge::SinglePassGraphMatching::MatchingResult> Aidge::SinglePassGraphMatching::filterLonguestDisjoint(const std::set<MatchingResult>& matches) { + // Sort matches by highest number of nodes first, thanks to the CompareMatchingResultSize function std::set<MatchingResult, CompareMatchingResultSize> sortedMatches(matches.begin(), matches.end()); + // Keep all the nodes that are already in previous (selected) matches std::set<NodePtr> selectedNodes; std::set<MatchingResult> filteredMatches; @@ -45,6 +47,8 @@ std::set<Aidge::SinglePassGraphMatching::MatchingResult> Aidge::SinglePassGraphM } if (isNonOverlapping) { + // If no node of the current match is already in a previous match, + // the match is disjoint from previous matches and can be kept! filteredMatches.insert(match); selectedNodes.insert(nodes.begin(), nodes.end()); } @@ -59,11 +63,13 @@ bool Aidge::SinglePassGraphMatching::matchNodeOrBlock(Context& ctx, std::set<Mat auto newMatches = matches; ++newCtx.depth; + // (BLOCK | NODE) if (!matchBlock(newCtx, newMatches) && !matchNode(newCtx, newMatches)) { Log::debug("{}{}", std::string(2*ctx.depth, ' '), fmt::styled("×", fmt::fg(fmt::color::red))); return false; } + // QUANTIFIER? bool matchMore = false; size_t matchQuantity = 0; removeWhiteSpace(newCtx.query); @@ -172,6 +178,7 @@ bool Aidge::SinglePassGraphMatching::matchBlock(Context& ctx, std::set<MatchingR auto newMatches = matches; ++newCtx.depth; + // '(' removeWhiteSpace(newCtx.query); if (!newCtx.query.empty() && newCtx.query[0] == '(') { newCtx.query.erase(0, 1); @@ -181,6 +188,7 @@ bool Aidge::SinglePassGraphMatching::matchBlock(Context& ctx, std::set<MatchingR return false; } + // SEQ | PAR | BLOCK | ALT | NODE if (!matchSequence(newCtx, newMatches) && !matchParallel(newCtx, newMatches) && !matchBlock(newCtx, newMatches) @@ -191,6 +199,7 @@ bool Aidge::SinglePassGraphMatching::matchBlock(Context& ctx, std::set<MatchingR return false; } + // ')' removeWhiteSpace(newCtx.query); if (!newCtx.query.empty() && newCtx.query[0] == ')') { newCtx.query.erase(0, 1); @@ -217,6 +226,7 @@ bool Aidge::SinglePassGraphMatching::matchSequence(Context& ctx, std::set<Matchi newCtx.firstNode = true; } + // NODE_OR_BLOCK if (!matchNodeOrBlock(newCtx, newMatches)) { Log::debug("{}{}", std::string(2*ctx.depth, ' '), fmt::styled("×", fmt::fg(fmt::color::red))); return false; @@ -226,6 +236,8 @@ bool Aidge::SinglePassGraphMatching::matchSequence(Context& ctx, std::set<Matchi bool found = false; while (true) { + // (EDGE NODE_OR_BLOCK)+ + // EDGE if (matchEdge(newCtx, newMatches)) { found = true; } @@ -233,6 +245,7 @@ bool Aidge::SinglePassGraphMatching::matchSequence(Context& ctx, std::set<Matchi break; } + // NODE_OR_BLOCK if (!matchNodeOrBlock(newCtx, newMatches)) { Log::debug("{}{}", std::string(2*ctx.depth, ' '), fmt::styled("×", fmt::fg(fmt::color::red))); return false; @@ -260,6 +273,7 @@ bool Aidge::SinglePassGraphMatching::matchParallel(Context& ctx, std::set<Matchi ++newCtx.depth; auto newMatches = matches; + // NODE_OR_BLOCK auto parCtx = newCtx; if (!matchNodeOrBlock(parCtx, newMatches)) { Log::debug("{}{}", std::string(2*ctx.depth, ' '), fmt::styled("×", fmt::fg(fmt::color::red))); @@ -269,6 +283,8 @@ bool Aidge::SinglePassGraphMatching::matchParallel(Context& ctx, std::set<Matchi bool found = false; while (true) { + // ('&' NODE_OR_BLOCK)+ + // '&' removeWhiteSpace(newCtx.query); if (!newCtx.query.empty() && newCtx.query[0] == '&') { newCtx.query.erase(0, 1); @@ -278,7 +294,10 @@ bool Aidge::SinglePassGraphMatching::matchParallel(Context& ctx, std::set<Matchi break; } + // NODE_OR_BLOCK + // reset the ctx to the beginning parCtx = newCtx; + // reset the startNode to the beginning for (auto& newMatch : newMatches) { for (const auto& match : matches) { if (match.graph->rootNode() == newMatch.graph->rootNode()) { @@ -314,6 +333,7 @@ bool Aidge::SinglePassGraphMatching::matchAlternative(Context& ctx, std::set<Mat ++newCtx.depth; std::set<MatchingResult> newMatches; + // NODE_OR_BLOCK auto altCtx = newCtx; auto altMatches = matches; if (!matchNodeOrBlock(altCtx, altMatches)) { @@ -325,6 +345,8 @@ bool Aidge::SinglePassGraphMatching::matchAlternative(Context& ctx, std::set<Mat bool found = false; while (true) { + // ('|' NODE_OR_BLOCK)+ + // '|' removeWhiteSpace(newCtx.query); if (!newCtx.query.empty() && newCtx.query[0] == '|') { newCtx.query.erase(0, 1); @@ -334,6 +356,7 @@ bool Aidge::SinglePassGraphMatching::matchAlternative(Context& ctx, std::set<Mat break; } + // NODE_OR_BLOCK altCtx = newCtx; altMatches = matches; if (!matchNodeOrBlock(altCtx, altMatches)) { @@ -359,6 +382,7 @@ bool Aidge::SinglePassGraphMatching::matchEdge(Context& ctx, std::set<MatchingRe auto newCtx = ctx; Log::debug("{}edge", std::string(2*newCtx.depth, ' ')); + // ('-' | '~') or '<' removeWhiteSpace(newCtx.query); if (!newCtx.query.empty() && (newCtx.query[0] == '-' || newCtx.query[0] == '~')) { newCtx.singleOutput = (newCtx.query[0] == '-'); @@ -374,6 +398,7 @@ bool Aidge::SinglePassGraphMatching::matchEdge(Context& ctx, std::set<MatchingRe return false; } + // optional first IO_INDEX int firstIdx = 0; bool foundFirst = false; const auto endOutputIdx = std::find_if(newCtx.query.begin(), newCtx.query.end(), @@ -389,6 +414,7 @@ bool Aidge::SinglePassGraphMatching::matchEdge(Context& ctx, std::set<MatchingRe foundFirst = true; } + // optional second IO_INDEX, preceded by '-' int secondIdx = 0; bool foundSecond = false; if (foundFirst && !newCtx.query.empty() && newCtx.query[0] == '-') { @@ -413,18 +439,20 @@ bool Aidge::SinglePassGraphMatching::matchEdge(Context& ctx, std::set<MatchingRe } } + // '>' or ('-' | '~') if (newCtx.lookForChild && !newCtx.query.empty() && newCtx.query[0] == '>') { newCtx.query.erase(0, 1); // drop '>' } else if (!newCtx.lookForChild && !newCtx.query.empty() && (newCtx.query[0] == '-' || newCtx.query[0] == '~')) { newCtx.singleOutput = (newCtx.query[0] == '-'); - newCtx.query.erase(0, 1); // drop '-' + newCtx.query.erase(0, 1); } else { Log::debug("{}{}", std::string(2*ctx.depth, ' '), fmt::styled("×", fmt::fg(fmt::color::red))); return false; } + // Parsing is done, update the remaining context newCtx.edgeLeftIdx = 0; newCtx.edgeRightIdx = 0; if (foundFirst && foundSecond) { @@ -458,6 +486,7 @@ bool Aidge::SinglePassGraphMatching::matchNode(Context& ctx, std::set<MatchingRe Log::debug("{}node", std::string(2*newCtx.depth, ' ')); auto newMatches = matches; + // (TYPE | '.') removeWhiteSpace(newCtx.query); if (newCtx.query.empty()) { Log::debug("{}{}", std::string(2*ctx.depth, ' '), fmt::styled("×", fmt::fg(fmt::color::red))); @@ -466,9 +495,11 @@ bool Aidge::SinglePassGraphMatching::matchNode(Context& ctx, std::set<MatchingRe std::string type; if (newCtx.query[0] == '.') { + // '.' newCtx.query.erase(0, 1); // drop '.' } else { + // TYPE const auto endIdentifier = std::find_if(newCtx.query.begin(), newCtx.query.end(), [](char c) { return (!isalnum(c) && c != '_'); }); @@ -481,19 +512,26 @@ bool Aidge::SinglePassGraphMatching::matchNode(Context& ctx, std::set<MatchingRe newCtx.query = newCtx.query.substr(endIdentifier - newCtx.query.begin()); } + // ('#' ANCHOR)? std::string anchor = ""; if (!newCtx.query.empty() && newCtx.query[0] == '#') { + // '#' newCtx.query.erase(0, 1); // drop '#' + + // ANCHOR const auto endAnchor = std::find_if(newCtx.query.begin(), newCtx.query.end(), [](char c) { return (!isalnum(c) && c != '_'); }); anchor = "#" + newCtx.query.substr(0, endAnchor - newCtx.query.begin()); newCtx.query = newCtx.query.substr(endAnchor - newCtx.query.begin()); } + // ('[' LAMBDA ']')? std::string lambda = ""; if (!newCtx.query.empty() && newCtx.query[0] == '[') { + // '[' newCtx.query.erase(0, 1); + // LAMBDA const auto endIdentifier = std::find_if(newCtx.query.begin(), newCtx.query.end(), [](char c) { return (!isalnum(c) && c != '_'); }); @@ -505,6 +543,7 @@ bool Aidge::SinglePassGraphMatching::matchNode(Context& ctx, std::set<MatchingRe lambda = newCtx.query.substr(0, endIdentifier - newCtx.query.begin()); newCtx.query = newCtx.query.substr(endIdentifier - newCtx.query.begin()); + // ']' if (!newCtx.query.empty() && newCtx.query[0] == ']') { newCtx.query.erase(0, 1); } @@ -514,6 +553,7 @@ bool Aidge::SinglePassGraphMatching::matchNode(Context& ctx, std::set<MatchingRe } } + // Parsing is done, try to match the node if (newCtx.firstSequence && newCtx.firstNode) { // First node of first sequence = root node for (auto node : mGraph->getNodes()) { -- GitLab