Example #1
0
def _test_revuz_minimize(g: IncidenceAutomaton, e_expected: set):
    before_html = graph_to_html(g) if in_ipynb() else None
    revuz_minimize(g)
    if in_ipynb():
        after_html = graph_to_html(g)
        html(beside(before_html, after_html, "Minimization", "Before",
                    "After"))
    check_graph(g, e_expected)
Example #2
0
def test_thompson_compile_nfa_alternation():
    (nfa, q0, f) = thompson_compile_nfa("a*|b")
    if in_ipynb():
        ipynb_display_graph(nfa)
    assert not accepts("bbbbb", nfa)
    assert accepts("b", nfa)
    assert accepts("aaaaaa", nfa)
Example #3
0
def test_trie_trie():
    t1 = make_t1()
    t2 = make_t2()
    t1.insert(t2)
    if in_ipynb(): html(graph_to_html(t1))
    assert num_vertices(t1) == 26
    assert num_vertices(t2) == 12
Example #4
0
def test_graph_to_html_with_weird_chars():
    from pybgl.automaton import Automaton, add_edge
    g = Automaton(2)
    add_edge(0, 1, WEIRD_CHARS, g)
    graph_to_html(g)
    if in_ipynb():
        ipynb_display_graph(g)
Example #5
0
def test_max_suffix_tree_g():
    t = make_suffix_trie("ananas")
    if in_ipynb(): html(graph_to_html(t))
    assert num_vertices(t) == 16
    for q in vertices(t):
        assert is_final(q, t)
    assert not is_final(BOTTOM, t)
def test_dijkstra_shortest_path(links: list = None):
    if links is None:
        links = LINKS
    # Prepare graph
    map_eweight = defaultdict(int)
    pmap_eweight = make_assoc_property_map(map_eweight)
    g = make_graph(links, pmap_eweight, build_reverse_edge=False)

    # Dijkstra, stopped when vertex 9 is reached
    map_vpreds = defaultdict(set)
    map_vdist = defaultdict(int)
    s = 0
    t = 8
    path = dijkstra_shortest_path(g, s, t, pmap_eweight,
                                  make_assoc_property_map(map_vpreds),
                                  make_assoc_property_map(map_vdist))
    if in_ipynb():
        ipynb_display_graph(g,
                            dpe={
                                "color":
                                make_func_property_map(
                                    lambda e: "green" if e in path else "red"),
                                "label":
                                pmap_eweight
                            })
    assert [(source(e, g), target(e, g)) for e in path] == [(0, 5), (5, 6),
                                                            (6, 8)]
Example #7
0
def run_tests(tests):
    """
    Run a list of tests.
    Args:
        tests: A list of pair (f, args) where:
            f: A test_* function, which raise exceptions in case
                of problem.
            args: A tuple corresponding to the parameters passed to f.
    Returns:
        0 in case of success, 1 otherwise.
    """
    ret = 0
    try:
        # Call each tests
        #for name, f in tests.items():
        for f, args in tests:
            s = "Running test: %s%s" % (f.__name__, args)
            if in_ipynb():
                from pybgl.html import html
                html("<b>%s</b>" % s)
            else:
                print(s)
            f(*args)
    except Exception as e:
        print(e)
        print(traceback.format_exc())
        ret = 1
    return ret
Example #8
0
def check_deterministic_inclusion(
    g1 :Automaton,
    g2 :Automaton,
    expected :int,
    show_g1 :bool = True,
    show_g2 :bool = True
):
    obtained = deterministic_inclusion(g1, g2)

    if in_ipynb():
        from pybgl.graphviz import graph_to_html
        from pybgl.html     import html
        l = list()
        if show_g1:
            l += ["<b>A</b>",  TEMPLATE_HTML % graph_to_html(g1)]
        if show_g2:
            l += ["<b>A'</b>", TEMPLATE_HTML % graph_to_html(g2)]
        result = "A c A'" if obtained == 1 else \
                 "A = A'" if obtained == 0 else \
                 "A' c A" if obtained == -1 else \
                 "A ! A'" if obtained is None else \
                 "??????"
        l.append(result)
        html("<br/>".join(l))

    assert obtained == expected, "obtained = %s expected = %s" % (obtained, expected)
