Ejemplo n.º 1
0
def test_iter():
    vertexes, _ = decorate_nx_graph(nx.balanced_tree(2, 3))
    partition = RankedPartition(vertexes)
    idx = 0
    for r in partition:
        assert r == partition._partition[idx]
        idx += 1
Ejemplo n.º 2
0
def test_well_founded_topological():
    g = nx.DiGraph()
    g.add_nodes_from(range(8))
    g.add_edges_from([(0, 1), (1, 2), (3, 4), (4, 5), (6, 7), (7, 6)])

    partition = [(0, 3), (1, 4), (2, 5), (6, 7)]

    vertexes, _ = decorate_nx_graph(g, partition)

    max_rank = max(map(lambda vx: vx.rank, vertexes))

    qpartition = [block for ls in RankedPartition(vertexes) for block in ls]

    topo = build_well_founded_topological_list(
        qpartition, vertexes[5], max_rank
    )

    assert len(topo) == 6

    last_rank = None
    for vx in topo:
        assert vx.wf
        if last_rank is not None:
            assert last_rank <= vx.rank
        last_rank = vx.rank
Ejemplo n.º 3
0
def test_split_upper_ranks(graph):
    vertexes, _ = decorate_nx_graph(graph)
    max_rank = max(vertex.rank for vertex in vertexes)
    partition_length = 0 if max_rank == float("-inf") else max_rank + 2

    for idx in range(partition_length):
        partition = RankedPartition(vertexes)
        split_upper_ranks(partition, partition[idx][0])
        assert all(
            check_block_stability(partition[idx][0], upper_rank_block)
            for upper_idx in range(idx + 1, partition_length)
            for upper_rank_block in partition[upper_idx])
Ejemplo n.º 4
0
def test_is_in_image():
    graph = nx.DiGraph()
    graph.add_nodes_from(range(5))
    graph.add_edges_from([(0, 1), (1, 2), (2, 3), (4, 1)])

    vertexes, _ = decorate_nx_graph(graph)
    RankedPartition(vertexes)

    assert is_in_image(vertexes[0].qblock, vertexes[1].qblock)
    assert not is_in_image(vertexes[1].qblock, vertexes[0].qblock)
    assert is_in_image(vertexes[1].qblock, vertexes[2].qblock)
    assert is_in_image(vertexes[2].qblock, vertexes[3].qblock)
    assert not is_in_image(vertexes[0].qblock, vertexes[4].qblock)
    assert not is_in_image(vertexes[4].qblock, vertexes[0].qblock)
Ejemplo n.º 5
0
def test_different_blocks_initial_partition():
    graph = nx.balanced_tree(2, 3, create_using=nx.DiGraph)
    initial_partition = [
        (0, 1, 2),
        (3, 4),
        (5, 6),
        (7, 8, 9, 10),
        (11, 12, 13),
        (14, ),
    ]
    vertexes, _ = decorate_nx_graph(nx.balanced_tree(2, 3), initial_partition)

    partition = RankedPartition(vertexes)

    assert len(partition[1]) == 3
    assert len(partition[2]) == 2
Ejemplo n.º 6
0
def test_merge_split_resets_visited_allowvisit_oldqblockid():
    g = nx.DiGraph()
    g.add_nodes_from(range(5))
    g.add_edges_from([(0, 1), (1, 0), (2, 1), (2, 4), (3, 1)])

    partition = [(2, 3), (1, 0), (4,)]

    vertexes, _ = decorate_nx_graph(g, partition)
    qblocks = [block for ls in RankedPartition(vertexes) for block in ls]

    finishing_time_list = [vertexes[2], vertexes[1], vertexes[0]]

    merge_split_phase(qblocks, finishing_time_list)

    assert all([not vertex.visited for vertex in vertexes])
    assert all([not vertex.allow_visit for vertex in vertexes])
Ejemplo n.º 7
0
def test_create_initial_partition(graph):
    vertexes, _ = decorate_nx_graph(graph)
    partition = RankedPartition(vertexes)

    # at least one block per rank, except for float('-inf')
    assert all(len(partition[idx]) for idx in range(1, len(partition)))

    # right vertexes in the right place
    for idx in range(len(partition)):
        rank = float("-inf") if idx == 0 else idx - 1

        # right number of vertexes
        assert partition[idx][0].vertexes.size == [
            vertex.rank == rank for vertex in vertexes
        ].count(True)
        # right rank
        assert all(vertex.rank == rank
                   for vertex in partition[idx][0].vertexes)
Ejemplo n.º 8
0
def test_merge_split_resets_visited_triedmerge_qblocks():
    g = nx.DiGraph()
    g.add_nodes_from(range(5))
    g.add_edges_from([(0, 1), (1, 0), (2, 1), (2, 4), (3, 1)])

    partition = [(2, 3), (1, 0), (4,)]

    vertexes, _ = decorate_nx_graph(g, partition)
    qblocks = [block for ls in RankedPartition(vertexes) for block in ls]

    qblocks[0].visited = True
    qblocks[2].visited = True

    finishing_time_list = [vertexes[2], vertexes[1], vertexes[0]]

    qpartition = merge_split_phase(qblocks, finishing_time_list)

    assert all([not block.visited for block in qpartition])
    assert all([not block.tried_merge for block in qpartition])
