Process a counterexample in the Rivest-Schapire way.
        Args:
            mma (DFA): The hypothesis automaton
            w_string (str): The examined string to be consumed
        Return:
            None

def _process_counter_example(self, mma, w_string):
        """"
        Process a counterexample in the Rivest-Schapire way.
        Args:
            mma (DFA): The hypothesis automaton
            w_string (str): The examined string to be consumed
        Return:
            None
        """
        if len(w_string) == 1:
            self.observation_table.smi_vector.append(w_string)
            for exp in self.observation_table.em_vector:
                self._fill_table_entry(w_string, exp)

        diff = len(w_string)
        same = 0
        membership_answer = self._membership_query(w_string)
        while True:
            i = (same + diff) / 2
            access_string = self._run_in_hypothesis(mma, w_string, i)
            if membership_answer != self._membership_query(access_string + w_string[i:]):
                diff = i
            else:
                same = i
            if diff - same == 1:
                break

        # First check if the transition is part of our training data.
        access_string = self._run_in_hypothesis(mma, w_string, diff - 1)
        wrong_transition = access_string + w_string[diff - 1]
        if wrong_transition not in self.observation_table.smi_vector:
            # If transition is not part of our training data add s_ib to Smi and
            # return to checking table closedness.
            self.observation_table.smi_vector.append(wrong_transition)
            for exp in self.observation_table.em_vector:
                self._fill_table_entry(wrong_transition, exp)
            return

        # This point presents a tradeoff between equivalence and membership
        # queries. If the transition in the counterexample'input_string breakpoint is not
        # part of our current training data (i.e. s_ib is not part of our Smi
        # set), then we assume a wrong transition and return to checking table
        # closure by adding s_ib to our training data. This saves a number of
        # membership queries since we don't add a row in our table unless
        # absolutely necessary. Notice that even if Equivalence queries are
        # expensive in general caching the result will be able to discover that
        # this iteration required a new state in the next equivalence query.

        exp = w_string[diff:]
        self.observation_table.em_vector.append(exp)
        for row in self.observation_table.sm_vector + self.observation_table.smi_vector:
            self._fill_table_entry(row, exp)