Example #9
0
def test_graph_to_html_with_html_sequences():
    from collections import defaultdict
    from pybgl.property_map import make_assoc_property_map

    g = DirectedGraph(2)
    (e, _) = add_edge(0, 1, g)
    pmap_vlabel = make_assoc_property_map(defaultdict(str))
    pmap_elabel = make_assoc_property_map(defaultdict(str))
    gdp = GraphDp(g, dpv={"label": pmap_vlabel}, dpe={"label": pmap_elabel})

    for label in [
            "<b>foo</b>",
            "<foo>",
            "<",
            ">",
            "<b>foo</b><bar>",
            "<bar><b>foo</b>",
            "<font color='red'><b>foo</b></font>",
            # NB: foo.png must exists + graphviz imposes <img/> not <img>
            #"<table><tr><td><img src='foo.png'/></td></tr></table>",
    ]:
        print(f"{label} --> {graphviz_escape_html(label)}")
        pmap_vlabel[0] = pmap_vlabel[1] = pmap_elabel[e] = label
        shtml = graph_to_html(gdp)
        if in_ipynb():
            html(shtml)
            ipynb_display_graph(gdp)
Example #10
0
def test_thompson_compile_nfa_repetition():
    (nfa, q0, f) = thompson_compile_nfa("((ab){3})*")
    if in_ipynb():
        ipynb_display_graph(nfa)
    for i in range(7):
        assert accepts("ab" * i,
                       nfa) == (i % 3 == 0), f"w = {'ab' * i}, i = {i}"
Example #11
0
def test_thompson_compile_nfa_one_or_more():
    (nfa, q0, f) = thompson_compile_nfa("(ab+)+")
    if in_ipynb():
        ipynb_display_graph(nfa)
    assert not accepts("", nfa)
    assert not accepts("b", nfa)
    assert accepts("abbbbb", nfa)
    assert accepts("abbbbbabbbbbabbbbb", nfa)
Example #12
0
def test_thompson_compile_nfa_concatenation():
    (nfa, q0, f) = thompson_compile_nfa("a+b+")
    if in_ipynb():
        ipynb_display_graph(nfa)
    assert not accepts("abab", nfa)
    assert not accepts("aaa", nfa)
    assert not accepts("bbb", nfa)
    assert accepts("ab", nfa)
    assert accepts("aaaaaabbbbbb", nfa)
def test_graph_extract_small(threshold :int = 50):
    g = DirectedGraph(5)
    (e01, _) = add_edge(0, 1, g)
    (e02, _) = add_edge(0, 2, g)
    (e04, _) = add_edge(0, 4, g)
    (e12, _) = add_edge(1, 2, g)
    (e23, _) = add_edge(2, 3, g)
    (e24, _) = add_edge(2, 4, g)
    (e40, _) = add_edge(4, 0, g)
    (e44, _) = add_edge(4, 4, g)
    pmap_eweight = make_assoc_property_map({
        e01 : 83,
        e02 : 3,
        e04 : 78,
        e12 : 92,
        e23 : 7,
        e24 : 18,
        e40 : 51,
        e44 : 84,
    })

    extracted_edges = set()
    pmap_erelevant = make_func_property_map(lambda e: pmap_eweight[e] >= threshold)
    graph_extract(
        0, g,
        pmap_erelevant        = pmap_erelevant,
        callback_edge_extract = lambda e, g: extracted_edges.add(e)
    )

    if in_ipynb():
        pmap_extracted = make_func_property_map(lambda e: e in extracted_edges)
        html(dotstr_to_html(GraphDp(
            g,
                dpe = {
                    "color" : make_func_property_map(lambda e : "darkgreen" if pmap_extracted[e] else "lightgrey"),
                    "style" : make_func_property_map(lambda e : "solid"     if pmap_extracted[e] else "dashed"),
                    "label" : pmap_eweight,
                }
            ).to_dot())
        )

    expected_edges = None

    if threshold == 0:
        expected_edges = {e for e in edges(g)}
    elif threshold == 50:
        expected_edges = {e12, e40, e44, e04, e01}
    elif threshold > 100:
        expected_edges = set()

    if expected_edges is not None:
        assert (extracted_edges == expected_edges), """Invalid edges:
            For threshold = %s:
            extracted: %s
            expected:  %s
        """ % (threshold, sorted(extracted_edges), sorted(expected_edges))
Example #14
0
def test_thompson_compile_nfa_zero_or_one():
    (nfa, q0, f) = thompson_compile_nfa("(ab?)*")
    if in_ipynb():
        ipynb_display_graph(nfa)
    assert accepts("", nfa)
    assert not accepts("b", nfa)
    assert accepts("a", nfa)
    assert accepts("ab", nfa)
    assert accepts("aba", nfa)
    assert not accepts("abb", nfa)