Ejemplo n.º 9
0
def test_add_edge():
    graph = nx.DiGraph()
    graph.add_nodes_from(range(5))
    graph.add_edges_from([(0, 1), (1, 2), (2, 3), (4, 1)])

    vertexes, _ = decorate_nx_graph(graph)
    ranked_partition = RankedPartition(vertexes)

    partition = []
    for rank in ranked_partition:
        for block in ranked_partition:
            partition.append(block)

    edge1 = add_edge(vertexes[0], vertexes[3])
    assert edge1.count is not None
    assert edge1.count.value == 2

    edge2 = add_edge(vertexes[3], vertexes[4])
    assert edge2.count is not None
    assert edge2.count.value == 1
Ejemplo n.º 10
0
def test_get_item():
    vertexes, _ = decorate_nx_graph(nx.balanced_tree(2, 3))
    partition = RankedPartition(vertexes)
    assert partition[1] == partition._partition[1]
Ejemplo n.º 11
0
def test_clear_index():
    vertexes, _ = decorate_nx_graph(nx.balanced_tree(2, 3))
    partition = RankedPartition(vertexes)
    partition.clear_index(1)
    assert len(partition[1]) == 0
Ejemplo n.º 12
0
def test_scc_leaf_length():
    vertexes, _ = decorate_nx_graph(nx.balanced_tree(2, 3))
    partition = RankedPartition(vertexes)
    assert partition[0][0].size == 0
Ejemplo n.º 13
0
def test_len():
    vertexes, _ = decorate_nx_graph(nx.balanced_tree(2, 3))
    partition = RankedPartition(vertexes)
    assert len(partition) == 5
Ejemplo n.º 14
0
def test_append_at_index():
    vertexes, _ = decorate_nx_graph(nx.balanced_tree(2, 3))
    partition = RankedPartition(vertexes)
    block = _QBlock([], None)
    partition.append_at_index(block, 1)
    assert partition[1][-1] == block
Ejemplo n.º 15
0
def test_nvertexes(graph):
    vertexes, _ = decorate_nx_graph(graph)
    partition = RankedPartition(vertexes)
    assert partition.nvertexes == len(graph.nodes)
Ejemplo n.º 16
0
def dovier_piazza_policriti(
    graph: nx.Graph,
    initial_partition: List[Tuple[int]] = None,
    is_integer_graph: bool = False,
) -> List[Tuple]:
    """Compute the RSCP/maximum bisimulation of the given graph using
    *Dovier-Piazza-Policriti*'s algorithm.

    Example:
        >>> graph = networkx.balanced_tree(2,3)
        >>> dovier_piazza_policriti(graph)
        [(7, 8, 9, 10, 11, 12, 13, 14), (3, 4, 5, 6), (1, 2), (0,)]

    This function works with integer graph (nodes are integers starting from
    0 and form an interval without holes). If the given graph is non-integer
    it is converted to an isomorphic integer graph automatically (unless
    `is_integer_graph` is `True`) and then re-converted to its original form
    after the end of the computation. For this reason nodes of `graph` **must**
    be hashable objects.

    .. warning::
        Using a non integer graph and setting `is_integer_graph` to `True`
        will probably make the function fail with an exception, or, even worse,
        return a wrong output.

    :param graph: The input graph.
    :param initial_partition: The initial partition (or labeling set). Defaults
        to `None`, in which case the trivial labeling set (one block which
        contains all the nodes) is used.
    :param is_integer_graph: If `True`, we do not check if the given graph is
        integer (saves time). If `is_integer_graph` is `True` but the graph
        is not integer the output may be wrong. Defaults to False.
    :returns: The RSCP/maximum bisimulation of the given labeling set as a
        list of tuples, each of which contains bisimilar nodes.
    """

    if not isinstance(graph, nx.DiGraph):
        raise Exception("graph should be a directed graph (nx.DiGraph)")

    # if True, the input graph is already an integer graph
    original_graph_is_integer = is_integer_graph or check_normal_integer_graph(
        graph)

    if not original_graph_is_integer:
        # convert the graph to an "integer" graph
        integer_graph, node_to_idx = convert_to_integer_graph(graph)
    else:
        integer_graph = graph

    vertexes, _ = decorate_nx_graph(integer_graph, initial_partition)
    partition = RankedPartition(vertexes)

    tp = dovier_piazza_policriti_partition(partition)
    collapsed_partition, collapse_map = tp

    # from the collapsed partition obtained from FBA, build the RSCP (external
    # representation, List[Tuple[int]])
    rscp = []
    for rank in collapsed_partition:
        for block in rank:
            if block.vertexes.size > 0:
                block_survivor_node = block.vertexes.first.value
                block_vertexes = [block_survivor_node.label]

                if collapse_map[block_survivor_node.label] is not None:
                    block_vertexes.extend(
                        map(
                            lambda vertex: vertex.label,
                            collapse_map[block_survivor_node.label],
                        ))

                rscp.append(tuple(block_vertexes))

    if original_graph_is_integer:
        return rscp
    else:
        return back_to_original(rscp, node_to_idx)