class TransitionTests(TestCase):
    def setUp(self):
        self.p = [0.5, 0.2, 0.1]
        self.state = State(25, self.p)
        self.p_transit = 0.25
        self.transition = Transition(self.state, self.state, self.p_transit)

    def test_cost(self):
        transition = Transition(self.state, self.state, 1)
        self.assertEqual(0, transition.cost())

        self.assertEqual(- np.log(self.p_transit), self.transition.cost())

        transition = Transition.free(self.state, self.state)
        self.assertEqual(0, transition.cost())

    def test_full_cost(self):
        self.assertEqual(- np.log(0.5) - np.log(self.p_transit),
                         self.transition.full_cost())

    def test_pass_token(self):
        expected_score = self.transition.full_cost()
        self.state.initialize_token()
        self.transition.pass_token()
        self.state.commit()

        self.assertEqual(Token(expected_score, [self.state.state]),
                         self.state.token)
    def test_cost(self):
        transition = Transition(self.state, self.state, 1)
        self.assertEqual(0, transition.cost())

        self.assertEqual(- np.log(self.p_transit), self.transition.cost())

        transition = Transition.free(self.state, self.state)
        self.assertEqual(0, transition.cost())
    def test_best_path_initially(self):
        graph = Graph(self.states)
        self.states[0].add_transition(
            Transition.free(self.states[0], self.states[1])
        )
        self.states[1].add_transition(
            Transition.free(self.states[1], self.states[1])
        )

        self.assertEqual([], graph.optimal_path().history)
    def test_add_transition(self):
        state = State(self.state_value, self.p)

        dest = State(2, self.p)
        transition = Transition(state, dest, 0.2)
        state.add_transition(transition)
        self.assertEqual(1, len(state.transitions))

        destination_state = state.transitions[0].destination
        self.assertEqual(2, destination_state.state)
        self.assertEqual(self.p, destination_state.p)
    def test_word_transition(self):
        graph_a = Graph([self.states[0]])
        graph_b = Graph([self.states[1]])

        a_to_b = Transition(graph_a, graph_b, 0.99)

        graph_a.add_transition(a_to_b)

        top_level = Graph([graph_a, graph_b])
        top_level.evolve()
        top_level.commit()

        self.assertEqual(graph_a.token, top_level.optimal_path())

        transit_cost = a_to_b.full_cost()

        top_level.evolve()
        top_level.commit()
        token = top_level.optimal_path()

        self.assertEqual(- np.log(0.5) + transit_cost, token.score)
        self.assertEqual([self.state1, self.state2], token.history)
    def test_multiple_states_model(self):
        graph_id = 7
        graph = Graph(self.states, graph_id=graph_id)
        graph.add_transition(
            Transition.free(self.states[0], self.states[1])
        )
        graph.add_transition(
            Transition.free(self.states[1], self.states[1])
        )

        graph.evolve()
        graph.commit()

        self.assertEqual(Token(- np.log(self.p1[0]), [self.state1], [graph_id]),
                         graph.optimal_path())

        graph.evolve()
        graph.commit()

        expected = Token(- np.log(self.p1[0]) - np.log(self.p2[1]),
                         [self.state1, self.state2], [graph_id])
        self.assertEqual(expected, graph.optimal_path())
    def test_transitions_with_self_loops(self):
        first_state = State(20, [0.2, 0.4])
        graph = Graph([first_state])

        graph.add_transition(Transition.free(first_state, first_state))

        graph.evolve()
        graph.commit()

        graph.evolve()
        graph.commit()
        score = graph._nodes[0].token.score

        self.assertEqual(- np.log(0.2) - np.log(0.4), score)
    def test_one_state_model(self):
        states = [self.states[0]]
        graph = Graph(states)
        graph.add_transition(
            Transition.free(self.states[0], self.states[0])
        )

        graph.evolve()
        graph.commit()

        t1_prob = self.p1[0]
        t2_prob = self.p1[1]

        self.assertEqual(Token(- np.log(t1_prob), [self.state1]),
                         graph.optimal_path())

        graph.evolve()
        graph.commit()

        expected = Token(- np.log(t1_prob) - np.log(t2_prob),
                         [self.state1, self.state1])
        self.assertEqual(expected, graph.optimal_path())
 def setUp(self):
     self.p = [0.5, 0.2, 0.1]
     self.state = State(25, self.p)
     self.p_transit = 0.25
     self.transition = Transition(self.state, self.state, self.p_transit)