Exemple #1
0
static
depth findMinWidth(const NGHolder &h, NFAVertex src) {
    if (isLeafNode(src, h)) {
        return depth::unreachable();
    }

    typedef boost::filtered_graph<NFAGraph, SpecialEdgeFilter> StartGraph;
    StartGraph g(h.g, SpecialEdgeFilter(&h));

    assert(hasCorrectlyNumberedVertices(h));
    const size_t num = num_vertices(h);
    vector<depth> distance(num, depth::unreachable());
    distance.at(g[src].index) = depth(0);

    auto index_map = get(&NFAGraphVertexProps::index, g);

    // Since we are interested in the single-source shortest paths on a graph
    // with the same weight on every edge, using BFS will be faster than
    // Dijkstra here.
    breadth_first_search(
        g, src,
        visitor(make_bfs_visitor(record_distances(
                    make_iterator_property_map(distance.begin(), index_map),
                    boost::on_tree_edge()))).vertex_index_map(index_map));

    DEBUG_PRINTF("d[accept]=%s, d[acceptEod]=%s\n",
                 distance.at(NODE_ACCEPT).str().c_str(),
                 distance.at(NODE_ACCEPT_EOD).str().c_str());

    depth d = min(distance.at(NODE_ACCEPT), distance.at(NODE_ACCEPT_EOD));

    if (d.is_unreachable()) {
        return d;
    }

    assert(d.is_finite());
    assert(d > depth(0));
    return d - depth(1);
}
Exemple #2
0
depth findMaxWidth(const NGHolder &h, u32 top) {
    return findMaxWidth(h, SpecialEdgeFilter(h, top));
}
Exemple #3
0
depth findMaxWidth(const NGHolder &h) {
    return findMaxWidth(h, SpecialEdgeFilter(h));
}
Exemple #4
0
static
depth findMaxWidth(const NGHolder &h, NFAVertex src) {
    if (isLeafNode(src, h.g)) {
        return depth::unreachable();
    }

    if (hasReachableCycle(h, src)) {
        // There's a cycle reachable from this src, so we have inf width.
        return depth::infinity();
    }

    typedef boost::filtered_graph<NFAGraph, SpecialEdgeFilter> NodeFilteredGraph;
    NodeFilteredGraph g(h.g, SpecialEdgeFilter(&h));

    assert(hasCorrectlyNumberedVertices(h));
    const size_t num = num_vertices(h);
    vector<int> distance(num);
    vector<boost::default_color_type> colors(num);

    auto index_map = get(&NFAGraphVertexProps::index, g);

    // DAG shortest paths with negative edge weights.
    dag_shortest_paths(
        g, src,
        distance_map(make_iterator_property_map(distance.begin(), index_map))
            .weight_map(boost::make_constant_property<NFAEdge>(-1))
            .vertex_index_map(index_map)
            .color_map(make_iterator_property_map(colors.begin(), index_map)));

    depth acceptDepth, acceptEodDepth;
    if (colors.at(NODE_ACCEPT) == boost::white_color) {
        acceptDepth = depth::unreachable();
    } else {
        acceptDepth = -1 * distance.at(NODE_ACCEPT);
    }
    if (colors.at(NODE_ACCEPT_EOD) == boost::white_color) {
        acceptEodDepth = depth::unreachable();
    } else {
        acceptEodDepth = -1 * distance.at(NODE_ACCEPT_EOD);
    }

    depth d;
    if (acceptDepth.is_unreachable()) {
        d = acceptEodDepth;
    } else if (acceptEodDepth.is_unreachable()) {
        d = acceptDepth;
    } else {
        d = max(acceptDepth, acceptEodDepth);
    }

    if (d.is_unreachable()) {
        // If we're actually reachable, we'll have a min width, so we can
        // return infinity in this case.
        if (findMinWidth(h, src).is_reachable()) {
            return depth::infinity();
        }
        return d;
    }

    // Invert sign and subtract one for start transition.
    assert(d.is_finite() && d > depth(0));
    return d - depth(1);
}