Skip to content
Snippets Groups Projects
Commit d5ff51ee authored by Olivier BICHLER's avatar Olivier BICHLER
Browse files

Improved doc

parent 426e4c6c
No related branches found
No related tags found
2 merge requests!152Update Aidge export to take a graph view has an argument instead of a...,!138Alternative graph matching
Pipeline #46097 failed
......@@ -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);
......
......@@ -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()) {
......
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