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)
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)]
def test_graph_dp_filter(): def vertex_filter(u): return u < 2 def edge_filter(e, g, vertex_filter): return vertex_filter(source(e, g)) and vertex_filter(target(e, g)) g = make_g() gdp = GraphDp( g, dv={"color": "red"}, de={"color": "purple"}, dpv={ "fontcolor": make_func_property_map(lambda e: "blue" if e % 2 else "green") }) ipynb_display_graph(gdp, vs=(u for u in vertices(g) if vertex_filter(u)), es=(e for e in edges(g) if edge_filter(e, g, vertex_filter))) gdp = GraphDp( g, dv={"color": "red"}, de={"color": "purple"}, dpv={ "fontcolor": make_func_property_map(lambda e: "blue" if e % 2 else "green") })
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}"
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)
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)
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)
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_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)
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)
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)
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
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 test_graph_view_default(): print("test_graph_view_default") g = make_graph() gv = GraphView(g) e = next(iter(edges(gv))) print(e) assert source(e, gv) == 0 assert target(e, gv) == 1 html("gv") ipynb_display_graph(gv) assert {u for u in vertices(g)} == {u for u in vertices(gv)} assert {e for e in edges(g)} == {e for e in edges(gv)} assert {e for e in out_edges(0, g)} == {e for e in out_edges(0, gv)} assert out_degree(0, g) == out_degree(0, gv) gv1 = GraphView(g, pmap_vrelevant = make_func_property_map(lambda u: bool(u % 3 != 0))) html("gv1") ipynb_display_graph(gv1) assert num_vertices(gv1) == 6 assert num_edges(gv1) == 3 gv2 = GraphView(g, pmap_erelevant = make_func_property_map(lambda e: bool(source(e, gv) % 2))) html("gv2") ipynb_display_graph(gv2) assert {u for u in vertices(g)} == {u for u in vertices(gv2)} assert {e for e in edges(g)} != {e for e in edges(gv2)} assert num_vertices(gv2) == num_vertices(g) assert num_edges(gv2) == 4
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
def test_graph_view_or(): print("test_graph_view_or") g = make_graph() gv1 = GraphView(g, pmap_vrelevant = make_func_property_map(lambda u: u < 5)) gv2 = GraphView(g, pmap_vrelevant = make_func_property_map(lambda u: u > 5)) gv = gv1 | gv2 html("gv1") ipynb_display_graph(gv1) html("gv2") ipynb_display_graph(gv2) html("gv1 | gv2") ipynb_display_graph(gv) assert num_vertices(gv) == 9 assert num_edges(gv) == 7
def test_graph_view_sub(): g = make_graph() gv1 = GraphView(g, pmap_vrelevant = make_func_property_map(lambda u: u > 2)) gv2 = GraphView(g, pmap_vrelevant = make_func_property_map(lambda u: u > 6)) gv = gv1 - gv2 html("gv1") ipynb_display_graph(gv1) html("gv2") ipynb_display_graph(gv2) html("gv1 - gv2") ipynb_display_graph(gv) assert {u for u in vertices(g)} != {u for u in vertices(gv)} assert {e for e in edges(g)} != {e for e in edges(gv)} assert num_vertices(gv) == 4 assert num_edges(gv) == 3
def test_graph_view_and(): g = make_graph() gv1 = GraphView(g, pmap_vrelevant = make_func_property_map(lambda u: u > 2)) gv2 = GraphView(g, pmap_vrelevant = make_func_property_map(lambda u: u < 6)) gv = gv1 & gv2 html("gv1") ipynb_display_graph(gv1) html("gv2") ipynb_display_graph(gv2) html("gv1 & gv2") ipynb_display_graph(gv) assert {u for u in vertices(g)} != {u for u in vertices(gv)} assert {e for e in edges(g)} != {e for e in edges(gv)} assert {e for e in out_edges(2, g)} != {e for e in out_edges(2, gv)} assert {e for e in out_edges(3, g)} == {e for e in out_edges(3, gv)} assert {e for e in out_edges(4, g)} == {e for e in out_edges(4, gv)} assert {e for e in out_edges(5, g)} != {e for e in out_edges(5, gv)} assert num_vertices(gv) == 3 assert num_edges(gv) == 2
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)
def test_graph_to_html(): g = DirectedGraph(2) (e, _) = add_edge(0, 1, g) shtml = graph_to_html(g) if in_ipynb(): ipynb_display_graph(g)
def test_graph_to_html_with_pmaps(): # Configure theme GraphvizStyle.set_fg_color("grey") GraphvizStyle.set_bg_color("transparent") display_graph = ipynb_display_graph from pybgl.graph_dp import GraphDp from pybgl.property_map import make_func_property_map def vertex_filter(u): return u < 5 def edge_filter(e, g, vertex_filter): return vertex_filter(source(e, g)) and vertex_filter(target(e, g)) for G in [DirectedGraph, UndirectedGraph]: html(str(G)) g = make_graph(G) # Graph configuration display dv = {"color": "purple"} de = {"color": "red"} dpv = { "fontcolor": make_func_property_map(lambda e: "cyan" if e % 2 else "orange") } dpe = { "fontcolor": make_func_property_map(lambda e: "blue" if source(e, g) % 2 else "red"), "label": make_func_property_map( lambda e: f"({source(e, g)}, {target(e, g)})") } # Choose view # Omit vs (resp. es) to iterate over all vertices (resp. edges) vs = [u for u in vertices(g) if vertex_filter(u)] es = [e for e in edges(g) if edge_filter(e, g, vertex_filter)] # Method1: call helper (ipynb_display_graph, graph_to_html) shtml = graph_to_html(g, dpv=dpv, dpe=dpe, dv=dv, de=de, vs=vs, es=es) assert isinstance(shtml, str) if in_ipynb(): ipynb_display_graph(g, dpv=dpv, dpe=dpe, dv=dv, de=de, vs=vs, es=es) # Method2: use GraphDp. This offers the opportunity to export the # displayed graph to other export formats. gdp = GraphDp(g, dpv=dpv, dpe=dpe, dv=dv, de=de) # These two commands have the same outcome shtml = graph_to_html(gdp, vs=vs, es=es) assert isinstance(shtml, str) shtml = graph_to_html(gdp, dpv=dpv, dpe=dpe, dv=dv, de=de, vs=vs, es=es) assert isinstance(shtml, str) if in_ipynb(): # These two commands have the same outcome ipynb_display_graph(gdp, vs=vs, es=es) ipynb_display_graph(gdp, dpv=dpv, dpe=dpe, dv=dv, de=de, vs=vs, es=es)
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)