Example #15
0
def test_thompson_compile_nfa_bracket_repetitions():
    (nfa, q0, f) = thompson_compile_nfa("[x-z]{1,3}")
    if in_ipynb():
        ipynb_display_graph(nfa)
    for w in ["x", "y", "xx", "xy", "zy", "xxx", "yyy", "zzz", "xyz", "zyx"]:
        assert accepts(w, nfa) is True
    for w in ["", "xxxx", "aaa"]:
        assert accepts(w, nfa) is False

    (nfa, q0, f) = thompson_compile_nfa("x{3}")
    assert accepts("xxx", nfa)
Example #16
0
def test_moore_determination():
    nfa = make_nfa()
    w = "babbbababcccccd"
    assert accepts(w, nfa)

    for complete in [True, False]:
        dfa = moore_determination(nfa, complete=complete)
        if in_ipynb():
            ipynb_display_graph(dfa)
        assert accepts(w, dfa), f"accepts({w}, dfa) = {accepts(w, dfa)}"

    nfa = make_second_nfa()
    w = ""
    assert accepts(w, nfa)

    for complete in [True, False]:
        dfa = moore_determination(nfa, complete=complete)
        if in_ipynb():
            ipynb_display_graph(dfa)
        assert accepts(w, dfa), f"accepts({w}, dfa) = {accepts(w, dfa)}"
def display_graph(g: Graph,
                  pmap_eweight: ReadPropertyMap = None,
                  map_vpreds: dict = None):
    if in_ipynb():
        dpe = dict()
        if pmap_eweight:
            dpe["label"] = pmap_eweight
        if map_vpreds:
            shortest_path_dag = {e for es in map_vpreds.values() for e in es}
            dpe["color"] = make_func_property_map(
                lambda e: "red" if e in shortest_path_dag else None)
        ipynb_display_graph(g, dpe=dpe)
Example #18
0
def test_read_graphviz_simple():
    g = DirectedGraph()
    dot = """digraph G {
        0;
        1;
        2;
        0->1;
    }"""
    read_graphviz(dot.splitlines(), g)
    if in_ipynb():
        ipynb_display_graph(g)
    assert num_vertices(g) == 3
    assert num_edges(g) == 1
Example #19
0
 def demo_minimal_cover(g: DirectedGraph, min_fds: set):
     if not in_ipynb(): return
     s_dot = GraphDp(
         g,
         dg_default={
             "rankdir": "LR"
         },
         dpe={
             "color":
             make_func_property_map(lambda e: "darkgreen" if edge_to_pair(
                 e, g) in min_fds else "red"),
             "style":
             make_func_property_map(lambda e: "solid" if edge_to_pair(e, g)
                                    in min_fds else "dashed"),
         }).to_dot()
     html(dotstr_to_html(s_dot))
Example #20
0
def test_deterministic_union(show_g1: bool = True,
                             show_g2: bool = True,
                             show_g12: bool = True):
    g1 = make_dafsa1()
    g2 = make_dafsa2()
    g12 = deterministic_union(g1, g2)

    if in_ipynb():
        from pybgl.graphviz import graph_to_html
        from pybgl.html import html
        l = list()
        if show_g1: l += ["<b>A</b>", graph_to_html(g1)]
        if show_g2: l += ["<b>A'</b>", graph_to_html(g2)]
        if show_g12: l += ["<b>A &#x222a; A'</b><br/>", graph_to_html(g12)]
        html("<br/>".join(l))
    assert num_vertices(g12) == 12
    assert num_edges(g12) == 11
Example #21
0
def test_revuz_height():
    g = make_incidence_node_automaton([(0, 1), (0, 2), (1, 2), (1, 3), (2, 4),
                                       (3, 4)],
                                      make_assoc_property_map(
                                          defaultdict(lambda: None, {
                                              1: "a",
                                              2: "b",
                                              3: "a",
                                              4: "c"
                                          })))

    map_vheight = defaultdict()
    pmap_vheight = make_assoc_property_map(map_vheight)
    pmap_vlabel = make_func_property_map(lambda u: "%s<br/>height: %s" %
                                         (u, pmap_vheight[u]))
    max_height = revuz_height(g, pmap_vheight)

    if in_ipynb():
        html(graph_to_html(g))

    assert map_vheight == {0: 3, 1: 2, 2: 1, 3: 1, 4: 0}
    assert max_height == 3, f"Expected max_height = 3, got {max_height}"
