docs: def dfa_reachable(dfa: dict) -> dict:
      """ Side effects on input! Removes unreachable states from a
      DFA and returns the pruned DFA.
  
      It is possible to remove from a DFA A all unreachable states
      from the initial state without altering the language.
      The reachable DFA :math:`A_R` corresponding to A is defined as:
  
      :math:`A_R = (Σ, S_R , s_0 , ρ|S_R , F ∩ S_R )`
  
      where
  
      • :math:`S_R` set of reachable state from the initial one
      • :math:`ρ|S_R` is the restriction on :math:`S_R × Σ` of ρ.
  
      :param dict dfa: input DFA.
      :return: *(dict)* representing the pruned DFA.
      """
      reachable_states = set()  # set of reachable states from root
      boundary = set()
      reachable_states.add(dfa['initial_state'])
      boundary.add(dfa['initial_state'])
  
      while boundary:
          s = boundary.pop()
          for a in dfa['alphabet']:
              if (s, a) in dfa['transitions']:
                  if dfa['transitions'][s, a] not in reachable_states:
                      reachable_states.add(dfa['transitions'][s, a])
                      boundary.add(dfa['transitions'][s, a])
      dfa['states'] = reachable_states
      dfa['accepting_states'] = \
          dfa['accepting_states'].intersection(dfa['states'])
  
      transitions = dfa[
          'transitions'].copy()  # TODO why copy? because for doesn't cycle
      # mutable set....
      for t in transitions:
          if t[0] not in dfa['states']:
              dfa['transitions'].pop(t)
          elif dfa['transitions'][t] not in dfa['states']:
              dfa['transitions'].pop(t)
  
      return dfa