def test_delete_corrupted(self):
        """
            a    b
             ___
            / / \
        1  A,B   C
           |/    |
        2  D --- E
        """
        A = Vertex(domain=(1,'a'))
        B = Vertex(domain=(1,'a'))
        D = Vertex(domain=(2,'a'))
        C = Vertex(domain=(1,'b'))
        E = Vertex(domain=(2,'b'))

        AD = Edge(A, D)
        AC = Edge(A, C)
        BC = Edge(B, C)
        BD = Edge(B, D)
        DE = Edge(D, E)
        CE = Edge(C, E)

        g = Graph([A, B, C, D, E], [AD, AC, BC, BD, DE, CE])
        g.prepare()
        self.assertItemsEqual(g.get_vertices(), [A, B, C, D, E])
        self.assertItemsEqual(g.get_edges(), [AD, AC, BC, BD, DE, CE])

        g.delete_edge(BD, True)
        g.delete_corrupted()

        self.assertItemsEqual(g.get_vertices(), [A, C, D, E])
        self.assertItemsEqual(g.get_edges(), [AD, AC, DE, CE])

        self.assertFalse(g.is_neighborhood_corrupted())
    def test_get_links(self):
        """
        a - b - c
        -----
        A - A - A
              /
        B - B
          \
            C
        """
        v_aA = Vertex(domain='a')
        v_aB = Vertex(domain='a')
        v_bA = Vertex(domain='b')
        v_bB = Vertex(domain='b')
        v_bC = Vertex(domain='b')
        v_cA = Vertex(domain='c')

        e_aA_bA = Edge(v_aA, v_bA)
        e_aB_bB = Edge(v_aB, v_bB)
        e_aB_bC = Edge(v_aB, v_bC)
        e_bA_cA = Edge(v_bA, v_cA)
        e_bB_cA = Edge(v_bB, v_cA)

        g = Graph([v_aA, v_aB, v_bA, v_bB, v_bC, v_cA],
                  [e_aA_bA, e_aB_bB, e_bA_cA, e_bB_cA, e_aB_bC])
        g.prepare()
        self.assertItemsEqual(g.get_link(('b', 'c')),
                              [e_bA_cA, e_bB_cA])
        self.assertItemsEqual(g.get_link(('a', 'b')),
                              [e_aA_bA, e_aB_bB, e_aB_bC])
    def test_delete_edge(self):
        """
        a - b
        -----
        B
          \
            C
        """
        v_aB = Vertex(domain='a')
        v_bC = Vertex(domain='b')

        e_aB_bC = Edge(v_aB, v_bC)

        g = Graph([v_aB, v_bC],
                  [e_aB_bC])
        g.prepare()
        g.delete_edge(e_aB_bC)
        self.assertItemsEqual(g.get_edges(), [])
        self.assertItemsEqual(g.get_vertices(), [])
        self.assertTrue(g.is_neighborhood_corrupted())
        """
    def test_prepare(self):
        start = Vertex('start')
        finish = Vertex('finish')

        a = Vertex('a')
        b = Vertex('b')
        c = Vertex('c')

        start_a = Edge(start, a, SemiringMinPlusElement(5))
        a_b = Edge(a, b, SemiringMinPlusElement(1))
        a_c = Edge(a, c, SemiringMinPlusElement(5))
        b_c = Edge(b, c, SemiringMinPlusElement(3))
        c_finish = Edge(c, finish, SemiringMinPlusElement(9))

        g = Graph([start, finish, a, b, c],
                  [start_a, a_b, b_c, a_c, c_finish])

        g.prepare(SemiringMinPlusElement)
        self.assertItemsEqual(a.get_outputs(), [a_b, a_c])
        self.assertItemsEqual(b.get_inputs(), [a_b])
        self.assertItemsEqual(b.get_outputs(), [b_c])
        self.assertItemsEqual(c.get_inputs(), [b_c, a_c])
    def test_delete_vertex(self):
        """
        a - b - c
        -----
        A - A - A
              /
        B - B
          \
            C
        """
        v_aA = Vertex(domain='a')
        v_aB = Vertex(domain='a')
        v_bA = Vertex(domain='b')
        v_bB = Vertex(domain='b')
        v_bC = Vertex(domain='b')
        v_cA = Vertex(domain='c')

        e_aA_bA = Edge(v_aA, v_bA)
        e_aB_bB = Edge(v_aB, v_bB)
        e_aB_bC = Edge(v_aB, v_bC)
        e_bA_cA = Edge(v_bA, v_cA)
        e_bB_cA = Edge(v_bB, v_cA)

        g = Graph([v_aA, v_aB, v_bA, v_bB, v_bC, v_cA],
                  [e_aA_bA, e_aB_bB, e_bA_cA, e_bB_cA, e_aB_bC])
        g.prepare()

        self.assertItemsEqual(g.get_edges(), [e_aA_bA, e_aB_bB, e_aB_bC,
                                              e_bA_cA, e_bB_cA])
        self.assertItemsEqual(g.get_vertices(), [v_aA, v_aB, v_bA,
                                                 v_bB, v_bC, v_cA])
        self.assertFalse(g.is_neighborhood_corrupted())

        """
        a - b - c
        -----
        X   x   A
              /
        B - B
          \
            C
        """
        g.delete_vertex(v_aA)
        self.assertItemsEqual(g.get_edges(), [e_aB_bB, e_aB_bC, e_bB_cA])
        self.assertItemsEqual(g.get_vertices(), [v_aB, v_bB, v_bC, v_cA])
        self.assertFalse(g.is_neighborhood_corrupted())
        self.assertItemsEqual(g.get_domain('b'), [v_bB, v_bC])

        """
        a - b - c
        -----
                x

        B   X
          \
            C
        """
        g.delete_vertex(v_bB)
        self.assertItemsEqual(g.get_edges(), [e_aB_bC])
        self.assertItemsEqual(g.get_vertices(), [v_aB, v_bC])
        self.assertTrue(g.is_neighborhood_corrupted())
        self.assertItemsEqual(g.get_domain('a'), [v_aB])
        self.assertItemsEqual(g.get_domain('b'), [v_bC])

        """
        a - b - c
        -----
        x

            X
        """
        g.delete_vertex(v_bC)
        self.assertEqual(g.get_edges(), set())
        self.assertEqual(g.get_vertices(), set())
        self.assertTrue(g.is_neighborhood_corrupted())

        g.restore()
        self.assertItemsEqual(g.get_edges(), [e_aA_bA, e_aB_bB, e_aB_bC,
                                              e_bA_cA, e_bB_cA])
        self.assertItemsEqual(g.get_vertices(), [v_aA, v_aB, v_bA,
                                                 v_bB, v_bC, v_cA])
        self.assertFalse(g.is_neighborhood_corrupted())