docs: def learn_sfa(self, mma=None):
          """
          Implements the high level loop of the algorithm for learning a
          Mealy machine.
          Args:
              mma:
          Returns:
              MealyMachine: A model for the Mealy machine to be learned.
          """
          logging.info('Initializing learning procedure.')
          if mma:
              self._init_table_from_dfa(mma)
          else:
              self._init_table()
  
          logging.info('Generating a closed and consistent observation table.')
          while True:
  
              closed = False
              # Make sure that the table is closed
              while not closed:
                  logging.debug('Checking if table is closed.')
                  closed, s = self.observation_table.is_closed()
                  if not closed:
                      logging.debug('Closing table.')
                      self._ot_make_closed(s)
                  else:
                      logging.debug('Table closed.')
  
              # Create conjecture
              sfa = self.get_sfa_conjecture()
  
              logging.info('Generated conjecture machine with %d states.',
                           len(list(sfa.states)))
  
              # _check correctness
              logging.debug('Running equivalence query.')
              found, counter_example = self._equivalence_query(sfa)
  
              # 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 %s with length %d.',
                  counter_example,
                  len(counter_example))
              self._process_counter_example(sfa, counter_example)
  
          logging.info('Learning complete.')
          return '', sfa