docs: def reduce(self, values, inplace=True):
          """
          Reduces the factor to the context of given variable values.
  
          Parameters
          ----------
          values: list, array-like
              A list of tuples of the form (variable_name, variable_state).
  
          inplace: boolean
              If inplace=True it will modify the factor itself, else would return
              a new factor.
  
          Returns
          -------
          DiscreteFactor or None: if inplace=True (default) returns None
                          if inplace=False returns a new `DiscreteFactor` instance.
  
          Examples
          --------
          >>> from pgmpy.factors.discrete import DiscreteFactor
          >>> phi = DiscreteFactor(['x1', 'x2', 'x3'], [2, 3, 2], range(12))
          >>> phi.reduce([('x1', 0), ('x2', 0)])
          >>> phi.variables
          ['x3']
          >>> phi.cardinality
          array([2])
          >>> phi.values
          array([0., 1.])
          """
          if isinstance(values, six.string_types):
              raise TypeError("values: Expected type list or array-like, got type str")
  
          if (any(isinstance(value, six.string_types) for value in values) or
                  not all(isinstance(state, (int, np.integer)) for var, state in values)):
              raise TypeError("values: must contain tuples or array-like elements of the form "
                              "(hashable object, type int)")
  
          phi = self if inplace else self.copy()
  
          var_index_to_del = []
          slice_ = [slice(None)] * len(self.variables)
          for var, state in values:
              var_index = phi.variables.index(var)
              slice_[var_index] = state
              var_index_to_del.append(var_index)
  
          var_index_to_keep = sorted(set(range(len(phi.variables))) - set(var_index_to_del))
          # set difference is not gaurenteed to maintain ordering
          phi.variables = [phi.variables[index] for index in var_index_to_keep]
          phi.cardinality = phi.cardinality[var_index_to_keep]
          phi.values = phi.values[tuple(slice_)]
  
          if not inplace:
              return phi