class_docstr: Base class for implementations of deterministic finite
  automata.
  
  This is abstract to allow for the possibility of states
  being calculated lazily as we traverse the DFA (which
  we make heavy use of in our L* implementation - see
  lstar.py for details).
  
  States can be of any hashable type.
class_docstr_tok: ["Base","class","for","implementations","of","deterministic","finite","automata",".","This","is","abstract","to","allow","for","the","possibility","of","states","being","calculated","lazily","as","we","traverse","the","DFA","(","which","we","make","heavy","use","of","in","our","L","*","implementation","-","see","lstar.py","for","details",")",".","States","can","be","of","any","hashable","type","."]
docstr: Yields all matching strings whose length is ``k``, in ascending
  lexicographic order.
docstr_tok: ["Yields","all","matching","strings","whose","length","is","``","k","``",",","in","ascending","lexicographic","order","."]
code: def all_matching_strings_of_length(self, k):
      """Yields all matching strings whose length is ``k``, in ascending
      lexicographic order."""
      if k == 0:
          if self.is_accepting(self.start):
              yield b""
          return
  
      if not self.has_strings(self.start, k):
          return
  
      # This tracks a path through the DFA. We alternate between growing
      # it until it has length ``k`` and is in an accepting state, then
      # yielding that as a result, then modifying it so that the next
      # time we do that it will yield the lexicographically next matching
      # string.
      path = bytearray()
  
      # Tracks the states that are visited by following ``path`` from the
      # starting point.
      states = [self.start]
  
      while True:
          # First we build up our current best prefix to the lexicographically
          # first string starting with it.
          while len(path) < k:
              state = states[-1]
              for c, j in self.transitions(state):
                  if self.has_strings(j, k - len(path) - 1):
                      states.append(j)
                      path.append(c)
                      break
              else:
                  raise NotImplementedError("Should be unreachable")
          assert self.is_accepting(states[-1])
          assert len(states) == len(path) + 1
          yield bytes(path)
  
          # Now we want to replace this string with the prefix that will
          # cause us to extend to its lexicographic successor. This can
          # be thought of as just repeatedly moving to the next lexicographic
          # successor until we find a matching string, but we're able to
          # use our length counts to jump over long sequences where there
          # cannot be a match.
          while True:
              # As long as we are in this loop we are trying to move to
              # the successor of the current string.
  
              # If we've removed the entire prefix then we're done - no
              # successor is possible.
              if not path:
                  return
  
              if path[-1] == 255:
                  # If our last element is maximal then the we have to "carry
                  # the one" - our lexicographic successor must be incremented
                  # earlier than this.
                  path.pop()
                  states.pop()
              else:
                  # Otherwise increment by one.
                  path[-1] += 1
                  states[-1] = self.transition(states[-2], path[-1])
  
                  # If there are no strings of the right length starting from
                  # this prefix we need to keep going. Otherwise, this is
                  # the right place to be and we break out of our loop of
                  # trying to find the successor because it starts here.
                  if self.count_strings(states[-1], k - len(path)) > 0:
                      break
  
imports: import threading
  from collections import Counter, defaultdict, deque
  from math import inf
  from hypothesis.internal.reflection import proxies
label_desc: Use image node_id 17 for calling the DFA obj's underlying member method code with example usage: obj.all_matching_strings_of_length(k) without return types