Example #22
0
def test_matching_tries():
    both = {"an", "banana"}
    only1 = {"ananas", "x", "y", "z"}
    only2 = {"bananas", "bank", "t"}
    corpus1 = both | only1
    corpus2 = both | only2

    t1 = Trie()
    for w in corpus1:
        t1.insert(w)

    t2 = Trie()
    for w in corpus2:
        t2.insert(w)

    if in_ipynb():
        html(graph_to_html(t1))
        html(graph_to_html(t2))

    l = trie_matching(t1, t2)
    assert l[1] == len(only1)
    assert l[2] == len(only2)
    assert l[3] == len(both)
Example #23
0
def test_read_graphviz_custom():
    from collections import defaultdict
    from pybgl.property_map import ReadWritePropertyMap, make_assoc_property_map
    from pybgl.graphviz import ReadGraphvizVisitor

    class MyReadGraphvizVisitor(ReadGraphvizVisitor):
        def __init__(self, g: Graph, pmap_vlabel: ReadWritePropertyMap,
                     pmap_elabel: ReadWritePropertyMap):
            super().__init__(g)
            self.pmap_vlabel = pmap_vlabel
            self.pmap_elabel = pmap_elabel

        def on_install_vertex_property(self, u, g, key, value):
            if key == "label":
                self.pmap_vlabel[u] = value

        def on_install_edge_property(self, e, g, key, value):
            if key == "label":
                self.pmap_elabel[e] = value

    map_vlabel = defaultdict(str)
    map_elabel = defaultdict(str)
    g = DirectedGraph()
    dot = """digraph G {
        0 [fontsize=8 label='red'];
        1 [label='green'];
        2 [label='blue' fontsize=10];
        0->1 [label='my_label'];
    }"""
    vis = MyReadGraphvizVisitor(g, make_assoc_property_map(map_vlabel),
                                make_assoc_property_map(map_elabel))
    read_graphviz(dot.splitlines(), g, vis)
    if in_ipynb(): ipynb_display_graph(g)
    assert map_vlabel == {0: "red", 1: "green", 2: "blue"}, map_vlabel
    e_01 = next(iter(edges(g)))
    assert map_elabel == {e_01: "my_label"}, map_vlabel
Example #24
0
def test_strong_components():
    # Create the graph
    g = DirectedGraph(7)
    add_edge(0, 1, g)
    add_edge(1, 2, g)
    add_edge(2, 3, g)
    add_edge(3, 1, g)
    add_edge(3, 4, g)
    add_edge(4, 5, g)
    add_edge(5, 6, g)
    add_edge(6, 4, g)

    # Find strong connected components
    map_component = {u : None for u in vertices(g)}
    pmap_component = make_assoc_property_map(map_component)
    strong_components(g, pmap_component)

    # Rendering
    pmap_color = make_assoc_property_map({
        0 : "red",
        1 : "blue",
        2 : "green",
        3 : "purple"
    })
    assert map_component == {
        0 : 2,
        1 : 1,
        2 : 1,
        3 : 1,
        4 : 0,
        5 : 0,
        6 : 0,
    }

    if in_ipynb():
        html(strong_components_to_html(g, pmap_color, pmap_component).replace("\\n", ""))
