Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
aidge_core
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Eclipse Projects
aidge
aidge_core
Commits
d5ff51ee
Commit
d5ff51ee
authored
10 months ago
by
Olivier BICHLER
Browse files
Options
Downloads
Patches
Plain Diff
Improved doc
parent
426e4c6c
No related branches found
No related tags found
2 merge requests
!152
Update Aidge export to take a graph view has an argument instead of a...
,
!138
Alternative graph matching
Pipeline
#46097
failed
10 months ago
Stage: static_analysis
Stage: build
Stage: test
Stage: coverage
Changes
2
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
include/aidge/graph/Matching.hpp
+3
-3
3 additions, 3 deletions
include/aidge/graph/Matching.hpp
src/graph/Matching.cpp
+41
-1
41 additions, 1 deletion
src/graph/Matching.cpp
with
44 additions
and
4 deletions
include/aidge/graph/Matching.hpp
+
3
−
3
View file @
d5ff51ee
...
...
@@ -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
);
...
...
This diff is collapsed.
Click to expand it.
src/graph/Matching.cpp
+
41
−
1
View file @
d5ff51ee
...
...
@@ -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
())
{
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment