예제 #1
0
    def test_save_load(self):
        with tempfile.NamedTemporaryFile(mode="r") as fid:
            gtn.savetxt(fid.name, self.g)
            loaded = gtn.loadtxt(fid.name)
            self.assertTrue(gtn.isomorphic(self.g, loaded))

        with tempfile.NamedTemporaryFile(mode="r") as fid:
            gtn.save(fid.name, self.g)
            loaded = gtn.load(fid.name)
            self.assertTrue(gtn.isomorphic(self.g, loaded))
    def test_transitions(self):
        num_tokens = 4

        # unigram
        transitions = make_transitions_graph(1, num_tokens)
        expected = gtn.Graph()
        expected.add_node(True, True)
        for i in range(num_tokens):
            expected.add_arc(0, 0, i)
        self.assertTrue(gtn.isomorphic(transitions, expected))

        # bigram
        transitions = make_transitions_graph(2, num_tokens)
        expected = gtn.Graph()
        expected.add_node(True, False)
        for i in range(num_tokens):
            expected.add_node(False, False)
            expected.add_arc(0, i + 1, i)
        for i in range(num_tokens):
            for j in range(num_tokens):
                expected.add_arc(i + 1, j + 1, j)
        expected.add_node(False, True)
        for i in range(num_tokens + 1):
            expected.add_arc(i, num_tokens + 1, gtn.epsilon)

        self.assertTrue(gtn.isomorphic(transitions, expected))

        # trigram
        transitions = make_transitions_graph(3, num_tokens)
        expected = gtn.Graph()
        expected.add_node(True, False)
        for i in range(num_tokens):
            expected.add_node(False, False)
            expected.add_arc(0, i + 1, i)
        for i in range(num_tokens):
            for j in range(num_tokens):
                expected.add_node(False, False)
                expected.add_arc(i + 1, num_tokens * i + j + num_tokens + 1, j)
        for i in range(num_tokens):
            for j in range(num_tokens):
                for k in range(num_tokens):
                    expected.add_arc(
                        num_tokens * i + j + num_tokens + 1,
                        num_tokens * j + k + num_tokens + 1,
                        k,
                    )
        end_idx = expected.add_node(False, True)
        self.assertEqual(end_idx, num_tokens * num_tokens + num_tokens + 1)
        for i in range(end_idx):
            expected.add_arc(i, end_idx, gtn.epsilon)

        self.assertTrue(gtn.isomorphic(transitions, expected))
예제 #3
0
    def test_sum(self):

        # Empty graph
        self.assertTrue(gtn.equal(gtn.union([]), gtn.Graph()))

        # Check single graph is a no-op
        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node(False, True)
        g1.add_arc(0, 1, 1)
        self.assertTrue(gtn.equal(gtn.union([g1]), g1))

        # Simple union
        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node(False, True)
        g1.add_arc(0, 1, 1)

        g2 = gtn.Graph()
        g2.add_node(True)
        g2.add_node(False, True)
        g2.add_arc(0, 1, 0)

        expected = gtn.Graph()
        expected.add_node(True)
        expected.add_node(True)
        expected.add_node(False, True)
        expected.add_node(False, True)
        expected.add_arc(0, 2, 1)
        expected.add_arc(1, 3, 0)
        self.assertTrue(gtn.isomorphic(gtn.union([g1, g2]), expected))

        # Check adding with an empty graph works
        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node(False, True)
        g1.add_arc(0, 1, 1)

        g2 = gtn.Graph()

        g3 = gtn.Graph()
        g3.add_node(True, True)
        g3.add_arc(0, 0, 2)

        expected = gtn.Graph()
        expected.add_node(True)
        expected.add_node(False, True)
        expected.add_node(True, True)
        expected.add_arc(0, 1, 1)
        expected.add_arc(2, 2, 2)
        self.assertTrue(gtn.isomorphic(gtn.union([g1, g2, g3]), expected))
예제 #4
0
    def test_loadsave(self):
        _, tmpfile = tempfile.mkstemp()

        g = gtn.Graph()
        gtn.save(tmpfile, g)
        g2 = gtn.load(tmpfile)
        self.assertTrue(gtn.equal(g, g2))

        g = gtn.Graph()
        g.add_node(True)
        g.add_node(True)
        g.add_node()
        g.add_node()
        g.add_node(False, True)
        g.add_node(False, True)

        g.add_arc(0, 1, 0, 1, 1.1)
        g.add_arc(1, 2, 1, 2, 2.1)
        g.add_arc(2, 3, 2, 3, 3.1)
        g.add_arc(3, 4, 3, 4, 4.1)
        g.add_arc(4, 5, 4, gtn.epsilon, 5.1)
        gtn.save(tmpfile, g)
        g2 = gtn.load(tmpfile)
        self.assertTrue(gtn.equal(g, g2))
        self.assertTrue(gtn.isomorphic(g, g2))
예제 #5
0
    def test_comparisons(self):
        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node(False, True)
        g1.add_arc(0, 1, 0)

        g2 = gtn.Graph()
        g2.add_node(True)
        g2.add_node(False, True)
        g2.add_arc(0, 1, 0)

        self.assertTrue(gtn.equal(g1, g2))
        self.assertTrue(gtn.isomorphic(g1, g2))

        g2 = gtn.Graph()
        g2.add_node(False, True)
        g2.add_node(True)
        g2.add_arc(1, 0, 0)

        self.assertFalse(gtn.equal(g1, g2))
        self.assertTrue(gtn.isomorphic(g1, g2))
예제 #6
0
    def test_loadtxt(self):

        g1 = gtn.Graph()
        g1.add_node(True, True)
        g1.add_node(False, True)
        g1.add_node()
        g1.add_arc(0, 0, 1)
        g1.add_arc(0, 2, 1, 1, 1.1)
        g1.add_arc(2, 1, 2, 2, 2.1)

        g_str = ["0", "0 1", "0 0 1 1 0", "0 2 1 1 1.1", "2 1 2 2 2.1"]
        g2 = create_graph_from_text(g_str)
        self.assertTrue(gtn.equal(g1, g2))
        self.assertTrue(gtn.isomorphic(g1, g2))

        _, tmpfile = tempfile.mkstemp()

        # Write the test file
        gtn.savetxt(tmpfile, g2)
        g3 = gtn.loadtxt(tmpfile)
        self.assertTrue(gtn.equal(g1, g3))

        # Empty graph doesn't load

        g_str = [""]
        self.assertRaises(ValueError, create_graph_from_text, g_str)

        # Graph without accept nodes doesn't load

        g_str = ["1"]
        self.assertRaises(ValueError, create_graph_from_text, g_str)

        # Graph with repeat start nodes doesn't load

        g_str = ["1 0 0", "0 1"]
        self.assertRaises(ValueError, create_graph_from_text, g_str)

        # Graph loads if the start and accept nodes are specified

        g_str = ["0", "1"]
        g = gtn.Graph()
        g.add_node(True)
        g.add_node(False, True)
        self.assertTrue(gtn.equal(g, create_graph_from_text(g_str)))

        # Graph doesn't load if arc incorrect

        g_str = ["0", "1", "0 2"]
        self.assertRaises(ValueError, create_graph_from_text, g_str)
        g_str = ["0", "1", "0 1 2 3 4 5"]
        self.assertRaises(ValueError, create_graph_from_text, g_str)

        # Transducer loads

        g1 = gtn.Graph()
        g1.add_node(True, True)
        g1.add_node(False, True)
        g1.add_node()
        g1.add_arc(0, 0, 1, 1)
        g1.add_arc(0, 2, 1, 2, 1.1)
        g1.add_arc(2, 1, 2, 3, 2.1)

        g_str = ["0", "0 1", "0 0 1", "0 2 1 2 1.1", "2 1 2 3 2.1"]
        g2 = create_graph_from_text(g_str)
        self.assertTrue(gtn.equal(g1, g2))
        self.assertTrue(gtn.isomorphic(g1, g2))