Example #25
0
def test_graph_copy_small(threshold :int = 50):
    g = DirectedGraph(5)
    (e01, _) = add_edge(0, 1, g)
    (e02, _) = add_edge(0, 2, g)
    (e04, _) = add_edge(0, 4, g)
    (e12, _) = add_edge(1, 2, g)
    (e23, _) = add_edge(2, 3, g)
    (e24, _) = add_edge(2, 4, g)
    (e40, _) = add_edge(4, 0, g)
    (e44, _) = add_edge(4, 4, g)
    map_eweight = {
        e01 : 83,
        e02 : 3,
        e04 : 78,
        e12 : 92,
        e23 : 7,
        e24 : 18,
        e40 : 51,
        e44 : 84,
    }
    pmap_eweight = make_assoc_property_map(map_eweight)
    pmap_erelevant = make_func_property_map(lambda e: pmap_eweight[e] >= threshold)

    g_dup = DirectedGraph(0)

    # Edge duplicate
    map_eweight_dup = dict()
    pmap_eweight_dup = make_assoc_property_map(map_eweight_dup)
    def callback_dup_edge(e, g, e_dup, g_dup):
        pmap_eweight_dup[e_dup] = pmap_eweight[e]

    # Vertex mapping
    map_vertices = dict()
    pmap_vertices = make_assoc_property_map(map_vertices)
    map_edges = dict()
    pmap_edges = make_assoc_property_map(map_edges)

    graph_copy(
        0, g, g_dup,
        pmap_erelevant    = pmap_erelevant,
        pmap_vertices     = pmap_vertices,
        pmap_edges        = pmap_edges,
        callback_dup_edge = callback_dup_edge
    )

    if in_ipynb():
        ori_html = dotstr_to_html(
            GraphDp(
                g,
                dpv = {
                    "label" : make_func_property_map(lambda u: "%s<br/>(becomes %s)" % (u, pmap_vertices[u]))
                },
                dpe = {
                    "color" : make_func_property_map(lambda e : "darkgreen" if pmap_erelevant[e] else "lightgrey"),
                    "style" : make_func_property_map(lambda e : "solid"     if pmap_erelevant[e] else "dashed"),
                    "label" : pmap_eweight,
                }
            ).to_dot()
        )
        dup_html = dotstr_to_html(
            GraphDp(
                g_dup,
                dpe = {
                    "label" : pmap_eweight_dup,
                }
            ).to_dot()
        )
        html(
            """
            <table>
                <tr>
                    <th>Original</th>
                    <th>Extracted</th>
                </tr><tr>
                    <td>%s</td>
                    <td>%s</td>
                </tr>
            </table>
            """ % (ori_html, dup_html)
        )

    if threshold == 50:
        expected_num_edges = 5
        assert map_vertices == {
            0 : 0,
            1 : 1,
            2 : 2,
            4 : 3
        }
        for e, e_dup in map_edges.items():
            u = source(e, g)
            v = target(e, g)
            u_dup = source(e_dup, g_dup)
            v_dup = target(e_dup, g_dup)
            assert u_dup == pmap_vertices[u], "u_dup = %s ; pmap_vertices[%s] = %s" % (u_dup, u, pmap_vertices[u])
            assert v_dup == pmap_vertices[v], "v_dup = %s ; pmap_vertices[%s] = %s" % (v_dup, v, pmap_vertices[v])
            assert pmap_eweight[e] == pmap_eweight_dup[e_dup]
    elif threshold < min([w for w in map_eweight.values()]):
        expected_num_edges = num_edges(g)
    elif threshold > max([w for w in map_eweight.values()]):
        expected_num_edges = 0

    assert expected_num_edges == num_edges(g_dup), \
        """
        Invalid edge number:
          Expected: %s
          Obtained: %s
        """ % (expected_num_edges, num_edges(g_dup))
Example #26
0
 def test_in_ipynb():
     assert in_ipynb() is True
Example #27
0
 def test_in_ipynb():
     assert in_ipynb() is False
Example #28
0
#!/usr/bin/env pytest-3
# -*- coding: utf-8 -*-

__author__ = "Marc-Olivier Buob"
__maintainer__ = "Marc-Olivier Buob"
__email__ = "*****@*****.**"
__copyright__ = "Copyright (C) 2020, Nokia"
__license__ = "BSD-3"

from pybgl.ipynb import in_ipynb, ipynb_get_background_color, ipynb_get_foreground_color

if not in_ipynb():

    def test_in_ipynb():
        assert in_ipynb() is False

    def test_ipynb_get_background_color():
        assert ipynb_get_background_color() is None

    def test_ipynb_get_foreground_color():
        assert ipynb_get_background_color() is None
else:

    def test_in_ipynb():
        assert in_ipynb() is True

    def test_ipynb_get_background_color():
        assert isinstance(ipynb_get_background_color(), str)

    def test_ipynb_get_foreground_color():
        assert isinstance(ipynb_get_background_color(), str)
Example #29
0
def test_thompson_compile_nfa_escaped_operators():
    regexp = r"\|\.\*\+\(\)\{\}\[\]aa"
    (nfa, q0, f) = thompson_compile_nfa(regexp)
    accepts(regexp.replace("\\", ""), nfa)
    if in_ipynb():
        ipynb_display_graph(nfa)
Example #30
0
def test_thompson_compile_nfa():
    (nfa, q0, f) = thompson_compile_nfa("(a?b)*?c+d")
    if in_ipynb():
        ipynb_display_graph(nfa)
    assert accepts("babbbababcccccd", nfa)