class_docstr: Has methods to ``enumerate`` and ``count`` the partitions of a multiset.
  
  This implements a refactored and extended version of Knuth's algorithm
  7.1.2.5M [AOCP]_."
  
  The enumeration methods of this class are generators and return
  data structures which can be interpreted by the same visitor
  functions used for the output of ``multiset_partitions_taocp``.
  
  Examples
  ========
  
  >>> from sympy.utilities.enumerative import MultisetPartitionTraverser
  >>> m = MultisetPartitionTraverser()
  >>> m.count_partitions([4,4,4,2])
  127750
  >>> m.count_partitions([3,3,3])
  686
  
  See Also
  ========
  
  multiset_partitions_taocp
  sympy.utilities.iterables.multiset_partitions
  
  References
  ==========
  
  .. [AOCP] Algorithm 7.1.2.5M in Volume 4A, Combinatoral Algorithms,
         Part 1, of The Art of Computer Programming, by Donald Knuth.
  
  .. [Factorisatio] On a Problem of Oppenheim concerning
         "Factorisatio Numerorum" E. R. Canfield, Paul Erdos, Carl
         Pomerance, JOURNAL OF NUMBER THEORY, Vol. 17, No. 1. August
         1983.  See section 7 for a description of an algorithm
         similar to Knuth's.
  
  .. [Yorgey] Generating Multiset Partitions, Brent Yorgey, The
         Monad.Reader, Issue 8, September 2007.
docstr: Enumerate multiset partitions with no more than ``ub`` parts.
  
  Equivalent to enum_range(multiplicities, 0, ub)
  
  Parameters
  ==========
  
  multiplicities
       list of multiplicities of the components of the multiset.
  
  ub
      Maximum number of parts
  
  Examples
  ========
  
  >>> from sympy.utilities.enumerative import list_visitor
  >>> from sympy.utilities.enumerative import MultisetPartitionTraverser
  >>> m = MultisetPartitionTraverser()
  >>> states = m.enum_small([2,2], 2)
  >>> list(list_visitor(state, 'ab') for state in states)
  [[['a', 'a', 'b', 'b']],
  [['a', 'a', 'b'], ['b']],
  [['a', 'a'], ['b', 'b']],
  [['a', 'b', 'b'], ['a']],
  [['a', 'b'], ['a', 'b']]]
  
  The implementation is based, in part, on the answer given to
  exercise 69, in Knuth [AOCP]_.
  
  See Also
  ========
  
  enum_all, enum_large, enum_range
docstr_tok: ["Enumerate","multiset","partitions","with","no","more","than","``","ub","``","parts",".","Equivalent","to","enum_range","(","multiplicities",",","0",",","ub",")","Parameters","==========","multiplicities","list","of","multiplicities","of","the","components","of","the","multiset",".","ub","Maximum","number","of","parts","Examples","========",">",">",">","from","sympy.utilities.enumerative","import","list_visitor",">",">",">","from","sympy.utilities.enumerative","import","MultisetPartitionTraverser",">",">",">","m","=","MultisetPartitionTraverser","(",")",">",">",">","states","=","m.enum_small","(","[","2,2","]",",","2",")",">",">",">","list","(","list_visitor","(","state",",","'ab","'",")","for","state","in","states",")","[","[","[","'","a","'",",","'","a","'",",","'","b","'",",","'","b","'","]","]",",","[","[","'","a","'",",","'","a","'",",","'","b","'","]",",","[","'","b","'","]","]",",","[","[","'","a","'",",","'","a","'","]",",","[","'","b","'",",","'","b","'","]","]",",","[","[","'","a","'",",","'","b","'",",","'","b","'","]",",","[","'","a","'","]","]",",","[","[","'","a","'",",","'","b","'","]",",","[","'","a","'",",","'","b","'","]","]","]","The","implementation","is","based",",","in","part",",","on","the","answer","given","to","exercise","69",",","in","Knuth","[","AOCP","]","_",".","See","Also","========","enum_all",",","enum_large",",","enum_range"]
code: def enum_small(self, multiplicities, ub):
      """Enumerate multiset partitions with no more than ``ub`` parts.
  
      Equivalent to enum_range(multiplicities, 0, ub)
  
      Parameters
      ==========
  
      multiplicities
           list of multiplicities of the components of the multiset.
  
      ub
          Maximum number of parts
  
      Examples
      ========
  
      >>> from sympy.utilities.enumerative import list_visitor
      >>> from sympy.utilities.enumerative import MultisetPartitionTraverser
      >>> m = MultisetPartitionTraverser()
      >>> states = m.enum_small([2,2], 2)
      >>> list(list_visitor(state, 'ab') for state in states)
      [[['a', 'a', 'b', 'b']],
      [['a', 'a', 'b'], ['b']],
      [['a', 'a'], ['b', 'b']],
      [['a', 'b', 'b'], ['a']],
      [['a', 'b'], ['a', 'b']]]
  
      The implementation is based, in part, on the answer given to
      exercise 69, in Knuth [AOCP]_.
  
      See Also
      ========
  
      enum_all, enum_large, enum_range
  
      """
  
      # Keep track of iterations which do not yield a partition.
      # Clearly, we would like to keep this number small.
      self.discarded = 0
      if ub <= 0:
          return
      self._initialize_enumeration(multiplicities)
      while True:
          while self.spread_part_multiplicity():
              self.db_trace("spread 1")
              if self.lpart >= ub:
                  self.discarded += 1
                  self.db_trace("  Discarding")
                  self.lpart = ub - 2
                  break
          else:
              # M4  Visit a partition
              state = [self.f, self.lpart, self.pstack]
              yield state
  
          # M5 (Decrease v)
          while not self.decrement_part_small(self.top_part(), ub):
              self.db_trace("Failed decrement, going to backtrack")
              # M6 (Backtrack)
              if self.lpart == 0:
                  return
              self.lpart -= 1
              self.db_trace("Backtracked to")
          self.db_trace("decrement ok, about to expand")
  
label_desc: Use image node_id 11 for calling the MultisetPartitionTraverser obj's underlying member method code with example usage: obj.enum_small(multiplicities, ub) without return types