예제 #7
0
    def test_isomorphic(self):

        g1 = gtn.Graph()
        g1.add_node(True)

        g2 = gtn.Graph()
        g2.add_node(True)

        self.assertTrue(gtn.isomorphic(g1, g2))

        g1 = gtn.Graph()
        g1.add_node(True)

        g2 = gtn.Graph()
        g2.add_node(True, True)

        self.assertFalse(gtn.isomorphic(g1, g2))

        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node(False, True)
        g1.add_arc(0, 1, 0, 0, 1)

        g2 = gtn.Graph()
        g2.add_node(True)
        g2.add_node(False, True)
        g2.add_arc(0, 1, 0, 0, 1)

        self.assertTrue(gtn.isomorphic(g1, g2))

        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node(False, True)
        g1.add_arc(0, 1, 0, 0, 1)

        g2 = gtn.Graph()
        g2.add_node(True)
        g2.add_node(False, True)
        g2.add_arc(0, 1, 0, 0, 1)
        g2.add_arc(0, 1, 0, 0, 1)

        self.assertFalse(gtn.isomorphic(g1, g2))

        # Graph with loops
        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node()
        g1.add_node(False, True)
        g1.add_arc(0, 2, 0)
        g1.add_arc(0, 1, 0)
        g1.add_arc(1, 1, 3)
        g1.add_arc(2, 1, 3)

        g2 = gtn.Graph()
        g2.add_node(True)
        g2.add_node(False, True)
        g2.add_node()
        g2.add_arc(0, 1, 0)
        g2.add_arc(1, 2, 3)
        g2.add_arc(0, 2, 0)
        g2.add_arc(2, 2, 3)

        self.assertTrue(gtn.isomorphic(g1, g2))

        # Repeat arcs
        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node(False, True)
        g1.add_arc(0, 1, 1, 1, 3.1)
        g1.add_arc(0, 1, 1, 1, 3.1)
        g1.add_arc(0, 1, 1, 1, 4.1)

        g2 = gtn.Graph()
        g2.add_node(True)
        g2.add_node(False, True)
        g2.add_arc(0, 1, 1, 1, 3.1)
        g2.add_arc(0, 1, 1, 1, 4.1)
        g2.add_arc(0, 1, 1, 1, 4.1)
        self.assertFalse(gtn.isomorphic(g1, g2))

        # Transducer with different outputs
        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node(False, True)
        g1.add_arc(0, 1, 0, 1, 2.1)
        g1.add_arc(1, 1, 1, 3, 4.1)

        g2 = gtn.Graph()
        g2.add_node(True)
        g2.add_node(False, True)
        g2.add_arc(0, 1, 0, 1, 2.1)
        g2.add_arc(1, 1, 1, 4, 4.1)
        self.assertFalse(gtn.isomorphic(g1, g2))
