docs: def shrink_dsp(self, inputs=None, outputs=None, cutoff=None,
                     inputs_dist=None, wildcard=True):
          """
          Returns a reduced dispatcher.
  
          :param inputs:
              Input data nodes.
          :type inputs: list[str], iterable, optional
  
          :param outputs:
              Ending data nodes.
          :type outputs: list[str], iterable, optional
  
          :param cutoff:
              Depth to stop the search.
          :type cutoff: float, int, optional
  
          :param inputs_dist:
              Initial distances of input data nodes.
          :type inputs_dist: dict[str, int | float], optional
  
          :param wildcard:
              If True, when the data node is used as input and target in the
              ArciDispatch algorithm, the input value will be used as input for
              the connected functions, but not as output.
          :type wildcard: bool, optional
  
          :return:
              A sub-dispatcher.
          :rtype: Dispatcher
  
          .. seealso:: :func:`dispatch`
  
          **--------------------------------------------------------------------**
  
          **Example**:
  
          A dispatcher like this:
  
          .. dispatcher:: dsp
             :opt: graph_attr={'ratio': '1'}
  
              >>> dsp = Dispatcher(name='Dispatcher')
              >>> functions = [
              ...     {
              ...         'function_id': 'fun1',
              ...         'inputs': ['a', 'b'],
              ...         'outputs': ['c']
              ...     },
              ...     {
              ...         'function_id': 'fun2',
              ...         'inputs': ['b', 'd'],
              ...         'outputs': ['e']
              ...     },
              ...     {
              ...         'function_id': 'fun3',
              ...         'function': min,
              ...         'inputs': ['d', 'f'],
              ...         'outputs': ['g']
              ...     },
              ...     {
              ...         'function_id': 'fun4',
              ...         'function': max,
              ...         'inputs': ['a', 'b'],
              ...         'outputs': ['g']
              ...     },
              ...     {
              ...         'function_id': 'fun5',
              ...         'function': max,
              ...         'inputs': ['d', 'e'],
              ...         'outputs': ['c', 'f']
              ...     },
              ... ]
              >>> dsp.add_from_lists(fun_list=functions)
              ([], [...])
  
          Get the sub-dispatcher induced by dispatching with no calls from inputs
          `a`, `b`, and `c` to outputs `c`, `e`, and `f`::
  
              >>> shrink_dsp = dsp.shrink_dsp(inputs=['a', 'b', 'd'],
              ...                             outputs=['c', 'f'])
  
          .. dispatcher:: shrink_dsp
             :opt: graph_attr={'ratio': '1'}
  
              >>> shrink_dsp.name = 'Sub-Dispatcher'
          """
  
          bfs = None
          if inputs:
              # Get all data nodes no wait inputs.
              wait_in = self._get_wait_in(flag=False)
  
              # Evaluate the workflow graph without invoking functions.
              o = self.dispatch(
                  inputs, outputs, cutoff, inputs_dist, wildcard, True, False,
                  True, _wait_in=wait_in
              )
  
              data_nodes = self.data_nodes  # Get data nodes.
  
              from .utils.alg import _union_workflow, _convert_bfs
              bfs = _union_workflow(o)  # bfg edges.
  
              # Set minimum initial distances.
              if inputs_dist:
                  inputs_dist = combine_dicts(o.dist, inputs_dist)
              else:
                  inputs_dist = o.dist
  
              # Set data nodes to wait inputs.
              wait_in = self._get_wait_in(flag=True)
  
              while True:  # Start shrinking loop.
                  # Evaluate the workflow graph without invoking functions.
                  o = self.dispatch(
                      inputs, outputs, cutoff, inputs_dist, wildcard, True, False,
                      False, _wait_in=wait_in
                  )
  
                  _union_workflow(o, bfs=bfs)  # Update bfs.
  
                  n_d, status = o._remove_wait_in()  # Remove wait input flags.
  
                  if not status:
                      break  # Stop iteration.
  
                  # Update inputs.
                  inputs = n_d.intersection(data_nodes).union(inputs)
  
              # Update outputs and convert bfs in DiGraphs.
              outputs, bfs = outputs or o, _convert_bfs(bfs)
  
          elif not outputs:
              return self.copy_structure()  # Empty Dispatcher.
  
          # Get sub dispatcher breadth-first-search graph.
          dsp = self._get_dsp_from_bfs(outputs, bfs_graphs=bfs)
  
          return dsp