Implements the high level loop of the algorithm for learning a
        Mealy machine.
        Args:
            None
        Returns:
            MealyMachine: The learned mealy machine

def learn_mealy_machine(self):
        """
        Implements the high level loop of the algorithm for learning a
        Mealy machine.
        Args:
            None
        Returns:
            MealyMachine: The learned mealy machine
        """
        logging.info('Initializing learning procedure.')
        self._init_table()

        logging.info('Generating a closed and consistent observation table.')
        while True:

            closed = False
            # Make sure that the table is closed and consistent
            while not closed:

                logging.debug('Checking if table is closed.')
                closed, string = self.observation_table.is_closed()
                if not closed:
                    logging.debug('Closing table.')
                    self._ot_make_closed(string)
                else:
                    logging.debug('Table closed.')

            # Create conjecture
            mma = self.get_mealy_conjecture()

            logging.info('Generated conjecture machine with %d states.',
                         len(list(mma.states)))

            # _check correctness
            logging.debug('Running equivalence query.')
            found, counter_example = self._equivalence_query(mma)

            # Are we done?
            if found:
                logging.info('No counterexample found. Hypothesis is correct!')
                break

            # Add the new experiments into the table to reiterate the
            # learning loop
            logging.info(
                'Processing counterexample %input_string with length %d.',
                counter_example,
                len(counter_example))
            self._process_counter_example(mma, counter_example)

        logging.info('Learning complete.')
        return mma