예제 #8
0
    def test_graph_build(self):
        # unigram test case
        graph = build_graph([[(0, ), (1, )]])
        expected = gtn.Graph()
        expected.add_node(True, True)
        expected.add_arc(0, 0, 0)
        expected.add_arc(0, 0, 1)
        self.assertTrue(gtn.isomorphic(graph, expected))

        # bigram test cases
        # fmt: off
        ngrams = [
            [(0, )],  # unigrams
            [(-1, 0), (-1, 1), (0, 1), (1, 0), (1, 1)]  # bigrams
        ]
        # fmt: on
        with self.assertRaises(ValueError):
            build_graph(ngrams)

        # fmt: off
        # text = ["ab, "ba", "bb"]
        ngrams = [
            [(0, ), (1, ), (-2, )],  # unigrams
            [(-1, 0), (-1, 1), (0, 1), (1, 0), (1, 1), (0, -2),
             (1, -2)]  # bigrams
        ]
        # fmt: on
        graph = build_graph(ngrams)
        expected = gtn.Graph()
        expected.add_node(True, False)  # <s>
        expected.add_node(False, False)  # 0
        expected.add_node(False, False)  # 1
        expected.add_node(False, False)  # back-off
        expected.add_node(False, True)  # </s>
        expected.add_arc(0, 1, 0)
        expected.add_arc(1, 2, 1)
        expected.add_arc(0, 2, 1)
        expected.add_arc(2, 1, 0)
        expected.add_arc(2, 2, 1)
        expected.add_arc(0, 3, gtn.epsilon)
        expected.add_arc(1, 3, gtn.epsilon)
        expected.add_arc(2, 3, gtn.epsilon)
        expected.add_arc(3, 1, 0)
        expected.add_arc(3, 2, 1)
        expected.add_arc(3, 4, gtn.epsilon)
        expected.add_arc(1, 4, gtn.epsilon)
        expected.add_arc(2, 4, gtn.epsilon)
        self.assertTrue(gtn.isomorphic(expected, graph))

        # bigram test case with empty string
        ngrams = [
            [(0, ), (-2, )],
            [(-1, 0), (0, 0), (0, -2), (-1, -2)],
        ]  # unigrams  # bigrams
        graph = build_graph(ngrams)
        expected = gtn.Graph()
        expected.add_node(True, False)  # (<s>)
        expected.add_node(False, False)  # (a)
        expected.add_node(False, False)  # (back-off)
        expected.add_node(False, True)  # (</s>)
        expected.add_arc(2, 1, 0)  # p(a)
        expected.add_arc(2, 3, gtn.epsilon)  # p(</s>)
        expected.add_arc(1, 1, 0)  # p(a/a)
        expected.add_arc(0, 1, 0)  # p(a/<s>)
        expected.add_arc(1, 3, gtn.epsilon)  # p(</s>/a)
        expected.add_arc(0, 3, gtn.epsilon)  # p(</s>/<s>)
        expected.add_arc(0, 2, gtn.epsilon)
        expected.add_arc(1, 2, gtn.epsilon)
        self.assertTrue(gtn.isomorphic(expected, graph))

        # trigram test case
        # fmt: off
        ngrams = [
            [(0, ), (1, ), (-2, )],  # unigrams
            [(-1, 0), (0, 1), (1, 1), (1, -2)],  # bigrams
            [(-1, 0, 1), (0, 1, 1), (1, 1, 1), (1, 1, -2)],  # trigrams
        ]
        # fmt: on
        graph = build_graph(ngrams)
        expected = gtn.Graph()
        expected.add_node(True, False)  # (<s>)
        expected.add_node(False, False)  # unigram back-off
        expected.add_node(False, False)  # 0
        expected.add_node(False, False)  # 1
        expected.add_node(False, False)  # (<s>, 0)
        expected.add_node(False, False)  # (0, 1)
        expected.add_node(False, False)  # (1, 1)
        expected.add_node(False, True)  # </s>

        # unigram arcs
        expected.add_arc(1, 2, 0)
        expected.add_arc(1, 3, 1)
        expected.add_arc(1, 7, gtn.epsilon)

        # bigram arcs
        expected.add_arc(0, 4, 0)
        expected.add_arc(2, 5, 1)
        expected.add_arc(3, 6, 1)
        expected.add_arc(3, 7, gtn.epsilon)

        # trigram arcs
        expected.add_arc(4, 5, 1)
        expected.add_arc(5, 6, 1)
        expected.add_arc(6, 6, 1)
        expected.add_arc(6, 7, gtn.epsilon)

        # back-off to bigram
        expected.add_arc(4, 2, gtn.epsilon)
        expected.add_arc(5, 3, gtn.epsilon)
        expected.add_arc(6, 3, gtn.epsilon)

        # back-off to unigram
        expected.add_arc(0, 1, gtn.epsilon)
        expected.add_arc(2, 1, gtn.epsilon)
        expected.add_arc(3, 1, gtn.epsilon)
        self.assertTrue(gtn.isomorphic(expected, graph))
