code: def factor_product(*args):
      """
      Returns factor product over `args`.
  
      Parameters
      ----------
      args: `BaseFactor` instances.
          factors to be multiplied
  
      Returns
      -------
      BaseFactor: `BaseFactor` representing factor product over all the `BaseFactor` instances in args.
  
      Examples
      --------
      >>> from pgmpy.factors.discrete import DiscreteFactor
      >>> from pgmpy.factors import factor_product
      >>> phi1 = DiscreteFactor(['x1', 'x2', 'x3'], [2, 3, 2], range(12))
      >>> phi2 = DiscreteFactor(['x3', 'x4', 'x1'], [2, 2, 2], range(8))
      >>> phi = factor_product(phi1, phi2)
      >>> phi.variables
      ['x1', 'x2', 'x3', 'x4']
      >>> phi.cardinality
      array([2, 3, 2, 2])
      >>> phi.values
      array([[[[ 0,  0],
               [ 4,  6]],
  
              [[ 0,  4],
               [12, 18]],
  
              [[ 0,  8],
               [20, 30]]],
  
  
             [[[ 6, 18],
               [35, 49]],
  
              [[ 8, 24],
               [45, 63]],
  
              [[10, 30],
               [55, 77]]]])
      """
      if not all(isinstance(phi, BaseFactor) for phi in args):
          raise TypeError("Arguments must be factors")
      # Check if all of the arguments are of the same type
      elif len(set(map(type, args))) != 1:
          raise NotImplementedError(
              "All the args are expected to be instances of the same factor class."
          )
  
      if len(args) == 1:
          return args[0].copy()
      else:
          return reduce(lambda phi1, phi2: phi1 * phi2, args)
  
file_path: pgmpy/pgmpy/factors/base.py
imports: from abc import abstractmethod
  from functools import reduce
  from itertools import chain
  from opt_einsum import contract
label_desc: Use image node_id 1 for calling a global function with example usage: factor_product() and returns: args, reduce