mirror of
https://github.com/VectorCamp/vectorscan.git
synced 2025-06-28 16:41:01 +03:00
ng_calc_components: check tail shell too
This commit is contained in:
parent
f6adc4f464
commit
63973175ed
@ -220,37 +220,51 @@ vector<NFAEdge> findShellEdges(const NGHolder &g,
|
|||||||
return shell_edges;
|
return shell_edges;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
template<typename GetAdjRange>
|
||||||
* True if all edges out of vertices in the head shell lead to at most a single
|
bool shellHasOnePath(const NGHolder &g, const flat_set<NFAVertex> &shell,
|
||||||
* outside vertex.
|
GetAdjRange adj_range_func) {
|
||||||
*/
|
if (shell.empty()) {
|
||||||
static
|
DEBUG_PRINTF("no shell\n");
|
||||||
bool shellHasOnePath(const NGHolder &g,
|
|
||||||
const flat_set<NFAVertex> &head_shell) {
|
|
||||||
if (head_shell.empty()) {
|
|
||||||
DEBUG_PRINTF("no head shell\n");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
NFAVertex succ = NGHolder::null_vertex();
|
NFAVertex exit_vertex = NGHolder::null_vertex();
|
||||||
for (auto u : head_shell) {
|
for (auto u : shell) {
|
||||||
for (auto v : adjacent_vertices_range(u, g)) {
|
for (auto v : adj_range_func(u, g)) {
|
||||||
if (contains(head_shell, v)) {
|
if (contains(shell, v)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!succ) {
|
if (!exit_vertex) {
|
||||||
succ = v;
|
exit_vertex = v;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (succ == v) {
|
if (exit_vertex == v) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True if all edges out of vertices in the head shell lead to at most a single
|
||||||
|
* outside vertex, or the inverse for the tail shell.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
bool shellHasOnePath(const NGHolder &g, const flat_set<NFAVertex> &head_shell,
|
||||||
|
const flat_set<NFAVertex> &tail_shell) {
|
||||||
|
if (shellHasOnePath(g, head_shell, adjacent_vertices_range<NGHolder>)) {
|
||||||
DEBUG_PRINTF("head shell has only one path through it\n");
|
DEBUG_PRINTF("head shell has only one path through it\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (shellHasOnePath(g, tail_shell, inv_adjacent_vertices_range<NGHolder>)) {
|
||||||
|
DEBUG_PRINTF("tail shell has only one path into it\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Common code called by calc- and recalc- below. Splits the given holder into
|
* Common code called by calc- and recalc- below. Splits the given holder into
|
||||||
@ -288,9 +302,9 @@ void splitIntoComponents(unique_ptr<NGHolder> g,
|
|||||||
DEBUG_PRINTF("%zu vertices in head, %zu in tail, %zu shell edges\n",
|
DEBUG_PRINTF("%zu vertices in head, %zu in tail, %zu shell edges\n",
|
||||||
head_shell.size(), tail_shell.size(), shell_edges.size());
|
head_shell.size(), tail_shell.size(), shell_edges.size());
|
||||||
|
|
||||||
// If there's only one way out of the head shell and no shell edges, we
|
// If there are no shell edges and only one path out of the head shell or
|
||||||
// aren't going to find more than one component.
|
// into the tail shell, we aren't going to find more than one component.
|
||||||
if (shell_edges.empty() && shellHasOnePath(*g, head_shell)) {
|
if (shell_edges.empty() && shellHasOnePath(*g, head_shell, tail_shell)) {
|
||||||
DEBUG_PRINTF("single component\n");
|
DEBUG_PRINTF("single component\n");
|
||||||
comps.push_back(std::move(g));
|
comps.push_back(std::move(g));
|
||||||
return;
|
return;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user