def test_automaton_match12():
    svg = dotstr_to_html(G1.to_dot())
    html(svg)
    svg = dotstr_to_html(G2.to_dot())
    html(svg)

    obtained = automaton_match(G1, G2)
    assert obtained == "ba"

    html("These automata don't match for w = %r" % obtained)
def test_automaton_match45():
    html(dotstr_to_html(G4.to_dot()))
    html(dotstr_to_html(G5.to_dot()))
    expected = "b"

    obtained = automaton_match(G4, G5)
    assert expected == obtained, "expected = %r obtained = %r" % (expected,
                                                                  obtained)

    obtained = automaton_match(G5, G4)
    assert expected == obtained, "expected = %r obtained = %r" % (expected,
                                                                  obtained)

    html("These automata don't match for w = %r" % obtained)
def test_automaton_match13():
    html(dotstr_to_html(G1.to_dot()))
    html(dotstr_to_html(G3.to_dot()))
    expected = "b"

    obtained = automaton_match(G3, G1)
    assert expected == obtained, "expected = %r obtained = %r" % (expected,
                                                                  obtained)

    obtained = automaton_match(G1, G3)
    assert expected == obtained, "expected = %r obtained = %r" % (expected,
                                                                  obtained)

    html("These automata don't match for w = %r" % obtained)
Esempio n. 4
0
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))
Esempio n. 5
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))
Esempio n. 6
0
def make_automaton_from_observation_table(o: ObservationTable,
                                          verbose: bool = False):
    def f(s):
        pass

    log = html if verbose else f
    map_row_state = dict()
    q0 = 0
    final_states = set()
    transitions = list()

    # Build states
    q = 0
    for s in sorted(o.s):  # Hence q0 = 0
        row = o.row(s)
        if row not in map_row_state.keys():
            map_row_state[row] = q
            is_final = o.get(s, "")
            if is_final:
                final_states.add(q)
            log("Adding state %d for prefix %s (row = %s, is_final = %s)" %
                (q, s, o.row(s), is_final))
            q += 1

    # Build transitions
    for (row, q) in map_row_state.items():
        # Find prefix leading to q
        s = None
        for s in o.s:
            if o.row(s) == row: break
        assert s is not None

        for a in o.a:
            r = map_row_state[o.row(s + a)]
            transitions.append((q, r, a))
            log("Adding %s-transition from %d (%s) to %d (%s)" %
                (a, q, o.row(s), r, o.row(s + a)))

    g = make_automaton(transitions, q0,
                       make_func_property_map(lambda q: q in final_states))
    log("final_states = %s" % final_states)
    log("<pre>make_automaton_from_observation_table</pre> returns:")
    log(dotstr_to_html(g.to_dot()))
    return g
Esempio n. 7
0
def display_strong_components(g, pmap_color, pmap_component) -> str:
    """
    Args:
        g: A DirectedGraph.
        pmap_component: A ReadPropertyMap, mapping a vertex with its strongly
            connected component.
    """
    html = dotstr_to_html(GraphDp(
        g,
        {
            "color" : make_func_property_map(lambda u : pmap_color[pmap_component[u]])
        }, {
            "color" : make_func_property_map(lambda e : edge_color(e, g, pmap_component, pmap_color)),
            "style" : make_func_property_map(lambda e : \
                "solid" if edge_color(e, g, pmap_component, pmap_color, None) else \
                "dashed"
            ),
        }
    ).to_dot())

    return html
def test_automaton_match11():
    html(dotstr_to_html(G1.to_dot()))
    html(dotstr_to_html(G1.to_dot()))
    assert automaton_match(G1, G1) == None

    html("These automata match")
Esempio n. 9
0
File: ipynb.py Progetto: nokia/PyBGL
def ipynb_display_graph(g, background_color=None, **kwargs):
    """
    Display a Graph in a Jupyter Notebook.
    """
    template_html = background_template_html(background_color)
    html(template_html % dotstr_to_html(g.to_dot(**kwargs)))
Esempio n. 10
0
def ipynb_display_graph(g):
    """
    Display a Graph in a Jupyter Notebook.
    """
    html(dotstr_to_html(g.to_dot()))
Esempio n. 11
0
    def learn(self,
              verbose: bool = False,
              write_files: bool = False) -> Automaton:
        self.initialize(verbose=verbose)
        i = 0
        while (True):
            if verbose:
                self.log("<b>iteration %d</b>" % (i + 1))
            is_consistent = self.o.is_consistent()
            is_closed = self.o.is_closed()
            i = 0
            while not (is_consistent and is_closed):
                if not is_consistent:
                    (s1, s2, a, e) = self.o.find_mismatch_consistency()
                    if verbose:
                        self.log(self.o.to_html())
                        self.log(
                            "Observation table is not consistent: (s1, s2, a, e) = %s, adding %s to E"
                            % ((s1, s2, a, e), a + e))
                    self.o.add_suffix(a + e)
                if not is_closed:
                    (s1, a) = self.o.find_mismatch_closeness()
                    if verbose:
                        self.log(self.o.to_html())
                        self.log(
                            "Observation table is not closed: (s1, a) = %s, adding s1 + a = %s to S"
                            % ((s1, a), s1 + a))
                    self.o.s.add(s1 + a)
                    self.o.add_prefix(s1 + a)
                self.extend()
                is_consistent = self.o.is_consistent()
                is_closed = self.o.is_closed()
                i += 1
                #if i > 10:
                #    raise Exception("Implementation error? (infinite loop)")
            if verbose:
                self.log("Observation table is closed and consistent")
                self.log("""
                    <table>
                        <tr>
                            <th>Teacher</th>
                            <th>Observation table</th>
                        </tr>
                        <tr>
                            <td>%s</td>
                            <td>%s</td>
                        </tr>
                    </table>
                    """ % (dotstr_to_html(
                    self.teacher.g.to_dot()), self.o.to_html()))
                assert self.o.is_consistent()
                assert self.o.is_closed()

            h = make_automaton_from_observation_table(self.o, verbose=False)
            if verbose:
                html(dotstr_to_html(h.to_dot()))
                html("Final states: %s" %
                     {q
                      for q in vertices(h) if is_final(q, h)})
            t = self.teacher.conjecture(h)
            if t is not None:
                prefixes = {t[:i] for i in np.arange(1, len(t) + 1)}
                self.o.s |= prefixes
                for s in prefixes:
                    self.o.add_prefix(s)
                self.extend()
                if verbose:
                    self.log("The teacher disagreed: t = %r" % t)
                    self.log(
                        "The following prefixes have been added to S: %s" %
                        prefixes)
                    html("S is now equal to %s" % self.o.s)
                    html(self.o.to_html())
            else:
                if verbose and t is not None:
                    self.log("The teacher agreed :-)")
                break
            i += 1
        return make_automaton_from_observation_table(self.o)
Esempio n. 12
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))