예제 #9
0
    def test_composition(self):
        # Compos,ing with an empty graph gives an empty graph
        g1 = gtn.Graph()
        g2 = gtn.Graph()
        self.assertTrue(gtn.equal(gtn.compose(g1, g2), gtn.Graph()))

        g1.add_node(True)
        g1.add_node()
        g1.add_arc(0, 1, 0)

        g2.add_node(True)
        g2.add_node(False, True)
        g2.add_arc(0, 1, 0)
        g2.add_arc(0, 1, 0)

        self.assertTrue(gtn.equal(gtn.compose(g1, g2), gtn.Graph()))
        self.assertTrue(gtn.equal(gtn.compose(g2, g1), gtn.Graph()))
        self.assertTrue(gtn.equal(gtn.intersect(g2, g1), gtn.Graph()))

        # Check singly sorted version
        g1.arc_sort(True)
        self.assertTrue(gtn.equal(gtn.compose(g1, g2), gtn.Graph()))

        # Check doubly sorted version
        g2.arc_sort()
        self.assertTrue(gtn.equal(gtn.compose(g1, g2), gtn.Graph()))

        # Self-loop in the composed graph
        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node(False, True)
        g1.add_arc(0, 0, 0)
        g1.add_arc(0, 1, 1)
        g1.add_arc(1, 1, 2)

        g2 = gtn.Graph()
        g2.add_node(True)
        g2.add_node()
        g2.add_node(False, True)
        g2.add_arc(0, 1, 0)
        g2.add_arc(1, 1, 0)
        g2.add_arc(1, 2, 1)

        g_str = ["0", "2", "0 1 0", "1 1 0", "1 2 1"]
        expected = create_graph_from_text(g_str)
        self.assertTrue(gtn.isomorphic(gtn.compose(g1, g2), expected))
        self.assertTrue(gtn.isomorphic(gtn.intersect(g1, g2), expected))

        # Check singly sorted version
        g1.arc_sort(True)
        self.assertTrue(gtn.isomorphic(gtn.compose(g1, g2), expected))

        # Check doubly sorted version
        g2.arc_sort()
        self.assertTrue(gtn.isomorphic(gtn.compose(g1, g2), expected))

        # Loop in the composed graph
        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node(False, True)
        g1.add_arc(0, 1, 0)
        g1.add_arc(1, 1, 1)
        g1.add_arc(1, 0, 0)

        g2 = gtn.Graph()
        g2.add_node(True)
        g2.add_node(False, True)
        g2.add_arc(0, 0, 0)
        g2.add_arc(0, 1, 1)
        g2.add_arc(1, 0, 1)

        g_str = ["0", "2", "0 1 0", "1 0 0", "1 2 1", "2 1 1"]
        expected = create_graph_from_text(g_str)
        self.assertTrue(gtn.isomorphic(gtn.compose(g1, g2), expected))
        self.assertTrue(gtn.isomorphic(gtn.intersect(g1, g2), expected))

        # Check singly sorted version
        g1.arc_sort(True)
        self.assertTrue(gtn.isomorphic(gtn.compose(g1, g2), expected))

        # Check doubly sorted version
        g2.arc_sort()
        self.assertTrue(gtn.isomorphic(gtn.compose(g1, g2), expected))

        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node()
        g1.add_node()
        g1.add_node()
        g1.add_node(False, True)
        for i in range(g1.num_nodes() - 1):
            for j in range(3):
                g1.add_arc(i, i + 1, j, j, j)

        g2 = gtn.Graph()
        g2.add_node(True)
        g2.add_node()
        g2.add_node(False, True)
        g2.add_arc(0, 1, 0, 0, 3.5)
        g2.add_arc(1, 1, 0, 0, 2.5)
        g2.add_arc(1, 2, 1, 1, 1.5)
        g2.add_arc(2, 2, 1, 1, 4.5)
        g_str = [
            "0",
            "6",
            "0 1 0 0 3.5",
            "1 2 0 0 2.5",
            "1 4 1 1 2.5",
            "2 3 0 0 2.5",
            "2 5 1 1 2.5",
            "4 5 1 1 5.5",
            "3 6 1 1 2.5",
            "5 6 1 1 5.5",
        ]
        expected = create_graph_from_text(g_str)
        self.assertTrue(gtn.isomorphic(gtn.compose(g1, g2), expected))
        self.assertTrue(gtn.isomorphic(gtn.intersect(g1, g2), expected))

        # Check singly sorted version
        g1.arc_sort(True)
        self.assertTrue(gtn.isomorphic(gtn.compose(g1, g2), expected))

        # Check doubly sorted version
        g2.arc_sort()
        self.assertTrue(gtn.isomorphic(gtn.compose(g1, g2), expected))